Merge pull request #5314 from MrPetovan/task/4889-fix-tests

Fix tests after enabling PHP Notices
This commit is contained in:
Michael Vogel 2018-07-06 22:14:01 +02:00 committed by GitHub
commit 3eec97aa6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 348 additions and 268 deletions

View File

@ -10,11 +10,10 @@ php:
services: services:
- mysql - mysql
env: env:
- USER=travis DB=test - MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_USERNAME=travis MYSQL_PASSWORD= MYSQL_DATABASE=test
install: install:
- composer install - composer install
before_script: before_script:
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;' - mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
# In order to avoid bin/worker.php warnings - mysql -utravis test < database.sql
- touch .htconfig.php

View File

@ -499,36 +499,6 @@ if (!defined("SIGTERM")) {
if (!defined('CURLE_OPERATION_TIMEDOUT')) { if (!defined('CURLE_OPERATION_TIMEDOUT')) {
define('CURLE_OPERATION_TIMEDOUT', CURLE_OPERATION_TIMEOUTED); define('CURLE_OPERATION_TIMEDOUT', CURLE_OPERATION_TIMEOUTED);
} }
/**
* Reverse the effect of magic_quotes_gpc if it is enabled.
* Please disable magic_quotes_gpc so we don't have to do this.
* See http://php.net/manual/en/security.magicquotes.disabling.php
*/
function startup()
{
error_reporting(E_ERROR | E_WARNING | E_PARSE);
set_time_limit(0);
// This has to be quite large to deal with embedded private photos
ini_set('pcre.backtrack_limit', 500000);
if (get_magic_quotes_gpc()) {
$process = [&$_GET, &$_POST, &$_COOKIE, &$_REQUEST];
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
}
/** /**
* @brief Retrieve the App structure * @brief Retrieve the App structure

View File

@ -23,17 +23,19 @@ $db_data = 'mysqldatabasename';
// Use environment variables for mysql if they are set beforehand // Use environment variables for mysql if they are set beforehand
if (!empty(getenv('MYSQL_HOST')) if (!empty(getenv('MYSQL_HOST'))
&& !empty(getenv('MYSQL_PORT'))
&& (!empty(getenv('MYSQL_USERNAME')) || !empty(getenv('MYSQL_USER'))) && (!empty(getenv('MYSQL_USERNAME')) || !empty(getenv('MYSQL_USER')))
&& !empty(getenv('MYSQL_PASSWORD')) && !getenv('MYSQL_PASSWORD') === false
&& !empty(getenv('MYSQL_DATABASE'))) { && !empty(getenv('MYSQL_DATABASE'))) {
$db_host = getenv('MYSQL_HOST') . ':' . getenv('MYSQL_PORT'); $db_host = getenv('MYSQL_HOST');
if (!empty(getenv('MYSQL_PORT'))) {
$db_host .= ':' . getenv('MYSQL_PORT');
}
if (!empty(getenv('MYSQL_USERNAME'))) { if (!empty(getenv('MYSQL_USERNAME'))) {
$db_user = getenv('MYSQL_USERNAME'); $db_user = getenv('MYSQL_USERNAME');
} elseif (!empty(getenv('MYSQL_USER'))) { } else {
$db_user = getenv('MYSQL_USER'); $db_user = getenv('MYSQL_USER');
} }
$db_pass = getenv('MYSQL_PASSWORD'); $db_pass = (string) getenv('MYSQL_PASSWORD');
$db_data = getenv('MYSQL_DATABASE'); $db_data = getenv('MYSQL_DATABASE');
} }

View File

@ -16,6 +16,7 @@ use Friendica\Core\Config;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\NotificationsManager; use Friendica\Core\NotificationsManager;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Core\Protocol;
use Friendica\Core\System; use Friendica\Core\System;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Friendica\Database\DBM; use Friendica\Database\DBM;
@ -90,11 +91,15 @@ function api_source()
} }
// Support for known clients that doesn't send a source name // Support for known clients that doesn't send a source name
if (strpos($_SERVER['HTTP_USER_AGENT'], "Twidere") !== false) { if (!empty($_SERVER['HTTP_USER_AGENT'])) {
return "Twidere"; if(strpos($_SERVER['HTTP_USER_AGENT'], "Twidere") !== false) {
} return "Twidere";
}
logger("Unrecognized user-agent ".$_SERVER['HTTP_USER_AGENT'], LOGGER_DEBUG); logger("Unrecognized user-agent ".$_SERVER['HTTP_USER_AGENT'], LOGGER_DEBUG);
} else {
logger("Empty user-agent", LOGGER_DEBUG);
}
return "api"; return "api";
} }
@ -193,8 +198,8 @@ function api_login(App $a)
throw new UnauthorizedException("This API requires login"); throw new UnauthorizedException("This API requires login");
} }
$user = $_SERVER['PHP_AUTH_USER']; $user = defaults($_SERVER, 'PHP_AUTH_USER', '');
$password = $_SERVER['PHP_AUTH_PW']; $password = defaults($_SERVER, 'PHP_AUTH_PW', '');
// allow "user@server" login (but ignore 'server' part) // allow "user@server" login (but ignore 'server' part)
$at = strstr($user, "@", true); $at = strstr($user, "@", true);
@ -258,7 +263,7 @@ function api_check_method($method)
if ($method == "*") { if ($method == "*") {
return true; return true;
} }
return (strpos($method, $_SERVER['REQUEST_METHOD']) !== false); return (stripos($method, defaults($_SERVER, 'REQUEST_METHOD', 'GET')) !== false);
} }
/** /**
@ -298,7 +303,7 @@ function api_call(App $a)
//unset($_SERVER['PHP_AUTH_USER']); //unset($_SERVER['PHP_AUTH_USER']);
/// @TODO should be "true ==[=] $info['auth']", if you miss only one = character, you assign a variable (only with ==). Let's make all this even. /// @TODO should be "true ==[=] $info['auth']", if you miss only one = character, you assign a variable (only with ==). Let's make all this even.
if ($info['auth'] === true && api_user() === false) { if (!empty($info['auth']) && api_user() === false) {
api_login($a); api_login($a);
} }
@ -475,7 +480,7 @@ function api_rss_extra(App $a, $arr, $user_info)
'base' => System::baseUrl(), 'base' => System::baseUrl(),
'updated' => api_date(null), 'updated' => api_date(null),
'atom_updated' => DateTimeFormat::utcNow(DateTimeFormat::ATOM), 'atom_updated' => DateTimeFormat::utcNow(DateTimeFormat::ATOM),
'language' => $user_info['language'], 'language' => $user_info['lang'],
'logo' => System::baseUrl() . "/images/friendica-32.png", 'logo' => System::baseUrl() . "/images/friendica-32.png",
]; ];
@ -571,6 +576,7 @@ function api_get_user(App $a, $contact_id = null)
} }
} }
// $called_api is the API path exploded on / and is expected to have at least 2 elements
if (is_null($user) && ($a->argc > (count($called_api) - 1)) && (count($called_api) > 0)) { if (is_null($user) && ($a->argc > (count($called_api) - 1)) && (count($called_api) > 0)) {
$argid = count($called_api); $argid = count($called_api);
list($user, $null) = explode(".", $a->argv[$argid]); list($user, $null) = explode(".", $a->argv[$argid]);
@ -773,13 +779,13 @@ function api_get_user(App $a, $contact_id = null)
$link_color = PConfig::get($ret['uid'], 'frio', 'link_color'); $link_color = PConfig::get($ret['uid'], 'frio', 'link_color');
$bgcolor = PConfig::get($ret['uid'], 'frio', 'background_color'); $bgcolor = PConfig::get($ret['uid'], 'frio', 'background_color');
} }
if (!$nav_bg) { if (empty($nav_bg)) {
$nav_bg = "#708fa0"; $nav_bg = "#708fa0";
} }
if (!$link_color) { if (empty($link_color)) {
$link_color = "#6fdbe8"; $link_color = "#6fdbe8";
} }
if (!$bgcolor) { if (empty($bgcolor)) {
$bgcolor = "#ededed"; $bgcolor = "#ededed";
} }
@ -801,12 +807,12 @@ function api_get_user(App $a, $contact_id = null)
*/ */
function api_item_get_user(App $a, $item) function api_item_get_user(App $a, $item)
{ {
$status_user = api_get_user($a, $item["author-id"]); $status_user = api_get_user($a, defaults($item, 'author-id', null));
$status_user["protected"] = $item["private"]; $status_user["protected"] = defaults($item, 'private', 0);
if ($item['thr-parent'] == $item['uri']) { if (defaults($item, 'thr-parent', '') == defaults($item, 'uri', '')) {
$owner_user = api_get_user($a, $item["owner-id"]); $owner_user = api_get_user($a, defaults($item, 'author-id', null));
} else { } else {
$owner_user = $status_user; $owner_user = $status_user;
} }
@ -880,7 +886,6 @@ function api_create_xml(array $data, $root_element)
{ {
$childname = key($data); $childname = key($data);
$data2 = array_pop($data); $data2 = array_pop($data);
$key = key($data2);
$namespaces = ["" => "http://api.twitter.com", $namespaces = ["" => "http://api.twitter.com",
"statusnet" => "http://status.net/schema/api/1/", "statusnet" => "http://status.net/schema/api/1/",
@ -893,18 +898,19 @@ function api_create_xml(array $data, $root_element)
} }
if (is_array($data2)) { if (is_array($data2)) {
$key = key($data2);
api_walk_recursive($data2, "api_reformat_xml"); api_walk_recursive($data2, "api_reformat_xml");
}
if ($key == "0") { if ($key == "0") {
$data4 = []; $data4 = [];
$i = 1; $i = 1;
foreach ($data2 as $item) { foreach ($data2 as $item) {
$data4[$i++ . ":" . $childname] = $item; $data4[$i++ . ":" . $childname] = $item;
}
$data2 = $data4;
} }
$data2 = $data4;
} }
$data3 = [$root_element => $data2]; $data3 = [$root_element => $data2];
@ -1299,19 +1305,19 @@ function api_status_show($type)
'in_reply_to_screen_name' => $in_reply_to['screen_name'], 'in_reply_to_screen_name' => $in_reply_to['screen_name'],
'user' => $user_info, 'user' => $user_info,
$geo => null, $geo => null,
'coordinates' => "", 'coordinates' => '',
'place' => "", 'place' => '',
'contributors' => "", 'contributors' => '',
'is_quote_status' => false, 'is_quote_status' => false,
'retweet_count' => 0, 'retweet_count' => 0,
'favorite_count' => 0, 'favorite_count' => 0,
'favorited' => $lastwall['starred'] ? true : false, 'favorited' => $lastwall['starred'] ? true : false,
'retweeted' => false, 'retweeted' => false,
'possibly_sensitive' => false, 'possibly_sensitive' => false,
'lang' => "", 'lang' => '',
'statusnet_html' => $converted["html"], 'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $lastwall['parent'], 'statusnet_conversation_id' => $lastwall['parent'],
'external_url' => System::baseUrl() . "/display/" . $lastwall['guid'], 'external_url' => System::baseUrl() . '/display/' . $lastwall['guid'],
]; ];
if (count($converted["attachments"]) > 0) { if (count($converted["attachments"]) > 0) {
@ -1477,7 +1483,7 @@ function api_users_lookup($type)
{ {
$users = []; $users = [];
if (x($_REQUEST['user_id'])) { if (!empty($_REQUEST['user_id'])) {
foreach (explode(',', $_REQUEST['user_id']) as $id) { foreach (explode(',', $_REQUEST['user_id']) as $id) {
if (!empty($id)) { if (!empty($id)) {
$users[] = api_get_user(get_app(), $id); $users[] = api_get_user(get_app(), $id);
@ -1801,20 +1807,20 @@ function api_statuses_show($type)
} }
// params // params
$id = intval($a->argv[3]); $id = intval(defaults($a->argv, 3, 0));
if ($id == 0) { if ($id == 0) {
$id = intval($_REQUEST["id"]); $id = intval(defaults($_REQUEST, 'id', 0));
} }
// Hotot workaround // Hotot workaround
if ($id == 0) { if ($id == 0) {
$id = intval($a->argv[4]); $id = intval(defaults($a->argv, 4, 0));
} }
logger('API: api_statuses_show: ' . $id); logger('API: api_statuses_show: ' . $id);
$conversation = (x($_REQUEST, 'conversation') ? 1 : 0); $conversation = !empty($_REQUEST['conversation']);
// try to fetch the item for the local user - or the public item, if there is no local one // try to fetch the item for the local user - or the public item, if there is no local one
$uri_item = dba::selectFirst('item', ['uri'], ['id' => $id]); $uri_item = dba::selectFirst('item', ['uri'], ['id' => $id]);
@ -1874,24 +1880,24 @@ function api_conversation_show($type)
} }
// params // params
$id = intval($a->argv[3]); $id = intval(defaults($a->argv , 3 , 0));
$count = (x($_REQUEST, 'count') ? $_REQUEST['count'] : 20); $since_id = intval(defaults($_REQUEST, 'since_id', 0));
$page = (x($_REQUEST, 'page') ? $_REQUEST['page'] - 1 : 0); $max_id = intval(defaults($_REQUEST, 'max_id' , 0));
$count = intval(defaults($_REQUEST, 'count' , 20));
$page = intval(defaults($_REQUEST, 'page' , 1)) - 1;
if ($page < 0) { if ($page < 0) {
$page = 0; $page = 0;
} }
$since_id = (x($_REQUEST, 'since_id') ? $_REQUEST['since_id'] : 0);
$max_id = (x($_REQUEST, 'max_id') ? $_REQUEST['max_id'] : 0);
$start = $page*$count; $start = $page * $count;
if ($id == 0) { if ($id == 0) {
$id = intval($_REQUEST["id"]); $id = intval(defaults($_REQUEST, 'id', 0));
} }
// Hotot workaround // Hotot workaround
if ($id == 0) { if ($id == 0) {
$id = intval($a->argv[4]); $id = intval(defaults($a->argv, 4, 0));
} }
logger('API: api_conversation_show: '.$id); logger('API: api_conversation_show: '.$id);
@ -1954,15 +1960,15 @@ function api_statuses_repeat($type)
api_get_user($a); api_get_user($a);
// params // params
$id = intval($a->argv[3]); $id = intval(defaults($a->argv, 3, 0));
if ($id == 0) { if ($id == 0) {
$id = intval($_REQUEST["id"]); $id = intval(defaults($_REQUEST, 'id', 0));
} }
// Hotot workaround // Hotot workaround
if ($id == 0) { if ($id == 0) {
$id = intval($a->argv[4]); $id = intval(defaults($a->argv, 4, 0));
} }
logger('API: api_statuses_repeat: '.$id); logger('API: api_statuses_repeat: '.$id);
@ -2020,15 +2026,15 @@ function api_statuses_destroy($type)
api_get_user($a); api_get_user($a);
// params // params
$id = intval($a->argv[3]); $id = intval(defaults($a->argv, 3, 0));
if ($id == 0) { if ($id == 0) {
$id = intval($_REQUEST["id"]); $id = intval(defaults($_REQUEST, 'id', 0));
} }
// Hotot workaround // Hotot workaround
if ($id == 0) { if ($id == 0) {
$id = intval($a->argv[4]); $id = intval(defaults($a->argv, 4, 0));
} }
logger('API: api_statuses_destroy: '.$id); logger('API: api_statuses_destroy: '.$id);
@ -2205,7 +2211,7 @@ function api_favorites_create_destroy($type)
// for versioned api. // for versioned api.
/// @TODO We need a better global soluton /// @TODO We need a better global soluton
$action_argv_id = 2; $action_argv_id = 2;
if ($a->argv[1] == "1.1") { if (count($a->argv) > 1 && $a->argv[1] == "1.1") {
$action_argv_id = 3; $action_argv_id = 3;
} }
@ -2214,10 +2220,9 @@ function api_favorites_create_destroy($type)
} }
$action = str_replace("." . $type, "", $a->argv[$action_argv_id]); $action = str_replace("." . $type, "", $a->argv[$action_argv_id]);
if ($a->argc == $action_argv_id + 2) { if ($a->argc == $action_argv_id + 2) {
$itemid = intval($a->argv[$action_argv_id + 1]); $itemid = intval(defaults($a->argv, $action_argv_id + 1, 0));
} else { } else {
/// @TODO use x() to check if _REQUEST contains 'id' $itemid = intval(defaults($_REQUEST, 'id', 0));
$itemid = intval($_REQUEST['id']);
} }
$item = Item::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]); $item = Item::selectFirstForUser(api_user(), [], ['id' => $itemid, 'uid' => api_user()]);
@ -2340,25 +2345,33 @@ function api_format_messages($item, $recipient, $sender)
{ {
// standard meta information // standard meta information
$ret = [ $ret = [
'id' => $item['id'], 'id' => $item['id'],
'sender_id' => $sender['id'] , 'sender_id' => $sender['id'] ,
'text' => "", 'text' => "",
'recipient_id' => $recipient['id'], 'recipient_id' => $recipient['id'],
'created_at' => api_date($item['created']), 'created_at' => api_date(defaults($item, 'created', DateTimeFormat::utcNow())),
'sender_screen_name' => $sender['screen_name'], 'sender_screen_name' => $sender['screen_name'],
'recipient_screen_name' => $recipient['screen_name'], 'recipient_screen_name' => $recipient['screen_name'],
'sender' => $sender, 'sender' => $sender,
'recipient' => $recipient, 'recipient' => $recipient,
'title' => "", 'title' => "",
'friendica_seen' => $item['seen'], 'friendica_seen' => defaults($item, 'seen', 0),
'friendica_parent_uri' => $item['parent-uri'], 'friendica_parent_uri' => defaults($item, 'parent-uri', ''),
]; ];
// "uid" and "self" are only needed for some internal stuff, so remove it from here // "uid" and "self" are only needed for some internal stuff, so remove it from here
unset($ret["sender"]["uid"]); if (isset($ret['sender']['uid'])) {
unset($ret["sender"]["self"]); unset($ret['sender']['uid']);
unset($ret["recipient"]["uid"]); }
unset($ret["recipient"]["self"]); if (isset($ret['sender']['self'])) {
unset($ret['sender']['self']);
}
if (isset($ret['recipient']['uid'])) {
unset($ret['recipient']['uid']);
}
if (isset($ret['recipient']['self'])) {
unset($ret['recipient']['self']);
}
//don't send title to regular StatusNET requests to avoid confusing these apps //don't send title to regular StatusNET requests to avoid confusing these apps
if (x($_GET, 'getText')) { if (x($_GET, 'getText')) {
@ -2405,8 +2418,8 @@ function api_convert_item($item)
$statustext = trim($statustitle."\n\n".$statusbody); $statustext = trim($statustitle."\n\n".$statusbody);
} }
if (($item["network"] == NETWORK_FEED) && (strlen($statustext)> 1000)) { if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (strlen($statustext)> 1000)) {
$statustext = substr($statustext, 0, 1000)."... \n".$item["plink"]; $statustext = substr($statustext, 0, 1000) . "... \n" . defaults($item, 'plink', '');
} }
$statushtml = BBCode::convert(api_clean_attachments($body), false); $statushtml = BBCode::convert(api_clean_attachments($body), false);
@ -2440,7 +2453,7 @@ function api_convert_item($item)
} }
// feeds without body should contain the link // feeds without body should contain the link
if (($item['network'] == NETWORK_FEED) && (strlen($item['body']) == 0)) { if ((defaults($item, 'network', Protocol::PHANTOM) == Protocol::FEED) && (strlen($item['body']) == 0)) {
$statushtml .= BBCode::convert($item['plink']); $statushtml .= BBCode::convert($item['plink']);
} }
@ -2482,7 +2495,7 @@ function api_get_attachments(&$body)
} }
} }
if (strstr($_SERVER['HTTP_USER_AGENT'], "AndStatus")) { if (strstr(defaults($_SERVER, 'HTTP_USER_AGENT', ''), "AndStatus")) {
foreach ($images[0] as $orig) { foreach ($images[0] as $orig) {
$body = str_replace($orig, "", $body); $body = str_replace($orig, "", $body);
} }
@ -3324,18 +3337,15 @@ function api_statusnet_config($type)
{ {
$a = get_app(); $a = get_app();
$name = $a->config['sitename']; $name = Config::get('config', 'sitename');
$server = $a->get_hostname(); $server = $a->get_hostname();
$logo = System::baseUrl() . '/images/friendica-64.png'; $logo = System::baseUrl() . '/images/friendica-64.png';
$email = $a->config['admin_email']; $email = Config::get('config', 'admin_email');
$closed = (($a->config['register_policy'] == REGISTER_CLOSED) ? 'true' : 'false'); $closed = Config::get('config', 'register_policy') == REGISTER_CLOSED ? 'true' : 'false';
$private = ((Config::get('system', 'block_public')) ? 'true' : 'false'); $private = Config::get('system', 'block_public') ? 'true' : 'false';
$textlimit = (string) (($a->config['max_import_size']) ? $a->config['max_import_size'] : 200000); $textlimit = (string) Config::get('config', 'api_import_size', Config::get('config', 'max_import_size', 200000));
if ($a->config['api_import_size']) { $ssl = Config::get('system', 'have_ssl') ? 'true' : 'false';
$textlimit = (string) $a->config['api_import_size']; $sslserver = Config::get('system', 'have_ssl') ? str_replace('http:', 'https:', System::baseUrl()) : '';
}
$ssl = ((Config::get('system', 'have_ssl')) ? 'true' : 'false');
$sslserver = (($ssl === 'true') ? str_replace('http:', 'https:', System::baseUrl()) : '');
$config = [ $config = [
'site' => ['name' => $name,'server' => $server, 'theme' => 'default', 'path' => '', 'site' => ['name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
@ -3457,34 +3467,40 @@ api_register_func('api/followers/ids', 'api_followers_ids', true);
*/ */
function api_direct_messages_new($type) function api_direct_messages_new($type)
{ {
$a = get_app(); $a = get_app();
if (api_user() === false) { if (api_user() === false) {
throw new ForbiddenException(); throw new ForbiddenException();
} }
if (!x($_POST, "text") || (!x($_POST, "screen_name") && !x($_POST, "user_id"))) { if (empty($_POST["text"]) || empty($_POST["screen_name"]) && empty($_POST["user_id"])) {
return; return;
} }
$sender = api_get_user($a); $sender = api_get_user($a);
if ($_POST['screen_name']) { $recipient = null;
if (!empty($_POST['screen_name'])) {
$r = q( $r = q(
"SELECT `id`, `nurl`, `network` FROM `contact` WHERE `uid`=%d AND `nick`='%s'", "SELECT `id`, `nurl`, `network` FROM `contact` WHERE `uid`=%d AND `nick`='%s'",
intval(api_user()), intval(api_user()),
dbesc($_POST['screen_name']) dbesc($_POST['screen_name'])
); );
// Selecting the id by priority, friendica first if (DBM::is_result($r)) {
api_best_nickname($r); // Selecting the id by priority, friendica first
api_best_nickname($r);
$recipient = api_get_user($a, $r[0]['nurl']); $recipient = api_get_user($a, $r[0]['nurl']);
}
} else { } else {
$recipient = api_get_user($a, $_POST['user_id']); $recipient = api_get_user($a, $_POST['user_id']);
} }
if (empty($recipient)) {
throw new NotFoundException('Recipient not found');
}
$replyto = ''; $replyto = '';
$sub = ''; $sub = '';
if (x($_REQUEST, 'replyto')) { if (x($_REQUEST, 'replyto')) {
@ -3622,17 +3638,17 @@ function api_direct_messages_box($type, $box, $verbose)
throw new ForbiddenException(); throw new ForbiddenException();
} }
// params // params
$count = (x($_GET, 'count') ? $_GET['count'] : 20); $count = defaults($_GET, 'count', 20);
$page = (x($_REQUEST, 'page') ? $_REQUEST['page'] -1 : 0); $page = defaults($_REQUEST, 'page', 1) - 1;
if ($page < 0) { if ($page < 0) {
$page = 0; $page = 0;
} }
$since_id = (x($_REQUEST, 'since_id') ? $_REQUEST['since_id'] : 0); $since_id = defaults($_REQUEST, 'since_id', 0);
$max_id = (x($_REQUEST, 'max_id') ? $_REQUEST['max_id'] : 0); $max_id = defaults($_REQUEST, 'max_id', 0);
$user_id = (x($_REQUEST, 'user_id') ? $_REQUEST['user_id'] : ""); $user_id = defaults($_REQUEST, 'user_id', '');
$screen_name = (x($_REQUEST, 'screen_name') ? $_REQUEST['screen_name'] : ""); $screen_name = defaults($_REQUEST, 'screen_name', '');
// caller user info // caller user info
unset($_REQUEST["user_id"]); unset($_REQUEST["user_id"]);
@ -3656,7 +3672,7 @@ function api_direct_messages_box($type, $box, $verbose)
if ($box=="sentbox") { if ($box=="sentbox") {
$sql_extra = "`mail`.`from-url`='" . dbesc($profile_url) . "'"; $sql_extra = "`mail`.`from-url`='" . dbesc($profile_url) . "'";
} elseif ($box == "conversation") { } elseif ($box == "conversation") {
$sql_extra = "`mail`.`parent-uri`='" . dbesc($_GET["uri"]) . "'"; $sql_extra = "`mail`.`parent-uri`='" . dbesc(defaults($_GET, 'uri', '')) . "'";
} elseif ($box == "all") { } elseif ($box == "all") {
$sql_extra = "true"; $sql_extra = "true";
} elseif ($box == "inbox") { } elseif ($box == "inbox") {
@ -5577,8 +5593,10 @@ function api_friendica_notification($type)
if ($type == "xml") { if ($type == "xml") {
$xmlnotes = []; $xmlnotes = [];
foreach ($notes as $note) { if (!empty($notes)) {
$xmlnotes[] = ["@attributes" => $note]; foreach ($notes as $note) {
$xmlnotes[] = ["@attributes" => $note];
}
} }
$notes = $xmlnotes; $notes = $xmlnotes;

View File

@ -1015,7 +1015,7 @@ class dba {
$commands = []; $commands = [];
// Create a key for the loop prevention // Create a key for the loop prevention
$key = $table . ':' . implode(':', array_keys($conditions)) . ':' . implode(':', $conditions); $key = $table . ':' . json_encode($conditions);
// We quit when this key already exists in the callstack. // We quit when this key already exists in the callstack.
if (isset($callstack[$key])) { if (isset($callstack[$key])) {
@ -1042,7 +1042,7 @@ class dba {
$rel_def = array_values(self::$relation[$table])[0]; $rel_def = array_values(self::$relation[$table])[0];
// Create a key for preventing double queries // Create a key for preventing double queries
$qkey = $field . '-' . $table . ':' . implode(':', array_keys($conditions)) . ':' . implode(':', $conditions); $qkey = $field . '-' . $table . ':' . json_encode($conditions);
// When the search field is the relation field, we don't need to fetch the rows // When the search field is the relation field, we don't need to fetch the rows
// This is useful when the leading record is already deleted in the frontend but the rest is done in the backend // This is useful when the leading record is already deleted in the frontend but the rest is done in the backend

View File

@ -41,7 +41,7 @@ function new_cookie($time, $user = [])
if ($user) { if ($user) {
$value = json_encode(["uid" => $user["uid"], $value = json_encode(["uid" => $user["uid"],
"hash" => cookie_hash($user), "hash" => cookie_hash($user),
"ip" => $_SERVER['REMOTE_ADDR']]); "ip" => defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0')]);
} else { } else {
$value = ""; $value = "";
} }
@ -70,7 +70,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive
$_SESSION['page_flags'] = $user_record['page-flags']; $_SESSION['page_flags'] = $user_record['page-flags'];
$_SESSION['my_url'] = System::baseUrl() . '/profile/' . $user_record['nickname']; $_SESSION['my_url'] = System::baseUrl() . '/profile/' . $user_record['nickname'];
$_SESSION['my_address'] = $user_record['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3); $_SESSION['my_address'] = $user_record['nickname'] . '@' . substr(System::baseUrl(), strpos(System::baseUrl(), '://') + 3);
$_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; $_SESSION['addr'] = defaults($_SERVER, 'REMOTE_ADDR', '0.0.0.0');
$a->user = $user_record; $a->user = $user_record;

View File

@ -1156,7 +1156,7 @@ function put_item_in_cache(&$item, $update = false)
$rendered_html = defaults($item, 'rendered-html', ''); $rendered_html = defaults($item, 'rendered-html', '');
if ($rendered_hash == '' if ($rendered_hash == ''
|| $item["rendered-html"] == "" || $rendered_html == ""
|| $rendered_hash != hash("md5", $item["body"]) || $rendered_hash != hash("md5", $item["body"])
|| Config::get("system", "ignore_cache") || Config::get("system", "ignore_cache")
) { ) {
@ -1176,7 +1176,7 @@ function put_item_in_cache(&$item, $update = false)
$update = true; $update = true;
} }
if ($update && ($item["id"] > 0)) { if ($update && !empty($item["id"])) {
Item::update(['rendered-html' => $item["rendered-html"], 'rendered-hash' => $item["rendered-hash"]], Item::update(['rendered-html' => $item["rendered-html"], 'rendered-hash' => $item["rendered-hash"]],
['id' => $item["id"]]); ['id' => $item["id"]]);
} }

View File

@ -178,6 +178,8 @@ function item_post(App $a) {
return; return;
} }
$categories = '';
if ($orig_post) { if ($orig_post) {
$str_group_allow = $orig_post['allow_gid']; $str_group_allow = $orig_post['allow_gid'];
$str_contact_allow = $orig_post['allow_cid']; $str_contact_allow = $orig_post['allow_cid'];
@ -223,13 +225,13 @@ function item_post(App $a) {
$str_contact_deny = perms2str($_REQUEST['contact_deny']); $str_contact_deny = perms2str($_REQUEST['contact_deny']);
} }
$title = notags(trim($_REQUEST['title'])); $title = notags(trim(defaults($_REQUEST, 'title' , '')));
$location = notags(trim($_REQUEST['location'])); $location = notags(trim(defaults($_REQUEST, 'location', '')));
$coord = notags(trim($_REQUEST['coord'])); $coord = notags(trim(defaults($_REQUEST, 'coord' , '')));
$verb = notags(trim($_REQUEST['verb'])); $verb = notags(trim(defaults($_REQUEST, 'verb' , '')));
$emailcc = notags(trim($_REQUEST['emailcc'])); $emailcc = notags(trim(defaults($_REQUEST, 'emailcc' , '')));
$body = escape_tags(trim($_REQUEST['body'])); $body = escape_tags(trim(defaults($_REQUEST, 'body' , '')));
$network = notags(trim(defaults($_REQUEST, 'network', NETWORK_DFRN))); $network = notags(trim(defaults($_REQUEST, 'network' , NETWORK_DFRN)));
$guid = get_guid(32); $guid = get_guid(32);
$postopts = defaults($_REQUEST, 'postopts', ''); $postopts = defaults($_REQUEST, 'postopts', '');
@ -279,15 +281,15 @@ function item_post(App $a) {
} }
} }
if (strlen($categories)) { if (!empty($categories)) {
// get the "fileas" tags for this post // get the "fileas" tags for this post
$filedas = file_tag_file_to_list($categories, 'file'); $filedas = file_tag_file_to_list($categories, 'file');
} }
// save old and new categories, so we can determine what needs to be deleted from pconfig // save old and new categories, so we can determine what needs to be deleted from pconfig
$categories_old = $categories; $categories_old = $categories;
$categories = file_tag_list_to_file(trim($_REQUEST['category']), 'category'); $categories = file_tag_list_to_file(trim(defaults($_REQUEST, 'category', '')), 'category');
$categories_new = $categories; $categories_new = $categories;
if (strlen($filedas)) { if (!empty($filedas)) {
// append the fileas stuff to the new categories list // append the fileas stuff to the new categories list
$categories .= file_tag_list_to_file($filedas, 'file'); $categories .= file_tag_list_to_file($filedas, 'file');
} }

View File

@ -125,28 +125,36 @@ function wall_upload_post(App $a, $desktopmode = true)
$filetype = $_FILES['userfile']['type']; $filetype = $_FILES['userfile']['type'];
} elseif (x($_FILES, 'media')) { } elseif (x($_FILES, 'media')) {
if (is_array($_FILES['media']['tmp_name'])) { if (!empty($_FILES['media']['tmp_name'])) {
$src = $_FILES['media']['tmp_name'][0]; if (is_array($_FILES['media']['tmp_name'])) {
} else { $src = $_FILES['media']['tmp_name'][0];
$src = $_FILES['media']['tmp_name']; } else {
$src = $_FILES['media']['tmp_name'];
}
} }
if (is_array($_FILES['media']['name'])) { if (!empty($_FILES['media']['name'])) {
$filename = basename($_FILES['media']['name'][0]); if (is_array($_FILES['media']['name'])) {
} else { $filename = basename($_FILES['media']['name'][0]);
$filename = basename($_FILES['media']['name']); } else {
$filename = basename($_FILES['media']['name']);
}
} }
if (is_array($_FILES['media']['size'])) { if (!empty($_FILES['media']['size'])) {
$filesize = intval($_FILES['media']['size'][0]); if (is_array($_FILES['media']['size'])) {
} else { $filesize = intval($_FILES['media']['size'][0]);
$filesize = intval($_FILES['media']['size']); } else {
$filesize = intval($_FILES['media']['size']);
}
} }
if (is_array($_FILES['media']['type'])) { if (!empty($_FILES['media']['type'])) {
$filetype = $_FILES['media']['type'][0]; if (is_array($_FILES['media']['type'])) {
} else { $filetype = $_FILES['media']['type'][0];
$filetype = $_FILES['media']['type']; } else {
$filetype = $_FILES['media']['type'];
}
} }
} }

View File

@ -1,5 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<phpunit bootstrap="tests/bootstrap.php"> <phpunit
bootstrap="tests/bootstrap.php"
verbose="true">
<testsuites> <testsuites>
<testsuite> <testsuite>
<directory>tests/</directory> <directory>tests/</directory>

View File

@ -181,7 +181,10 @@ class App
$this->process_id = uniqid('log', true); $this->process_id = uniqid('log', true);
startup(); set_time_limit(0);
// This has to be quite large to deal with embedded private photos
ini_set('pcre.backtrack_limit', 500000);
$this->scheme = 'http'; $this->scheme = 'http';
@ -290,7 +293,7 @@ class App
$this->is_tablet = $mobile_detect->isTablet(); $this->is_tablet = $mobile_detect->isTablet();
// Friendica-Client // Friendica-Client
$this->is_friendica_app = ($_SERVER['HTTP_USER_AGENT'] == 'Apache-HttpClient/UNAVAILABLE (java 1.4)'); $this->is_friendica_app = isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] == 'Apache-HttpClient/UNAVAILABLE (java 1.4)';
// Register template engines // Register template engines
$this->register_template_engine('Friendica\Render\FriendicaSmartyEngine'); $this->register_template_engine('Friendica\Render\FriendicaSmartyEngine');
@ -863,7 +866,7 @@ class App
return; return;
} }
array_unshift($args, ((x($this->config, 'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php')); array_unshift($args, $this->getConfigValue('config', 'php_path', 'php'));
for ($x = 0; $x < count($args); $x ++) { for ($x = 0; $x < count($args); $x ++) {
$args[$x] = escapeshellarg($args[$x]); $args[$x] = escapeshellarg($args[$x]);
@ -875,7 +878,7 @@ class App
return; return;
} }
if (Config::get('system', 'proc_windows')) { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->get_basepath()); $resource = proc_open('cmd /c start /b ' . $cmdline, [], $foo, $this->get_basepath());
} else { } else {
$resource = proc_open($cmdline . ' &', [], $foo, $this->get_basepath()); $resource = proc_open($cmdline . ' &', [], $foo, $this->get_basepath());

View File

@ -72,6 +72,7 @@ class System extends BaseObject
} }
} elseif (!in_array($func['function'], $ignore)) { } elseif (!in_array($func['function'], $ignore)) {
$callstack[] = $func['function']; $callstack[] = $func['function'];
$func['class'] = '';
$previous = $func; $previous = $func;
} }
} }

View File

@ -412,7 +412,7 @@ class DBStructure
$field_definition = $database[$name]["fields"][$fieldname]; $field_definition = $database[$name]["fields"][$fieldname];
// Define the default collation if not given // Define the default collation if not given
if (!isset($parameters['Collation']) && !is_null($field_definition['Collation'])) { if (!isset($parameters['Collation']) && !empty($field_definition['Collation'])) {
$parameters['Collation'] = 'utf8mb4_general_ci'; $parameters['Collation'] = 'utf8mb4_general_ci';
} else { } else {
$parameters['Collation'] = null; $parameters['Collation'] = null;
@ -536,26 +536,26 @@ class DBStructure
private static function FieldCommand($parameters, $create = true) { private static function FieldCommand($parameters, $create = true) {
$fieldstruct = $parameters["type"]; $fieldstruct = $parameters["type"];
if (!is_null($parameters["Collation"])) { if (!empty($parameters["Collation"])) {
$fieldstruct .= " COLLATE ".$parameters["Collation"]; $fieldstruct .= " COLLATE ".$parameters["Collation"];
} }
if ($parameters["not null"]) { if (!empty($parameters["not null"])) {
$fieldstruct .= " NOT NULL"; $fieldstruct .= " NOT NULL";
} }
if (isset($parameters["default"])) { if (!empty($parameters["default"])) {
if (strpos(strtolower($parameters["type"]),"int")!==false) { if (strpos(strtolower($parameters["type"]),"int")!==false) {
$fieldstruct .= " DEFAULT ".$parameters["default"]; $fieldstruct .= " DEFAULT ".$parameters["default"];
} else { } else {
$fieldstruct .= " DEFAULT '".$parameters["default"]."'"; $fieldstruct .= " DEFAULT '".$parameters["default"]."'";
} }
} }
if ($parameters["extra"] != "") { if (!empty($parameters["extra"])) {
$fieldstruct .= " ".$parameters["extra"]; $fieldstruct .= " ".$parameters["extra"];
} }
if (!is_null($parameters["comment"])) { if (!empty($parameters["comment"])) {
$fieldstruct .= " COMMENT '".dbesc($parameters["comment"])."'"; $fieldstruct .= " COMMENT '".dbesc($parameters["comment"])."'";
} }
@ -579,7 +579,7 @@ class DBStructure
} }
} }
if (!is_null($structure["indexes"])) { if (!empty($structure["indexes"])) {
foreach ($structure["indexes"] AS $indexname => $fieldnames) { foreach ($structure["indexes"] AS $indexname => $fieldnames) {
$sql_index = self::createIndex($indexname, $fieldnames, ""); $sql_index = self::createIndex($indexname, $fieldnames, "");
if (!is_null($sql_index)) { if (!is_null($sql_index)) {
@ -588,11 +588,11 @@ class DBStructure
} }
} }
if (!is_null($structure["engine"])) { if (!empty($structure["engine"])) {
$engine = " ENGINE=" . $structure["engine"]; $engine = " ENGINE=" . $structure["engine"];
} }
if (!is_null($structure["comment"])) { if (!empty($structure["comment"])) {
$comment = " COMMENT='" . dbesc($structure["comment"]) . "'"; $comment = " COMMENT='" . dbesc($structure["comment"]) . "'";
} }

View File

@ -61,7 +61,7 @@ class Conversation
unset($old_conv['source']); unset($old_conv['source']);
} }
// Update structure data all the time but the source only when its from a better protocol. // Update structure data all the time but the source only when its from a better protocol.
if (($old_conv['protocol'] < $conversation['protocol']) && ($old_conv['protocol'] != 0)) { if (isset($conversation['protocol']) && isset($conversation['source']) && ($old_conv['protocol'] < $conversation['protocol']) && ($old_conv['protocol'] != 0)) {
unset($conversation['protocol']); unset($conversation['protocol']);
unset($conversation['source']); unset($conversation['source']);
} }

View File

@ -809,7 +809,9 @@ class Item extends BaseObject
// If item has attachments, drop them // If item has attachments, drop them
foreach (explode(", ", $item['attach']) as $attach) { foreach (explode(", ", $item['attach']) as $attach) {
preg_match("|attach/(\d+)|", $attach, $matches); preg_match("|attach/(\d+)|", $attach, $matches);
dba::delete('attach', ['id' => $matches[1], 'uid' => $item['uid']]); if (is_array($matches) && count($matches) > 1) {
dba::delete('attach', ['id' => $matches[1], 'uid' => $item['uid']]);
}
} }
// Delete tags that had been attached to other items // Delete tags that had been attached to other items
@ -1997,7 +1999,7 @@ class Item extends BaseObject
Contact::unmarkForArchival($contact); Contact::unmarkForArchival($contact);
} }
$update = (!$arr['private'] && (($arr["author-link"] === $arr["owner-link"]) || ($arr["parent-uri"] === $arr["uri"]))); $update = (!$arr['private'] && ((defaults($arr, 'author-link', '') === defaults($arr, 'owner-link', '')) || ($arr["parent-uri"] === $arr["uri"])));
// Is it a forum? Then we don't care about the rules from above // Is it a forum? Then we don't care about the rules from above
if (!$update && ($arr["network"] == NETWORK_DFRN) && ($arr["parent-uri"] === $arr["uri"])) { if (!$update && ($arr["network"] == NETWORK_DFRN) && ($arr["parent-uri"] === $arr["uri"])) {

View File

@ -109,6 +109,7 @@ class Probe
$redirects = 0; $redirects = 0;
logger("Probing for ".$host, LOGGER_DEBUG); logger("Probing for ".$host, LOGGER_DEBUG);
$xrd = null;
$ret = Network::curl($ssl_url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); $ret = Network::curl($ssl_url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']);
if ($ret['success']) { if ($ret['success']) {
@ -1510,6 +1511,7 @@ class Probe
return false; return false;
} }
$feed = $ret['body']; $feed = $ret['body'];
$dummy1 = $dummy2 = $dummy3 = null;
$feed_data = Feed::import($feed, $dummy1, $dummy2, $dummy3, true); $feed_data = Feed::import($feed, $dummy1, $dummy2, $dummy3, true);
if (!$feed_data) { if (!$feed_data) {

View File

@ -29,6 +29,10 @@ class ApiTest extends DatabaseTest
global $a; global $a;
parent::setUp(); parent::setUp();
// Reusable App object
$this->app = new App(__DIR__.'/../');
$a = $this->app;
// User data that the test database is populated with // User data that the test database is populated with
$this->selfUser = [ $this->selfUser = [
'id' => 42, 'id' => 42,
@ -36,6 +40,12 @@ class ApiTest extends DatabaseTest
'nick' => 'selfcontact', 'nick' => 'selfcontact',
'nurl' => 'http://localhost/profile/selfcontact' 'nurl' => 'http://localhost/profile/selfcontact'
]; ];
$this->friendUser = [
'id' => 44,
'name' => 'Friend contact',
'nick' => 'friendcontact',
'nurl' => 'http://localhost/profile/friendcontact'
];
$this->otherUser = [ $this->otherUser = [
'id' => 43, 'id' => 43,
'name' => 'othercontact', 'name' => 'othercontact',
@ -53,10 +63,6 @@ class ApiTest extends DatabaseTest
'uid' => $this->selfUser['id'] 'uid' => $this->selfUser['id']
]; ];
// Reusable App object
$this->app = new App(__DIR__.'/../');
$a = $this->app;
// Default config // Default config
Config::set('config', 'hostname', 'localhost'); Config::set('config', 'hostname', 'localhost');
Config::set('system', 'throttle_limit_day', 100); Config::set('system', 'throttle_limit_day', 100);
@ -481,7 +487,7 @@ class ApiTest extends DatabaseTest
$this->app->query_string = 'api_path.rss'; $this->app->query_string = 'api_path.rss';
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL. '<?xml version="1.0" encoding="UTF-8"?>'."\n".
'some_data', 'some_data',
api_call($this->app) api_call($this->app)
); );
@ -505,7 +511,7 @@ class ApiTest extends DatabaseTest
$this->app->query_string = 'api_path.atom'; $this->app->query_string = 'api_path.atom';
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL. '<?xml version="1.0" encoding="UTF-8"?>'."\n".
'some_data', 'some_data',
api_call($this->app) api_call($this->app)
); );
@ -571,14 +577,14 @@ class ApiTest extends DatabaseTest
public function testApiErrorWithXml() public function testApiErrorWithXml()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '. '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
'xmlns:friendica="http://friendi.ca/schema/api/1/" '. 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
'xmlns:georss="http://www.georss.org/georss">'.PHP_EOL. 'xmlns:georss="http://www.georss.org/georss">'."\n".
' <error>error_message</error>'.PHP_EOL. ' <error>error_message</error>'."\n".
' <code>200 Friendica\Network\HTTP</code>'.PHP_EOL. ' <code>200 Friendica\Network\HTTP</code>'."\n".
' <request/>'.PHP_EOL. ' <request/>'."\n".
'</status>'.PHP_EOL, '</status>'."\n",
api_error('xml', new HTTPException('error_message')) api_error('xml', new HTTPException('error_message'))
); );
} }
@ -591,14 +597,14 @@ class ApiTest extends DatabaseTest
public function testApiErrorWithRss() public function testApiErrorWithRss()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '. '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
'xmlns:friendica="http://friendi.ca/schema/api/1/" '. 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
'xmlns:georss="http://www.georss.org/georss">'.PHP_EOL. 'xmlns:georss="http://www.georss.org/georss">'."\n".
' <error>error_message</error>'.PHP_EOL. ' <error>error_message</error>'."\n".
' <code>200 Friendica\Network\HTTP</code>'.PHP_EOL. ' <code>200 Friendica\Network\HTTP</code>'."\n".
' <request/>'.PHP_EOL. ' <request/>'."\n".
'</status>'.PHP_EOL, '</status>'."\n",
api_error('rss', new HTTPException('error_message')) api_error('rss', new HTTPException('error_message'))
); );
} }
@ -611,14 +617,14 @@ class ApiTest extends DatabaseTest
public function testApiErrorWithAtom() public function testApiErrorWithAtom()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '. '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
'xmlns:friendica="http://friendi.ca/schema/api/1/" '. 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
'xmlns:georss="http://www.georss.org/georss">'.PHP_EOL. 'xmlns:georss="http://www.georss.org/georss">'."\n".
' <error>error_message</error>'.PHP_EOL. ' <error>error_message</error>'."\n".
' <code>200 Friendica\Network\HTTP</code>'.PHP_EOL. ' <code>200 Friendica\Network\HTTP</code>'."\n".
' <request/>'.PHP_EOL. ' <request/>'."\n".
'</status>'.PHP_EOL, '</status>'."\n",
api_error('atom', new HTTPException('error_message')) api_error('atom', new HTTPException('error_message'))
); );
} }
@ -629,7 +635,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiRssExtra() public function testApiRssExtra()
{ {
$user_info = ['url' => 'user_url']; $user_info = ['url' => 'user_url', 'lang' => 'en'];
$result = api_rss_extra($this->app, [], $user_info); $result = api_rss_extra($this->app, [], $user_info);
$this->assertEquals($user_info, $result['$user']); $this->assertEquals($user_info, $result['$user']);
$this->assertEquals($user_info['url'], $result['$rss']['alternate']); $this->assertEquals($user_info['url'], $result['$rss']['alternate']);
@ -818,7 +824,7 @@ class ApiTest extends DatabaseTest
public function testApiGetUserWithCalledApi() public function testApiGetUserWithCalledApi()
{ {
global $called_api; global $called_api;
$called_api = ['api_path']; $called_api = ['api', 'api_path'];
$this->assertSelfUser(api_get_user($this->app)); $this->assertSelfUser(api_get_user($this->app));
} }
@ -853,7 +859,6 @@ class ApiTest extends DatabaseTest
$this->assertSelfUser(api_get_user($this->app, 0)); $this->assertSelfUser(api_get_user($this->app, 0));
} }
/** /**
* Test the api_item_get_user() function. * Test the api_item_get_user() function.
* @return void * @return void
@ -957,12 +962,12 @@ class ApiTest extends DatabaseTest
public function testApiCreateXml() public function testApiCreateXml()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '. '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
'xmlns:friendica="http://friendi.ca/schema/api/1/" '. 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
'xmlns:georss="http://www.georss.org/georss">'.PHP_EOL. 'xmlns:georss="http://www.georss.org/georss">'."\n".
' <data>some_data</data>'.PHP_EOL. ' <data>some_data</data>'."\n".
'</root_element>'.PHP_EOL, '</root_element>'."\n",
api_create_xml(['data' => ['some_data']], 'root_element') api_create_xml(['data' => ['some_data']], 'root_element')
); );
} }
@ -974,10 +979,10 @@ class ApiTest extends DatabaseTest
public function testApiCreateXmlWithoutNamespaces() public function testApiCreateXmlWithoutNamespaces()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<ok>'.PHP_EOL. '<ok>'."\n".
' <data>some_data</data>'.PHP_EOL. ' <data>some_data</data>'."\n".
'</ok>'.PHP_EOL, '</ok>'."\n",
api_create_xml(['data' => ['some_data']], 'ok') api_create_xml(['data' => ['some_data']], 'ok')
); );
} }
@ -999,12 +1004,12 @@ class ApiTest extends DatabaseTest
public function testApiFormatDataWithXml() public function testApiFormatDataWithXml()
{ {
$this->assertEquals( $this->assertEquals(
'<?xml version="1.0"?>'.PHP_EOL. '<?xml version="1.0"?>'."\n".
'<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '. '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
'xmlns:friendica="http://friendi.ca/schema/api/1/" '. 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
'xmlns:georss="http://www.georss.org/georss">'.PHP_EOL. 'xmlns:georss="http://www.georss.org/georss">'."\n".
' <data>some_data</data>'.PHP_EOL. ' <data>some_data</data>'."\n".
'</root_element>'.PHP_EOL, '</root_element>'."\n",
api_format_data('root_element', 'xml', ['data' => ['some_data']]) api_format_data('root_element', 'xml', ['data' => ['some_data']])
); );
} }
@ -1073,6 +1078,7 @@ class ApiTest extends DatabaseTest
'width' => 666, 'width' => 666,
'height' => 666, 'height' => 666,
'tmp_name' => $this->getTempImage(), 'tmp_name' => $this->getTempImage(),
'name' => 'spacer.png',
'type' => 'image/png' 'type' => 'image/png'
] ]
]; ];
@ -1110,6 +1116,7 @@ class ApiTest extends DatabaseTest
'width' => 666, 'width' => 666,
'height' => 666, 'height' => 666,
'tmp_name' => $this->getTempImage(), 'tmp_name' => $this->getTempImage(),
'name' => 'spacer.png',
'type' => 'image/png' 'type' => 'image/png'
] ]
]; ];
@ -1217,6 +1224,7 @@ class ApiTest extends DatabaseTest
'width' => 666, 'width' => 666,
'height' => 666, 'height' => 666,
'tmp_name' => $this->getTempImage(), 'tmp_name' => $this->getTempImage(),
'name' => 'spacer.png',
'type' => 'image/png' 'type' => 'image/png'
] ]
]; ];
@ -1833,6 +1841,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroy() public function testApiFavoritesCreateDestroy()
{ {
$this->app->argv = ['api', '1.1', 'favorites', 'create'];
$this->app->argc = count($this->app->argv);
api_favorites_create_destroy('json'); api_favorites_create_destroy('json');
} }
@ -1843,9 +1853,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithInvalidId() public function testApiFavoritesCreateDestroyWithInvalidId()
{ {
// This triggers a very specific condition ($action_argv_id + 2) $this->app->argv = ['api', '1.1', 'favorites', 'create', '12.json'];
$this->app->argv[1] = '1.1'; $this->app->argc = count($this->app->argv);
$this->app->argc = 5;
api_favorites_create_destroy('json'); api_favorites_create_destroy('json');
} }
@ -1856,8 +1865,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithInvalidAction() public function testApiFavoritesCreateDestroyWithInvalidAction()
{ {
$this->app->argv[1] = '1.1'; $this->app->argv = ['api', '1.1', 'favorites', 'change.json'];
$this->app->argc = 10; $this->app->argc = count($this->app->argv);
$_REQUEST['id'] = 1; $_REQUEST['id'] = 1;
api_favorites_create_destroy('json'); api_favorites_create_destroy('json');
} }
@ -1868,9 +1877,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithCreateAction() public function testApiFavoritesCreateDestroyWithCreateAction()
{ {
$this->app->argv[1] = '1.1'; $this->app->argv = ['api', '1.1', 'favorites', 'create.json'];
$this->app->argv[3] = 'create'; $this->app->argc = count($this->app->argv);
$this->app->argc = 10;
$_REQUEST['id'] = 3; $_REQUEST['id'] = 3;
$result = api_favorites_create_destroy('json'); $result = api_favorites_create_destroy('json');
$this->assertStatus($result['status']); $this->assertStatus($result['status']);
@ -1882,9 +1890,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithCreateActionAndRss() public function testApiFavoritesCreateDestroyWithCreateActionAndRss()
{ {
$this->app->argv[1] = '1.1'; $this->app->argv = ['api', '1.1', 'favorites', 'create.rss'];
$this->app->argv[3] = 'create'; $this->app->argc = count($this->app->argv);
$this->app->argc = 10;
$_REQUEST['id'] = 3; $_REQUEST['id'] = 3;
$result = api_favorites_create_destroy('rss'); $result = api_favorites_create_destroy('rss');
$this->assertXml($result, 'status'); $this->assertXml($result, 'status');
@ -1896,9 +1903,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithDestroyAction() public function testApiFavoritesCreateDestroyWithDestroyAction()
{ {
$this->app->argv[1] = '1.1'; $this->app->argv = ['api', '1.1', 'favorites', 'destroy.json'];
$this->app->argv[3] = 'destroy'; $this->app->argc = count($this->app->argv);
$this->app->argc = 10;
$_REQUEST['id'] = 3; $_REQUEST['id'] = 3;
$result = api_favorites_create_destroy('json'); $result = api_favorites_create_destroy('json');
$this->assertStatus($result['status']); $this->assertStatus($result['status']);
@ -1911,6 +1917,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFavoritesCreateDestroyWithoutAuthenticatedUser() public function testApiFavoritesCreateDestroyWithoutAuthenticatedUser()
{ {
$this->app->argv = ['api', '1.1', 'favorites', 'create.json'];
$this->app->argc = count($this->app->argv);
$_SESSION['authenticated'] = false; $_SESSION['authenticated'] = false;
api_favorites_create_destroy('json'); api_favorites_create_destroy('json');
} }
@ -1962,7 +1970,7 @@ class ApiTest extends DatabaseTest
['id' => 2, 'screen_name' => 'recipient_name'], ['id' => 2, 'screen_name' => 'recipient_name'],
['id' => 3, 'screen_name' => 'sender_name'] ['id' => 3, 'screen_name' => 'sender_name']
); );
$this->assertEquals('item_title'.PHP_EOL.'item_body', $result['text']); $this->assertEquals('item_title'."\n".'item_body', $result['text']);
$this->assertEquals(1, $result['id']); $this->assertEquals(1, $result['id']);
$this->assertEquals(2, $result['recipient_id']); $this->assertEquals(2, $result['recipient_id']);
$this->assertEquals(3, $result['sender_id']); $this->assertEquals(3, $result['sender_id']);
@ -2014,8 +2022,8 @@ class ApiTest extends DatabaseTest
['id' => 2, 'screen_name' => 'recipient_name'], ['id' => 2, 'screen_name' => 'recipient_name'],
['id' => 3, 'screen_name' => 'sender_name'] ['id' => 3, 'screen_name' => 'sender_name']
); );
$this->assertNull($result['sender']); $this->assertTrue(!isset($result['sender']));
$this->assertNull($result['recipient']); $this->assertTrue(!isset($result['recipient']));
} }
/** /**
@ -2051,7 +2059,8 @@ class ApiTest extends DatabaseTest
'repellat officia illum quos impedit quam iste esse unde qui '. 'repellat officia illum quos impedit quam iste esse unde qui '.
'suscipit aut facilis ut inventore omnis exercitationem quo magnam '. 'suscipit aut facilis ut inventore omnis exercitationem quo magnam '.
'consequatur maxime aut illum soluta quaerat natus unde aspernatur '. 'consequatur maxime aut illum soluta quaerat natus unde aspernatur '.
'et sed beatae nihil ullam temporibus corporis ratione blanditiis' 'et sed beatae nihil ullam temporibus corporis ratione blanditiis',
'plink' => 'item_plink'
] ]
); );
$this->assertStringStartsWith('item_title', $result['text']); $this->assertStringStartsWith('item_title', $result['text']);
@ -2108,7 +2117,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiGetAttachmentsWithImage() public function testApiGetAttachmentsWithImage()
{ {
$body = '[img]img_url[/img]'; $body = '[img]http://via.placeholder.com/1x1.png[/img]';
$this->assertInternalType('array', api_get_attachments($body)); $this->assertInternalType('array', api_get_attachments($body));
} }
@ -2119,7 +2128,7 @@ class ApiTest extends DatabaseTest
public function testApiGetAttachmentsWithImageAndAndStatus() public function testApiGetAttachmentsWithImageAndAndStatus()
{ {
$_SERVER['HTTP_USER_AGENT'] = 'AndStatus'; $_SERVER['HTTP_USER_AGENT'] = 'AndStatus';
$body = '[img]img_url[/img]'; $body = '[img]http://via.placeholder.com/1x1.png[/img]';
$this->assertInternalType('array', api_get_attachments($body)); $this->assertInternalType('array', api_get_attachments($body));
} }
@ -2155,7 +2164,7 @@ class ApiTest extends DatabaseTest
public function testApiFormatItemsEmbededImages() public function testApiFormatItemsEmbededImages()
{ {
$this->assertEquals( $this->assertEquals(
'text http://localhost/display/item_guid', 'text ' . \Friendica\Core\System::baseUrl() . '/display/item_guid',
api_format_items_embeded_images(['guid' => 'item_guid'], 'text data:image/foo') api_format_items_embeded_images(['guid' => 'item_guid'], 'text data:image/foo')
); );
} }
@ -2196,7 +2205,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFormatItemsActivities() public function testApiFormatItemsActivities()
{ {
$item = []; $item = ['uid' => 0, 'uri' => ''];
$result = api_format_items_activities($item); $result = api_format_items_activities($item);
$this->assertArrayHasKey('like', $result); $this->assertArrayHasKey('like', $result);
$this->assertArrayHasKey('dislike', $result); $this->assertArrayHasKey('dislike', $result);
@ -2211,7 +2220,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFormatItemsActivitiesWithXml() public function testApiFormatItemsActivitiesWithXml()
{ {
$item = []; $item = ['uid' => 0, 'uri' => ''];
$result = api_format_items_activities($item, 'xml'); $result = api_format_items_activities($item, 'xml');
$this->assertArrayHasKey('friendica:like', $result); $this->assertArrayHasKey('friendica:like', $result);
$this->assertArrayHasKey('friendica:dislike', $result); $this->assertArrayHasKey('friendica:dislike', $result);
@ -2325,10 +2334,16 @@ class ApiTest extends DatabaseTest
[ [
'item_network' => 'item_network', 'item_network' => 'item_network',
'source' => 'web', 'source' => 'web',
'coord' => '5 7' 'coord' => '5 7',
'body' => '',
'verb' => '',
'author-id' => 43,
'author-network' => \Friendica\Core\Protocol::DFRN,
'author-link' => 'http://localhost/profile/othercontact',
'plink' => '',
] ]
]; ];
$result = api_format_items($items, [], true); $result = api_format_items($items, ['id' => 0], true);
foreach ($result as $status) { foreach ($result as $status) {
$this->assertStatus($status); $this->assertStatus($status);
} }
@ -2342,10 +2357,16 @@ class ApiTest extends DatabaseTest
{ {
$items = [ $items = [
[ [
'coord' => '5 7' 'coord' => '5 7',
'body' => '',
'verb' => '',
'author-id' => 43,
'author-network' => \Friendica\Core\Protocol::DFRN,
'author-link' => 'http://localhost/profile/othercontact',
'plink' => '',
] ]
]; ];
$result = api_format_items($items, [], true, 'xml'); $result = api_format_items($items, ['id' => 0], true, 'xml');
foreach ($result as $status) { foreach ($result as $status) {
$this->assertStatus($status); $this->assertStatus($status);
} }
@ -2389,7 +2410,6 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiHelpTestWithXml() public function testApiHelpTestWithXml()
{ {
$this->markTestIncomplete('Triggers this error: "key() expects parameter 1 to be array, string given"');
$result = api_help_test('xml'); $result = api_help_test('xml');
$this->assertXml($result, 'ok'); $this->assertXml($result, 'ok');
} }
@ -2615,7 +2635,7 @@ class ApiTest extends DatabaseTest
$result = api_statusnet_config('json'); $result = api_statusnet_config('json');
$this->assertEquals('localhost', $result['config']['site']['server']); $this->assertEquals('localhost', $result['config']['site']['server']);
$this->assertEquals('default', $result['config']['site']['theme']); $this->assertEquals('default', $result['config']['site']['theme']);
$this->assertEquals('http://localhost/images/friendica-64.png', $result['config']['site']['logo']); $this->assertEquals(\Friendica\Core\System::baseUrl() . '/images/friendica-64.png', $result['config']['site']['logo']);
$this->assertTrue($result['config']['site']['fancy']); $this->assertTrue($result['config']['site']['fancy']);
$this->assertEquals('en', $result['config']['site']['language']); $this->assertEquals('en', $result['config']['site']['language']);
$this->assertEquals('UTC', $result['config']['site']['timezone']); $this->assertEquals('UTC', $result['config']['site']['timezone']);
@ -2725,7 +2745,7 @@ class ApiTest extends DatabaseTest
public function testApiDirectMessagesNewWithScreenName() public function testApiDirectMessagesNewWithScreenName()
{ {
$_POST['text'] = 'message_text'; $_POST['text'] = 'message_text';
$_POST['screen_name'] = $this->otherUser['nick']; $_POST['screen_name'] = $this->friendUser['nick'];
$result = api_direct_messages_new('json'); $result = api_direct_messages_new('json');
$this->assertEquals(1, $result['direct_message']['id']); $this->assertEquals(1, $result['direct_message']['id']);
$this->assertContains('message_text', $result['direct_message']['text']); $this->assertContains('message_text', $result['direct_message']['text']);
@ -2740,7 +2760,7 @@ class ApiTest extends DatabaseTest
public function testApiDirectMessagesNewWithTitle() public function testApiDirectMessagesNewWithTitle()
{ {
$_POST['text'] = 'message_text'; $_POST['text'] = 'message_text';
$_POST['screen_name'] = $this->otherUser['nick']; $_POST['screen_name'] = $this->friendUser['nick'];
$_REQUEST['title'] = 'message_title'; $_REQUEST['title'] = 'message_title';
$result = api_direct_messages_new('json'); $result = api_direct_messages_new('json');
$this->assertEquals(1, $result['direct_message']['id']); $this->assertEquals(1, $result['direct_message']['id']);
@ -2757,7 +2777,7 @@ class ApiTest extends DatabaseTest
public function testApiDirectMessagesNewWithRss() public function testApiDirectMessagesNewWithRss()
{ {
$_POST['text'] = 'message_text'; $_POST['text'] = 'message_text';
$_POST['screen_name'] = $this->otherUser['nick']; $_POST['screen_name'] = $this->friendUser['nick'];
$result = api_direct_messages_new('rss'); $result = api_direct_messages_new('rss');
$this->assertXml($result, 'direct-messages'); $this->assertXml($result, 'direct-messages');
} }
@ -3357,7 +3377,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiShareAsRetweet() public function testApiShareAsRetweet()
{ {
$item = []; $item = ['body' => ''];
$result = api_share_as_retweet($item); $result = api_share_as_retweet($item);
$this->assertFalse($result); $this->assertFalse($result);
} }
@ -3397,7 +3417,7 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiInReplyTo() public function testApiInReplyTo()
{ {
$result = api_in_reply_to([]); $result = api_in_reply_to(['id' => 0, 'parent' => 0, 'uri' => '', 'thr-parent' => '']);
$this->assertArrayHasKey('status_id', $result); $this->assertArrayHasKey('status_id', $result);
$this->assertArrayHasKey('user_id', $result); $this->assertArrayHasKey('user_id', $result);
$this->assertArrayHasKey('status_id_str', $result); $this->assertArrayHasKey('status_id_str', $result);
@ -3562,7 +3582,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFriendicaNotificationWithArgumentCount() public function testApiFriendicaNotificationWithArgumentCount()
{ {
$this->app->argc = 3; $this->app->argv = ['api', 'friendica', 'notification'];
$this->app->argc = count($this->app->argv);
$result = api_friendica_notification('json'); $result = api_friendica_notification('json');
$this->assertEquals(['note' => false], $result); $this->assertEquals(['note' => false], $result);
} }
@ -3573,8 +3594,8 @@ class ApiTest extends DatabaseTest
*/ */
public function testApiFriendicaNotificationWithXmlResult() public function testApiFriendicaNotificationWithXmlResult()
{ {
$this->markTestIncomplete('Fails with "Invalid argument supplied for foreach()".'); $this->app->argv = ['api', 'friendica', 'notification'];
$this->app->argc = 3; $this->app->argc = count($this->app->argv);
$result = api_friendica_notification('xml'); $result = api_friendica_notification('xml');
$this->assertXml($result, 'notes'); $this->assertXml($result, 'notes');
} }

View File

@ -20,6 +20,54 @@ abstract class DatabaseTest extends TestCase
use TestCaseTrait; use TestCaseTrait;
/**
* Renames an eventually existing .htconfig.php to .htconfig.php.tmp
* Creates a new .htconfig.php for bin/worker.php execution
*/
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
$base_config_file_name = 'htconfig.php';
$config_file_name = '.htconfig.php';
$base_config_file_path = stream_resolve_include_path($base_config_file_name);
$config_file_path = dirname($base_config_file_path) . DIRECTORY_SEPARATOR . $config_file_name;
$config_file_path_tmp = $config_file_path . '.tmp';
if (file_exists($config_file_path)) {
rename($config_file_path, $config_file_path_tmp);
}
$config_string = file_get_contents($base_config_file_path);
$config_string = str_replace('die(', '// die(', $config_string);
file_put_contents($config_file_path, $config_string);
}
/**
* Delete the created .htconfig.php
* Renames an eventually existing .htconfig.php.tmp to .htconfig.php
*/
public static function tearDownAfterClass()
{
$base_config_file_name = 'htconfig.php';
$config_file_name = '.htconfig.php';
$base_config_file_path = stream_resolve_include_path($base_config_file_name);
$config_file_path = dirname($base_config_file_path) . DIRECTORY_SEPARATOR . $config_file_name;
$config_file_path_tmp = $config_file_path . '.tmp';
if (file_exists($config_file_path)) {
unlink($config_file_path);
}
if (file_exists($config_file_path_tmp)) {
rename($config_file_path_tmp, $config_file_path);
}
}
/** /**
* Get database connection. * Get database connection.
* *
@ -34,21 +82,23 @@ abstract class DatabaseTest extends TestCase
protected function getConnection() protected function getConnection()
{ {
if (!dba::$connected) { if (!dba::$connected) {
dba::connect('localhost', getenv('USER'), getenv('PASS'), getenv('DB')); dba::connect(getenv('MYSQL_HOST') . ':' . getenv('MYSQL_PORT'), getenv('MYSQL_USERNAME'), getenv('MYSQL_PASSWORD'), getenv('MYSQL_DATABASE'));
if (dba::$connected) { if (dba::$connected) {
$app = get_app(); $app = get_app();
// We need to do this in order to disable logging // We need to do this in order to disable logging
$app->module = 'install'; $app->mode = \Friendica\App::MODE_INSTALL;
// Create database structure // Create database structure
DBStructure::update(false, true, true); DBStructure::update(false, true, true);
$app->mode = \Friendica\App::MODE_NORMAL;
} else { } else {
$this->markTestSkipped('Could not connect to the database.'); $this->markTestSkipped('Could not connect to the database. Please check the MYSQL_* environment variables.');
} }
} }
return $this->createDefaultDBConnection(dba::get_db(), getenv('DB')); return $this->createDefaultDBConnection(dba::get_db(), getenv('MYSQL_DATABASE'));
} }
/** /**

View File

@ -48,7 +48,7 @@ contact:
network: dfrn network: dfrn
- -
id: 44 id: 44
uid: 0 uid: 42
name: Friend contact name: Friend contact
nick: friendcontact nick: friendcontact
self: 0 self: 0