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

This commit is contained in:
Ralf Thees 2018-08-23 16:58:18 +02:00
commit 9b5bef6dea
41 changed files with 889 additions and 673 deletions

View File

@ -634,6 +634,73 @@ Friendica doesn't allow showing the friends of other users.
* trim_user * trim_user
* contributor_details * contributor_details
---
### Return values for statuses/* api calls
Returned status object is conform to GNU Social/Twitter api.
Friendica adds some addictional fields:
- owner: a user object, it's the owner of the item.
- private: boolean, true if the item is marked as private
- activities: map with activities related to the item. Every activity is a list of user objects.
This properties are prefixed with "friendica_" in JSON responses and namespaced under "http://friendi.ca/schema/api/1/" in XML responses
JSON:
```json
[
{
// ...
'friendica_owner' : {
// user object
},
'friendica_private' : true,
'friendica_activities': {
'like': [
{
// user object
},
// ...
],
'dislike': [],
'attendyes': [],
'attendno': [],
'attendmaybe': []
}
},
// ...
]
```
XML:
```xml
<statuses xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" xmlns:friendica="http://friendi.ca/schema/api/1/" xmlns:georss="http://www.georss.org/georss">
<status>
<!-- ... -->
<friendica:owner><!-- user object --></friendica:owner>
<friendica:private>true</friendica:private>
<friendica:activities>
<friendica:like>
<user>
<!-- user object -->
</user>
<!-- ... --->
</friendica:like>
<friendica:dislike/>
<friendica:attendyes/>
<friendica:attendno/>
<friendica:attendmaybe/>
</friendica:activities>
</status>
<!-- ... -->
</statuses>
```
--- ---
### statusnet/config (*) ### statusnet/config (*)

View File

@ -2888,6 +2888,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json")
'favorited' => $item['starred'] ? true : false, 'favorited' => $item['starred'] ? true : false,
'user' => $status_user , 'user' => $status_user ,
'friendica_owner' => $owner_user, 'friendica_owner' => $owner_user,
'friendica_private' => $item['private'] == 1,
//'entities' => NULL, //'entities' => NULL,
'statusnet_html' => $converted["html"], 'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $item['parent'], 'statusnet_conversation_id' => $item['parent'],

View File

@ -471,6 +471,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
. "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; . "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
} }
} elseif ($mode === 'profile') { } elseif ($mode === 'profile') {
$items = conversation_add_children($items, false, $order, $uid);
$profile_owner = $a->profile['profile_uid']; $profile_owner = $a->profile['profile_uid'];
if (!$update) { if (!$update) {
@ -490,6 +491,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
} }
} }
} elseif ($mode === 'notes') { } elseif ($mode === 'notes') {
$items = conversation_add_children($items, false, $order, $uid);
$profile_owner = local_user(); $profile_owner = local_user();
if (!$update) { if (!$update) {
@ -498,6 +500,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
. "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n"; . "; var netargs = '/?f='; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
} }
} elseif ($mode === 'display') { } elseif ($mode === 'display') {
$items = conversation_add_children($items, false, $order, $uid);
$profile_owner = $a->profile['uid']; $profile_owner = $a->profile['uid'];
if (!$update) { if (!$update) {

View File

@ -5,9 +5,9 @@ use Friendica\Database\DBA;
/** /**
* @brief execute SQL query with printf style args - deprecated * @brief execute SQL query with printf style args - deprecated
* *
* Please use the dba:: functions instead: * Please use the DBA:: functions instead:
* dba::select, dba::exists, dba::insert * DBA::select, DBA::exists, DBA::insert
* dba::delete, dba::update, dba::p, dba::e * DBA::delete, DBA::update, DBA::p, DBA::e
* *
* @param $args Query parameters (1 to N parameters of different types) * @param $args Query parameters (1 to N parameters of different types)
* @return array|bool Query array * @return array|bool Query array

View File

@ -32,6 +32,20 @@ function notification($params)
logger('Missing parameters.' . System::callstack()); logger('Missing parameters.' . System::callstack());
} }
// Ensure that the important fields are set at any time
$fields = ['notify-flags', 'language', 'username', 'email'];
$user = DBA::selectFirst('user', $fields, ['uid' => $params['uid']]);
if (!DBA::isResult($user)) {
logger('Unknown user ' . $params['uid']);
return;
}
$params['notify_flags'] = defaults($params, 'notify_flags', $user['notify-flags']);
$params['language'] = defaults($params, 'language', $user['language']);
$params['to_name'] = defaults($params, 'to_name', $user['username']);
$params['to_email'] = defaults($params, 'to_email', $user['email']);
// from here on everything is in the recipients language // from here on everything is in the recipients language
L10n::pushLang($params['language']); L10n::pushLang($params['language']);
@ -510,7 +524,7 @@ function notification($params)
} }
// send email notification if notification preferences permit // send email notification if notification preferences permit
if ((!empty($params['notify_flags']) & intval($params['type'])) if ((intval($params['notify_flags']) & intval($params['type']))
|| $params['type'] == NOTIFY_SYSTEM || $params['type'] == NOTIFY_SYSTEM
|| $params['type'] == SYSTEM_EMAIL) { || $params['type'] == SYSTEM_EMAIL) {
@ -661,7 +675,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
$profiles = $notification_data["profiles"]; $profiles = $notification_data["profiles"];
$fields = ['notify-flags', 'language', 'username', 'email', 'nickname']; $fields = ['nickname'];
$user = DBA::selectFirst('user', $fields, ['uid' => $uid]); $user = DBA::selectFirst('user', $fields, ['uid' => $uid]);
if (!DBA::isResult($user)) { if (!DBA::isResult($user)) {
return false; return false;
@ -724,10 +738,6 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
// Generate the notification array // Generate the notification array
$params = []; $params = [];
$params["uid"] = $uid; $params["uid"] = $uid;
$params["notify_flags"] = $user["notify-flags"];
$params["language"] = $user["language"];
$params["to_name"] = $user["username"];
$params["to_email"] = $user["email"];
$params["item"] = $item; $params["item"] = $item;
$params["parent"] = $item["parent"]; $params["parent"] = $item["parent"];
$params["link"] = System::baseUrl().'/display/'.urlencode($item["guid"]); $params["link"] = System::baseUrl().'/display/'.urlencode($item["guid"]);

View File

@ -371,7 +371,7 @@ function drop_item($id)
if ((local_user() == $item['uid']) || $contact_id) { if ((local_user() == $item['uid']) || $contact_id) {
// Check if we should do HTML-based delete confirmation // Check if we should do HTML-based delete confirmation
if ($_REQUEST['confirm']) { if (!empty($_REQUEST['confirm'])) {
// <form> can't take arguments in its "action" parameter // <form> can't take arguments in its "action" parameter
// so add any arguments as hidden inputs // so add any arguments as hidden inputs
$query = explode_querystring($a->query_string); $query = explode_querystring($a->query_string);
@ -395,7 +395,7 @@ function drop_item($id)
]); ]);
} }
// Now check how the user responded to the confirmation query // Now check how the user responded to the confirmation query
if ($_REQUEST['canceled']) { if (!empty($_REQUEST['canceled'])) {
goaway(System::baseUrl() . '/' . $_SESSION['return_url']); goaway(System::baseUrl() . '/' . $_SESSION['return_url']);
} }

View File

@ -10,6 +10,7 @@ use Friendica\Core\Config;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig; use Friendica\Core\PConfig;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Contact;
function community_init(App $a) function community_init(App $a)
{ {
@ -35,6 +36,25 @@ function community_content(App $a, $update = 0)
return; return;
} }
$accounttype = null;
if ($a->argc > 2) {
switch ($a->argv[2]) {
case 'person':
$accounttype = Contact::ACCOUNT_TYPE_PERSON;
break;
case 'organisation':
$accounttype = Contact::ACCOUNT_TYPE_ORGANISATION;
break;
case 'news':
$accounttype = Contact::ACCOUNT_TYPE_NEWS;
break;
case 'community':
$accounttype = Contact::ACCOUNT_TYPE_COMMUNITY;
break;
}
}
if ($a->argc > 1) { if ($a->argc > 1) {
$content = $a->argv[1]; $content = $a->argv[1];
} else { } else {
@ -135,7 +155,7 @@ function community_content(App $a, $update = 0)
$a->set_pager_itemspage($itemspage_network); $a->set_pager_itemspage($itemspage_network);
$r = community_getitems($a->pager['start'], $a->pager['itemspage'], $content); $r = community_getitems($a->pager['start'], $a->pager['itemspage'], $content, $accounttype);
if (!DBA::isResult($r)) { if (!DBA::isResult($r)) {
info(L10n::t('No results.') . EOL); info(L10n::t('No results.') . EOL);
@ -164,7 +184,7 @@ function community_content(App $a, $update = 0)
} }
} }
if (count($s) < $a->pager['itemspage']) { if (count($s) < $a->pager['itemspage']) {
$r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage'], $content); $r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage'], $content, $accounttype);
} }
} while ((count($s) < $a->pager['itemspage']) && ( ++$count < 50) && (count($r) > 0)); } while ((count($s) < $a->pager['itemspage']) && ( ++$count < 50) && (count($r) > 0));
} else { } else {
@ -186,24 +206,40 @@ function community_content(App $a, $update = 0)
]); ]);
} }
function community_getitems($start, $itemspage, $content) function community_getitems($start, $itemspage, $content, $accounttype)
{ {
if ($content == 'local') { if ($content == 'local') {
if (!is_null($accounttype)) {
$sql_accounttype = " AND `user`.`account-type` = ?";
$values = [$accounttype, $start, $itemspage];
} else {
$sql_accounttype = "";
$values = [$start, $itemspage];
}
$r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread` $r = DBA::p("SELECT `item`.`uri`, `author`.`url` AS `author-link` FROM `thread`
INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall` INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id` INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated` WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin` AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin` $sql_accounttype
ORDER BY `thread`.`commented` DESC LIMIT " . intval($start) . ", " . intval($itemspage) ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);
);
return DBA::toArray($r); return DBA::toArray($r);
} elseif ($content == 'global') { } elseif ($content == 'global') {
if (!is_null($accounttype)) {
$sql_accounttype = " AND `owner`.`contact-type` = ?";
$values = [$accounttype, $start, $itemspage];
} else {
$sql_accounttype = "";
$values = [$start, $itemspage];
}
$r = DBA::p("SELECT `uri` FROM `thread` $r = DBA::p("SELECT `uri` FROM `thread`
INNER JOIN `item` ON `item`.`id` = `thread`.`iid` INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id` INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
WHERE `thread`.`uid` = 0 AND NOT `author`.`hidden` AND NOT `author`.`blocked` INNER JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id`
ORDER BY `thread`.`commented` DESC LIMIT " . intval($start) . ", " . intval($itemspage)); WHERE `thread`.`uid` = 0 AND NOT `author`.`hidden` AND NOT `author`.`blocked` $sql_accounttype
ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);
return DBA::toArray($r); return DBA::toArray($r);
} }

View File

@ -71,7 +71,7 @@ function dfrn_notify_post(App $a) {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]); $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
if (!DBA::isResult($user)) { if (!DBA::isResult($user)) {
logger('User not found for nickname ' . $$a->argv[1]); logger('User not found for nickname ' . $a->argv[1]);
System::xmlExit(3, 'User not found'); System::xmlExit(3, 'User not found');
} }
@ -280,7 +280,7 @@ function dfrn_notify_content(App $a) {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]); $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
if (!DBA::isResult($user)) { if (!DBA::isResult($user)) {
logger('User not found for nickname ' . $$a->argv[1]); logger('User not found for nickname ' . $a->argv[1]);
killme(); killme();
} }

View File

@ -480,6 +480,12 @@ function dfrn_poll_content(App $a)
} }
if (($type === 'profile') && (strlen($sec))) { if (($type === 'profile') && (strlen($sec))) {
// heluecht: I don't know why we don't fail immediately when the user or contact hadn't been found.
// Since it doesn't make sense to continue from this point on, we now fail here. This should be safe.
if (!DBA::isResult($r)) {
System::httpExit(404, ["title" => L10n::t('Page not found.')]);
}
// URL reply // URL reply
if ($dfrn_version < 2.2) { if ($dfrn_version < 2.2) {
$s = Network::fetchUrl($r[0]['poll'] $s = Network::fetchUrl($r[0]['poll']

View File

@ -333,35 +333,34 @@ function display_content(App $a, $update = false, $update_uid = 0)
return ''; return '';
} }
$condition = ["`item`.`parent-uri` = (SELECT `parent-uri` FROM `item` WHERE `id` = ?) $condition = ["`id` = ? AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, local_user()];
AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, local_user()]; $fields = ['parent-uri', 'body', 'title', 'author-name', 'author-avatar', 'plink'];
$params = ['order' => ['uid', 'parent' => true, 'gravity', 'id']]; $item = Item::selectFirstForUser(local_user(), $fields, $condition);
$items_obj = Item::selectForUser(local_user(), [], $condition, $params);
if (!DBA::isResult($items_obj)) { if (!DBA::isResult($item)) {
notice(L10n::t('Item not found.') . EOL); notice(L10n::t('Item not found.') . EOL);
return $o; return $o;
} }
$item['uri'] = $item['parent-uri'];
if ($unseen) { if ($unseen) {
$condition = ['parent-uri' => $item_parent_uri, 'uid' => local_user(), 'unseen' => true]; $condition = ['parent-uri' => $item_parent_uri, 'uid' => local_user(), 'unseen' => true];
Item::update(['unseen' => false], $condition); Item::update(['unseen' => false], $condition);
} }
$items = Item::inArray($items_obj);
$conversation_items = conv_sort($items, "`commented`");
if (!$update) { if (!$update) {
$o .= "<script> var netargs = '?f=&item_id=" . $item_id . "'; </script>"; $o .= "<script> var netargs = '?f=&item_id=" . $item_id . "'; </script>";
} }
$o .= conversation($a, $conversation_items, 'display', $update_uid, false, 'commented', local_user());
$o .= conversation($a, [$item], 'display', $update_uid, false, 'commented', local_user());
// Preparing the meta header // Preparing the meta header
$description = trim(HTML::toPlaintext(BBCode::convert($items[0]["body"], false), 0, true)); $description = trim(HTML::toPlaintext(BBCode::convert($item["body"], false), 0, true));
$title = trim(HTML::toPlaintext(BBCode::convert($items[0]["title"], false), 0, true)); $title = trim(HTML::toPlaintext(BBCode::convert($item["title"], false), 0, true));
$author_name = $items[0]["author-name"]; $author_name = $item["author-name"];
$image = $a->remove_baseurl($items[0]["author-avatar"]); $image = $a->remove_baseurl($item["author-avatar"]);
if ($title == "") { if ($title == "") {
$title = $author_name; $title = $author_name;
@ -393,7 +392,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
$a->page['htmlhead'] .= '<meta name="twitter:title" content="'.$title.'" />'."\n"; $a->page['htmlhead'] .= '<meta name="twitter:title" content="'.$title.'" />'."\n";
$a->page['htmlhead'] .= '<meta name="twitter:description" content="'.$description.'" />'."\n"; $a->page['htmlhead'] .= '<meta name="twitter:description" content="'.$description.'" />'."\n";
$a->page['htmlhead'] .= '<meta name="twitter:image" content="'.System::baseUrl().'/'.$image.'" />'."\n"; $a->page['htmlhead'] .= '<meta name="twitter:image" content="'.System::baseUrl().'/'.$image.'" />'."\n";
$a->page['htmlhead'] .= '<meta name="twitter:url" content="'.$items[0]["plink"].'" />'."\n"; $a->page['htmlhead'] .= '<meta name="twitter:url" content="'.$item["plink"].'" />'."\n";
// Dublin Core // Dublin Core
$a->page['htmlhead'] .= '<meta name="DC.title" content="'.$title.'" />'."\n"; $a->page['htmlhead'] .= '<meta name="DC.title" content="'.$title.'" />'."\n";
@ -403,7 +402,7 @@ function display_content(App $a, $update = false, $update_uid = 0)
$a->page['htmlhead'] .= '<meta property="og:type" content="website" />'."\n"; $a->page['htmlhead'] .= '<meta property="og:type" content="website" />'."\n";
$a->page['htmlhead'] .= '<meta property="og:title" content="'.$title.'" />'."\n"; $a->page['htmlhead'] .= '<meta property="og:title" content="'.$title.'" />'."\n";
$a->page['htmlhead'] .= '<meta property="og:image" content="'.System::baseUrl().'/'.$image.'" />'."\n"; $a->page['htmlhead'] .= '<meta property="og:image" content="'.System::baseUrl().'/'.$image.'" />'."\n";
$a->page['htmlhead'] .= '<meta property="og:url" content="'.$items[0]["plink"].'" />'."\n"; $a->page['htmlhead'] .= '<meta property="og:url" content="'.$item["plink"].'" />'."\n";
$a->page['htmlhead'] .= '<meta property="og:description" content="'.$description.'" />'."\n"; $a->page['htmlhead'] .= '<meta property="og:description" content="'.$description.'" />'."\n";
$a->page['htmlhead'] .= '<meta name="og:article:author" content="'.$author_name.'" />'."\n"; $a->page['htmlhead'] .= '<meta name="og:article:author" content="'.$author_name.'" />'."\n";
// article:tag // article:tag

View File

@ -16,9 +16,7 @@ use Friendica\Util\Proxy as ProxyUtils;
function follow_post(App $a) function follow_post(App $a)
{ {
if (!local_user()) { if (!local_user()) {
notice(L10n::t('Permission denied.')); System::httpExit(403, ['title' => L10n::t('Access denied.')]);
goaway($_SESSION['return_url']);
// NOTREACHED
} }
if (isset($_REQUEST['cancel'])) { if (isset($_REQUEST['cancel'])) {

View File

@ -72,7 +72,20 @@ function install_post(App $a) {
// connect to db // connect to db
DBA::connect($dbhost, $dbuser, $dbpass, $dbdata); DBA::connect($dbhost, $dbuser, $dbpass, $dbdata);
Install::install($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail); $errors = Install::createConfig($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail);
if ($errors) {
$a->data['db_failed'] = $errors;
return;
}
$errors = Install::installDatabaseStructure();
if ($errors) {
$a->data['db_failed'] = $errors;
} else {
$a->data['db_installed'] = true;
}
return; return;
break; break;

View File

@ -65,26 +65,13 @@ function notes_content(App $a, $update = false)
$params = ['order' => ['created' => true], $params = ['order' => ['created' => true],
'limit' => [$a->pager['start'], $a->pager['itemspage']]]; 'limit' => [$a->pager['start'], $a->pager['itemspage']]];
$r = Item::selectForUser(local_user(), ['id'], $condition, $params); $r = Item::selectThreadForUser(local_user(), ['uri'], $condition, $params);
$count = 0; $count = 0;
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
$count = count($r); $count = count($r);
$parents_arr = []; $o .= conversation($a, DBA::toArray($r), 'notes', $update);
while ($rr = Item::fetch($r)) {
$parents_arr[] = $rr['id'];
}
DBA::close($r);
$condition = ['uid' => local_user(), 'parent' => $parents_arr];
$result = Item::selectForUser(local_user(), [], $condition);
if (DBA::isResult($result)) {
$items = conv_sort(Item::inArray($result), 'commented');
$o .= conversation($a, $items, 'notes', $update);
}
} }
$o .= alt_pager($a, $count); $o .= alt_pager($a, $count);

View File

@ -1093,6 +1093,12 @@ function photos_content(App $a)
'$albumselect' => $albumselect, '$albumselect' => $albumselect,
'$permissions' => L10n::t('Permissions'), '$permissions' => L10n::t('Permissions'),
'$aclselect' => $aclselect_e, '$aclselect' => $aclselect_e,
'$lockstate' => is_array($a->user)
&& (strlen($a->user['allow_cid'])
|| strlen($a->user['allow_gid'])
|| strlen($a->user['deny_cid'])
|| strlen($a->user['deny_gid'])
) ? 'lock' : 'unlock',
'$alt_uploader' => $ret['addon_text'], '$alt_uploader' => $ret['addon_text'],
'$default_upload_box' => ($ret['default_upload'] ? $default_upload_box : ''), '$default_upload_box' => ($ret['default_upload'] ? $default_upload_box : ''),
'$default_upload_submit' => ($ret['default_upload'] ? $default_upload_submit : ''), '$default_upload_submit' => ($ret['default_upload'] ? $default_upload_submit : ''),

View File

@ -23,7 +23,7 @@ use Friendica\Util\DateTimeFormat;
function profile_init(App $a) function profile_init(App $a)
{ {
if (!x($a->page, 'aside')) { if (empty($a->page['aside'])) {
$a->page['aside'] = ''; $a->page['aside'] = '';
} }
@ -54,15 +54,15 @@ function profile_init(App $a)
$blocked = !local_user() && !remote_user() && Config::get('system', 'block_public'); $blocked = !local_user() && !remote_user() && Config::get('system', 'block_public');
$userblock = !local_user() && !remote_user() && $a->profile['hidewall']; $userblock = !local_user() && !remote_user() && $a->profile['hidewall'];
if (x($a->profile, 'page-flags') && $a->profile['page-flags'] == Contact::PAGE_COMMUNITY) { if (!empty($a->profile['page-flags']) && $a->profile['page-flags'] == Contact::PAGE_COMMUNITY) {
$a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />'; $a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />';
} }
if (x($a->profile, 'openidserver')) { if (!empty($a->profile['openidserver'])) {
$a->page['htmlhead'] .= '<link rel="openid.server" href="' . $a->profile['openidserver'] . '" />' . "\r\n"; $a->page['htmlhead'] .= '<link rel="openid.server" href="' . $a->profile['openidserver'] . '" />' . "\r\n";
} }
if (x($a->profile, 'openid')) { if (!empty($a->profile['openid'])) {
$delegate = strstr($a->profile['openid'], '://') ? $a->profile['openid'] : 'https://' . $a->profile['openid']; $delegate = strstr($a->profile['openid'], '://') ? $a->profile['openid'] : 'https://' . $a->profile['openid'];
$a->page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\r\n"; $a->page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\r\n";
} }
@ -109,7 +109,7 @@ function profile_content(App $a, $update = 0)
} }
} }
if (!x($category)) { if (empty($category)) {
$category = defaults($_GET, 'category', ''); $category = defaults($_GET, 'category', '');
} }
@ -140,7 +140,7 @@ function profile_content(App $a, $update = 0)
$contact_id = 0; $contact_id = 0;
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) { if (!empty($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) { foreach ($_SESSION['remote'] as $v) {
if ($v['uid'] == $a->profile['profile_uid']) { if ($v['uid'] == $a->profile['profile_uid']) {
$contact_id = $v['cid']; $contact_id = $v['cid'];
@ -171,14 +171,14 @@ function profile_content(App $a, $update = 0)
$is_owner = local_user() == $a->profile['profile_uid']; $is_owner = local_user() == $a->profile['profile_uid'];
$last_updated_key = "profile:" . $a->profile['profile_uid'] . ":" . local_user() . ":" . remote_user(); $last_updated_key = "profile:" . $a->profile['profile_uid'] . ":" . local_user() . ":" . remote_user();
if (x($a->profile, 'hidewall') && !$is_owner && !$remote_contact) { if (!empty($a->profile['hidewall']) && !$is_owner && !$remote_contact) {
notice(L10n::t('Access to this profile has been restricted.') . EOL); notice(L10n::t('Access to this profile has been restricted.') . EOL);
return; return;
} }
if (!$update) { if (!$update) {
$tab = false; $tab = false;
if (x($_GET, 'tab')) { if (!empty($_GET['tab'])) {
$tab = notags(trim($_GET['tab'])); $tab = notags(trim($_GET['tab']));
} }
@ -196,7 +196,7 @@ function profile_content(App $a, $update = 0)
$commvisitor = $commpage && $remote_contact; $commvisitor = $commpage && $remote_contact;
$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true); $a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (x($category) ? xmlify($category) : '')); $a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? xmlify($category) : ''));
$a->page['aside'] .= Widget::tagCloud(); $a->page['aside'] .= Widget::tagCloud();
if (can_write_wall($a->profile['profile_uid'])) { if (can_write_wall($a->profile['profile_uid'])) {
@ -227,7 +227,7 @@ function profile_content(App $a, $update = 0)
$sql_extra2 = ''; $sql_extra2 = '';
if ($update) { if ($update) {
$last_updated = (x($_SESSION['last_updated'], $last_updated_key) ? $_SESSION['last_updated'][$last_updated_key] : 0); $last_updated = (!empty($_SESSION['last_updated'][$last_updated_key]) ? $_SESSION['last_updated'][$last_updated_key] : 0);
// If the page user is the owner of the page we should query for unseen // If the page user is the owner of the page we should query for unseen
// items. Otherwise use a timestamp of the last succesful update request. // items. Otherwise use a timestamp of the last succesful update request.
@ -238,7 +238,7 @@ function profile_content(App $a, $update = 0)
$sql_extra4 = " AND `item`.`received` > '" . $gmupdate . "'"; $sql_extra4 = " AND `item`.`received` > '" . $gmupdate . "'";
} }
$r = q("SELECT distinct(parent) AS `item_id`, `item`.`network` AS `item_network`, `item`.`created` $items = q("SELECT DISTINCT(`parent-uri`) AS `uri`
FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`uid` = %d AND `item`.`visible` AND WHERE `item`.`uid` = %d AND `item`.`visible` AND
@ -250,38 +250,33 @@ function profile_content(App $a, $update = 0)
intval($a->profile['profile_uid']), intval(GRAVITY_ACTIVITY) intval($a->profile['profile_uid']), intval(GRAVITY_ACTIVITY)
); );
if (!DBA::isResult($r)) { if (!DBA::isResult($items)) {
return ''; return '';
} }
} else { } else {
$sql_post_table = ""; $sql_post_table = "";
if (x($category)) { if (!empty($category)) {
$sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", $sql_post_table = sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
DBA::escape(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['profile_uid'])); DBA::escape(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['profile_uid']));
} }
if (x($hashtags)) { if (!empty($hashtags)) {
$sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ", $sql_post_table .= sprintf("INNER JOIN (SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d ORDER BY `tid` DESC) AS `term` ON `item`.`id` = `term`.`oid` ",
DBA::escape(protect_sprintf($hashtags)), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), intval($a->profile['profile_uid'])); DBA::escape(protect_sprintf($hashtags)), intval(TERM_OBJ_POST), intval(TERM_HASHTAG), intval($a->profile['profile_uid']));
} }
if ($datequery) { if (!empty($datequery)) {
$sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` <= '%s' ", DBA::escape(DateTimeFormat::convert($datequery, 'UTC', date_default_timezone_get())))); $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` <= '%s' ", DBA::escape(DateTimeFormat::convert($datequery, 'UTC', date_default_timezone_get()))));
} }
if ($datequery2) { if (!empty($datequery2)) {
$sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", DBA::escape(DateTimeFormat::convert($datequery2, 'UTC', date_default_timezone_get())))); $sql_extra2 .= protect_sprintf(sprintf(" AND `thread`.`created` >= '%s' ", DBA::escape(DateTimeFormat::convert($datequery2, 'UTC', date_default_timezone_get()))));
} }
// Belongs the profile page to a forum? // Does the profile page belong to a forum?
// If not then we can improve the performance with an additional condition // If not then we can improve the performance with an additional condition
$r = q("SELECT `uid` FROM `user` WHERE `uid` = %d AND `page-flags` IN (%d, %d)", $condition = ['uid' => $a->profile['profile_uid'], 'page-flags' => [Contact::PAGE_COMMUNITY, Contact::PAGE_PRVGROUP]];
intval($a->profile['profile_uid']), if (!DBA::exists('user', $condition)) {
intval(Contact::PAGE_COMMUNITY),
intval(Contact::PAGE_PRVGROUP)
);
if (!DBA::isResult($r)) {
$sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id']))); $sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id'])));
} else { } else {
$sql_extra3 = ""; $sql_extra3 = "";
@ -305,7 +300,7 @@ function profile_content(App $a, $update = 0)
$pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage'])); $pager_sql = sprintf(" LIMIT %d, %d ", intval($a->pager['start']), intval($a->pager['itemspage']));
$r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network` $items = q("SELECT `item`.`uri`
FROM `thread` FROM `thread`
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid` STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
$sql_post_table $sql_post_table
@ -321,31 +316,15 @@ function profile_content(App $a, $update = 0)
); );
} }
$parents_arr = [];
$parents_str = '';
// Set a time stamp for this page. We will make use of it when we // Set a time stamp for this page. We will make use of it when we
// search for new items (update routine) // search for new items (update routine)
$_SESSION['last_updated'][$last_updated_key] = time(); $_SESSION['last_updated'][$last_updated_key] = time();
if (DBA::isResult($r)) {
foreach ($r as $rr) {
$parents_arr[] = $rr['item_id'];
}
$condition = ['uid' => $a->profile['profile_uid'], 'parent' => $parents_arr];
$result = Item::selectForUser($a->profile['profile_uid'], [], $condition);
$items = conv_sort(Item::inArray($result), 'created');
} else {
$items = [];
}
if ($is_owner && !$update && !Config::get('theme', 'hide_eventlist')) { if ($is_owner && !$update && !Config::get('theme', 'hide_eventlist')) {
$o .= Profile::getBirthdays(); $o .= Profile::getBirthdays();
$o .= Profile::getEventsReminderHTML(); $o .= Profile::getEventsReminderHTML();
} }
if ($is_owner) { if ($is_owner) {
$unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]); $unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]);
if ($unseen) { if ($unseen) {

View File

@ -23,7 +23,7 @@ function redir_init(App $a) {
} }
if (!empty($cid)) { if (!empty($cid)) {
$fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex']; $fields = ['id', 'uid', 'nurl', 'url', 'addr', 'name', 'network', 'poll', 'issued-id', 'dfrn-id', 'duplex', 'pending'];
$contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]); $contact = DBA::selectFirst('contact', $fields, ['id' => $cid, 'uid' => [0, local_user()]]);
if (!DBA::isResult($contact)) { if (!DBA::isResult($contact)) {
notice(L10n::t('Contact not found.')); notice(L10n::t('Contact not found.'));
@ -80,7 +80,7 @@ function redir_init(App $a) {
} }
// Doing remote auth with dfrn. // Doing remote auth with dfrn.
if (local_user()&& (!empty($contact['dfrn-id']) || !empty($contact['issued-id']))) { if (local_user() && (!empty($contact['dfrn-id']) || !empty($contact['issued-id'])) && empty($contact['pending'])) {
$dfrn_id = $orig_id = (($contact['issued-id']) ? $contact['issued-id'] : $contact['dfrn-id']); $dfrn_id = $orig_id = (($contact['issued-id']) ? $contact['issued-id'] : $contact['dfrn-id']);
if ($contact['duplex'] && $contact['issued-id']) { if ($contact['duplex'] && $contact['issued-id']) {

View File

@ -140,6 +140,8 @@ class App
* @brief App constructor. * @brief App constructor.
* *
* @param string $basepath Path to the app base folder * @param string $basepath Path to the app base folder
*
* @throws Exception if the Basepath is not usable
*/ */
public function __construct($basepath) public function __construct($basepath)
{ {

View File

@ -4,6 +4,7 @@ namespace Friendica\Core\Console;
use Asika\SimpleConsole\Console; use Asika\SimpleConsole\Console;
use Friendica\App; use Friendica\App;
use Friendica\BaseObject;
use Friendica\Core\Config; use Friendica\Core\Config;
use Friendica\Core\Install; use Friendica\Core\Install;
use Friendica\Core\Theme; use Friendica\Core\Theme;
@ -20,19 +21,51 @@ class AutomaticInstallation extends Console
return <<<HELP return <<<HELP
Installation - Install Friendica automatically Installation - Install Friendica automatically
Synopsis Synopsis
bin/console autoinstall [-h|--help|-?] [-v] [-a] bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
Description Description
Installs Friendica with data based on the htconfig.php file Installs Friendica with data based on the local.ini.php file or environment variables
Notes: Notes
Not checking .htaccess/URL-Rewrite during CLI installation. Not checking .htaccess/URL-Rewrite during CLI installation.
Options Options
-h|--help|-? Show help information -h|--help|-? Show help information
-v Show more debug information. -v Show more debug information.
-a All setup checks are required (except .htaccess) -a All setup checks are required (except .htaccess)
-f prepared config file (e.g. ".htconfig.php" itself) -f|--file <config> prepared config file (e.g. "config/local.ini.php" itself) which will override every other config option - except the environment variables)
-s|--savedb Save the DB credentials to the file (if environment variables is used)
-h|--dbhost <host> The host of the mysql database (env MYSQL_HOST)
-p|--dbport <port> The port of the mysql database (env MYSQL_PORT)
-d|--dbdata <database> The name of the mysql database (env MYSQL_DATABASE)
-U|--dbuser <username> The username of the mysql database login (env MYSQL_USER or MYSQL_USERNAME)
-P|--dbpass <password> The password of the mysql database login (env MYSQL_PASSWORD)
-b|--phppath <path> The path of the PHP binary (env FRIENDICA_PHP_PATH)
-A|--admin <mail> The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL)
-T|--tz <timezone> The timezone of Friendica (env FRIENDICA_TZ)
-L|--lang <language> The language of Friendica (env FRIENDICA_LANG)
Environment variables
MYSQL_HOST The host of the mysql database (mandatory if mysql and environment is used)
MYSQL_PORT The port of the mysql database
MYSQL_USERNAME|MYSQL_USER The username of the mysql database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
MYSQL_PASSWORD The password of the mysql database login
MYSQL_DATABASE The name of the mysql database
FRIENDICA_PHP_PATH The path of the PHP binary
FRIENDICA_ADMIN_MAIL The admin email address of Friendica
FRIENDICA_TZ The timezone of Friendica
FRIENDICA_LANG The langauge of Friendica
Examples
bin/console autoinstall -f 'input.ini.php
Installs Friendica with the prepared 'input.ini.php' file
bin/console autoinstall --savedb
Installs Friendica with environment variables and saves them to the 'config/local.ini.php' file
bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
Installs Friendica with a local mysql database with credentials
HELP; HELP;
} }
@ -41,18 +74,59 @@ HELP;
// Initialise the app // Initialise the app
$this->out("Initializing setup...\n"); $this->out("Initializing setup...\n");
$a = get_app(); // if a config file is set,
$db_host = ''; $config_file = $this->getOption(['f', 'file']);
$db_user = '';
$db_pass = '';
$db_data = '';
$config_file = $this->getOption('f', 'htconfig.php'); if (!empty($config_file)) {
if ($config_file != 'config/local.ini.php') {
// Copy config file
$this->out("Copying config file...\n");
if (!copy($config_file, 'config/local.ini.php')) {
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to 'config/local.ini.php' manually.\n");
}
}
$this->out("Using config $config_file...\n"); // load the app after copying the file
require_once $config_file; $a = BaseObject::getApp();
Install::setInstallMode(); $db_host = $a->getConfigValue('database', 'hostname');
$db_user = $a->getConfigValue('database', 'username');
$db_pass = $a->getConfigValue('database', 'password');
$db_data = $a->getConfigValue('database', 'database');
} else {
// Creating config file
$this->out("Creating config file...\n");
// load the app first (for the template engine)
$a = BaseObject::getApp();
$save_db = $this->getOption(['s', 'savedb'], false);
$db_host = $this->getOption(['h', 'dbhost'], ($save_db) ? getenv('MYSQL_HOST') : '');
$db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null);
$db_data = $this->getOption(['d', 'dbdata'], ($save_db) ? getenv('MYSQL_DATABASE') : '');
$db_user = $this->getOption(['U', 'dbuser'], ($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : '');
$db_pass = $this->getOption(['P', 'dbpass'], ($save_db) ? getenv('MYSQL_PASSWORD') : '');
$php_path = $this->getOption(['b', 'phppath'], (!empty('FRIENDICA_PHP_PATH')) ? getenv('FRIENDICA_PHP_PATH') : '');
$admin_mail = $this->getOption(['A', 'admin'], (!empty('FRIENDICA_ADMIN_MAIL')) ? getenv('FRIENDICA_ADMIN_MAIL') : '');
$tz = $this->getOption(['T', 'tz'], (!empty('FRIENDICA_TZ')) ? getenv('FRIENDICA_TZ') : '');
$lang = $this->getOption(['L', 'lang'], (!empty('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : '');
// creating config file
$this->out("Creating config file...\n");
Install::createConfig(
$php_path,
$db_host,
$db_user,
$db_pass,
$db_data,
$php_path,
$tz,
$lang,
$admin_mail
);
}
$this->out(" Complete!\n\n"); $this->out(" Complete!\n\n");
@ -99,15 +173,9 @@ HELP;
Theme::install(Config::get('system', 'theme')); Theme::install(Config::get('system', 'theme'));
$this->out(" Complete\n\n"); $this->out(" Complete\n\n");
} else { } else {
$this->out(" Theme setting is empty. Please check the file htconfig.php\n\n"); $this->out(" Theme setting is empty. Please check the file 'config/local.ini.php'\n\n");
} }
// Copy config file
$this->out("Saving config file...\n");
if ($config_file != '.htconfig.php' && !copy($config_file, '.htconfig.php')) {
throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '.htconfig.php' manually.\n");
}
$this->out(" Complete!\n\n");
$this->out("\nInstallation is finished\n"); $this->out("\nInstallation is finished\n");
return 0; return 0;

View File

@ -1,427 +1,409 @@
<?php <?php
/** /**
* @file src/Core/Install.php * @file src/Core/Install.php
*/ */
namespace Friendica\Core; namespace Friendica\Core;
use Friendica\BaseObject; use DOMDocument;
use Friendica\App; use Exception;
use Friendica\Database\DBStructure; use Friendica\BaseObject;
use Friendica\Object\Image; use Friendica\Database\DBStructure;
use Friendica\Util\Network; use Friendica\Object\Image;
use Friendica\Util\Network;
use Exception;
use DOMDocument; /**
* Contains methods for installation purpose of Friendica
/** */
* Contains methods for installation purpose of Friendica class Install extends BaseObject
*/ {
class Install extends BaseObject /**
{ * Checks the current installation environment. There are optional and mandatory checks.
/** *
* Sets the install-mode for further methods * @param string $phpath Optional path to the PHP binary (Default is 'php')
*/ *
public static function setInstallMode() * @return array First element is a list of all checks and their results,
{ * the second element is a list of passed checks
self::getApp()->mode = App::MODE_INSTALL; */
} public static function check($phpath = 'php')
{
/** $checks = [];
* Checks the current installation environment. There are optional and mandatory checks.
* self::checkFunctions($checks);
* @param string $phpath Optional path to the PHP binary (Default is 'php')
* self::checkImagick($checks);
* @return array First element is a list of all checks and their results,
* the second element is a list of passed checks self::checkLocalIni($checks);
*/
public static function check($phpath = 'php') self::checkSmarty3($checks);
{
$checks = []; self::checkKeys($checks);
self::checkFunctions($checks); self::checkPHP($phpath, $checks);
self::checkImagick($checks); self::checkHtAccess($checks);
self::checkLocalIni($checks); $checkspassed = array_reduce($checks,
function ($v, $c) {
self::checkSmarty3($checks); if (!empty($c['require'])) {
$v = $v && $c['status'];
self::checkKeys($checks); }
return $v;
self::checkPHP($phpath, $checks); },
true);
self::checkHtAccess($checks);
return array($checks, $checkspassed);
$checkspassed = array_reduce($checks, }
function ($v, $c) {
if (!empty($c['require'])) { /**
$v = $v && $c['status']; * Executes the installation of Friendica in the given environment.
} * - Creates `config/local.ini.php`
return $v; * - Installs Database Structure
}, *
true); * @param string $urlpath Path based on the URL of Friendica (e.g. '/friendica')
* @param string $dbhost Hostname/IP of the Friendica Database
return array($checks, $checkspassed); * @param string $dbuser Username of the Database connection credentials
} * @param string $dbpass Password of the Database connection credentials
* @param string $dbdata Name of the Database
/** * @param string $phpath Path to the PHP-Binary (e.g. 'php' or '/usr/bin/php')
* Executes the installation of Friendica in the given environment. * @param string $timezone Timezone of the Friendica Installaton (e.g. 'Europe/Berlin')
* - Creates `config/local.ini.php` * @param string $language 2-letter ISO 639-1 code (eg. 'en')
* - Installs Database Structure * @param string $adminmail Mail-Adress of the administrator
* */
* @param string $urlpath Path based on the URL of Friendica (e.g. '/friendica') public static function createConfig($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail)
* @param string $dbhost Hostname/IP of the Friendica Database {
* @param string $dbuser Username of the Database connection credentials $tpl = get_markup_template('local.ini.tpl');
* @param string $dbpass Password of the Database connection credentials $txt = replace_macros($tpl,[
* @param string $dbdata Name of the Database '$dbhost' => $dbhost,
* @param string $phpath Path to the PHP-Binary (e.g. 'php' or '/usr/bin/php') '$dbuser' => $dbuser,
* @param string $timezone Timezone of the Friendica Installaton (e.g. 'Europe/Berlin') '$dbpass' => $dbpass,
* @param string $language 2-letter ISO 639-1 code (eg. 'en') '$dbdata' => $dbdata,
* @param string $adminmail Mail-Adress of the administrator '$timezone' => $timezone,
* @param int $rino Rino-enabled (1 = true, 0 = false) '$language' => $language,
*/ '$urlpath' => $urlpath,
public static function install($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail) '$phpath' => $phpath,
{ '$adminmail' => $adminmail,
$tpl = get_markup_template('local.ini.tpl'); ]);
$txt = replace_macros($tpl,[
'$dbhost' => $dbhost, $result = file_put_contents('config/local.ini.php', $txt);
'$dbuser' => $dbuser, if (!$result) {
'$dbpass' => $dbpass, self::getApp()->data['txt'] = $txt;
'$dbdata' => $dbdata, }
'$timezone' => $timezone,
'$language' => $language, }
'$urlpath' => $urlpath,
'$phpath' => $phpath, /**
'$adminmail' => $adminmail, * Adds new checks to the array $checks
]); *
* @param array $checks The list of all checks (by-ref parameter!)
$result = file_put_contents('config/local.ini.php', $txt); * @param string $title The title of the current check
if (! $result) { * @param bool $status 1 = check passed, 0 = check not passed
self::getApp()->data['txt'] = $txt; * @param bool $required 1 = check is mandatory, 0 = check is optional
} * @param string $help A help-string for the current check
* @param string $error_msg Optional. A error message, if the current check failed
$errors = self::installDatabaseStructure(); */
private static function addCheck(&$checks, $title, $status, $required, $help, $error_msg = "")
if ($errors) { {
self::getApp()->data['db_failed'] = $errors; $checks[] = [
} else { 'title' => $title,
self::getApp()->data['db_installed'] = true; 'status' => $status,
} 'required' => $required,
} 'help' => $help,
'error_msg' => $error_msg,
/** ];
* Adds new checks to the array $checks }
*
* @param array $checks The list of all checks (by-ref parameter!) /**
* @param string $title The title of the current check * PHP Check
* @param bool $status 1 = check passed, 0 = check not passed *
* @param bool $required 1 = check is mandatory, 0 = check is optional * Checks the PHP environment.
* @param string $help A help-string for the current check *
* @param string $error_msg Optional. A error message, if the current check failed * - Checks if a PHP binary is available
*/ * - Checks if it is the CLI version
private static function addCheck(&$checks, $title, $status, $required, $help, $error_msg = "") * - Checks if "register_argc_argv" is enabled
{ *
$checks[] = [ * @param string $phpath Optional. The Path to the PHP-Binary
'title' => $title, * @param array $checks The list of all checks (by-ref parameter!)
'status' => $status, */
'required' => $required, public static function checkPHP($phpath, &$checks)
'help' => $help, {
'error_msg' => $error_msg, $passed = $passed2 = $passed3 = false;
]; if (strlen($phpath)) {
} $passed = file_exists($phpath);
} else {
/** $phpath = trim(shell_exec('which php'));
* PHP Check $passed = strlen($phpath);
* }
* Checks the PHP environment. $help = "";
* if (!$passed) {
* - Checks if a PHP binary is available $help .= L10n::t('Could not find a command line version of PHP in the web server PATH.') . EOL;
* - Checks if it is the CLI version $help .= L10n::t("If you don't have a command line version of PHP installed on your server, you will not be able to run the background processing. See <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-worker'>'Setup the worker'</a>") . EOL;
* - Checks if "register_argc_argv" is enabled $help .= EOL . EOL;
* $tpl = get_markup_template('field_input.tpl');
* @param string $phpath Optional. The Path to the PHP-Binary $help .= replace_macros($tpl, [
* @param array $checks The list of all checks (by-ref parameter!) '$field' => ['phpath', L10n::t('PHP executable path'), $phpath, L10n::t('Enter full path to php executable. You can leave this blank to continue the installation.')],
*/ ]);
public static function checkPHP(&$phpath, &$checks) $phpath = "";
{ }
$passed = $passed2 = $passed3 = false;
if (strlen($phpath)) { self::addCheck($checks, L10n::t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
$passed = file_exists($phpath);
} else { if ($passed) {
$phpath = trim(shell_exec('which php')); $cmd = "$phpath -v";
$passed = strlen($phpath); $result = trim(shell_exec($cmd));
} $passed2 = (strpos($result, "(cli)") !== false);
$help = ""; list($result) = explode("\n", $result);
if (!$passed) { $help = "";
$help .= L10n::t('Could not find a command line version of PHP in the web server PATH.') . EOL; if (!$passed2) {
$help .= L10n::t("If you don't have a command line version of PHP installed on your server, you will not be able to run the background processing. See <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-worker'>'Setup the worker'</a>") . EOL; $help .= L10n::t("PHP executable is not the php cli binary \x28could be cgi-fgci version\x29") . EOL;
$help .= EOL . EOL; $help .= L10n::t('Found PHP version: ') . "<tt>$result</tt>";
$tpl = get_markup_template('field_input.tpl'); }
$help .= replace_macros($tpl, [ self::addCheck($checks, L10n::t('PHP cli binary'), $passed2, true, $help);
'$field' => ['phpath', L10n::t('PHP executable path'), $phpath, L10n::t('Enter full path to php executable. You can leave this blank to continue the installation.')], }
]);
$phpath = ""; if ($passed2) {
} $str = autoname(8);
$cmd = "$phpath testargs.php $str";
self::addCheck($checks, L10n::t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help); $result = trim(shell_exec($cmd));
$passed3 = $result == $str;
if ($passed) { $help = "";
$cmd = "$phpath -v"; if (!$passed3) {
$result = trim(shell_exec($cmd)); $help .= L10n::t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . EOL;
$passed2 = (strpos($result, "(cli)") !== false); $help .= L10n::t('This is required for message delivery to work.');
list($result) = explode("\n", $result); }
$help = ""; self::addCheck($checks, L10n::t('PHP register_argc_argv'), $passed3, true, $help);
if (!$passed2) { }
$help .= L10n::t("PHP executable is not the php cli binary \x28could be cgi-fgci version\x29") . EOL; }
$help .= L10n::t('Found PHP version: ') . "<tt>$result</tt>";
} /**
self::addCheck($checks, L10n::t('PHP cli binary'), $passed2, true, $help); * OpenSSL Check
} *
* Checks the OpenSSL Environment
if ($passed2) { *
$str = autoname(8); * - Checks, if the command "openssl_pkey_new" is available
$cmd = "$phpath testargs.php $str"; *
$result = trim(shell_exec($cmd)); * @param array $checks The list of all checks (by-ref parameter!)
$passed3 = $result == $str; */
$help = ""; public static function checkKeys(&$checks)
if (!$passed3) { {
$help .= L10n::t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . EOL; $help = '';
$help .= L10n::t('This is required for message delivery to work.'); $res = false;
}
self::addCheck($checks, L10n::t('PHP register_argc_argv'), $passed3, true, $help); if (function_exists('openssl_pkey_new')) {
} $res = openssl_pkey_new([
} 'digest_alg' => 'sha1',
'private_key_bits' => 4096,
/** 'encrypt_key' => false
* OpenSSL Check ]);
* }
* Checks the OpenSSL Environment
* // Get private key
* - Checks, if the command "openssl_pkey_new" is available if (!$res) {
* $help .= L10n::t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys') . EOL;
* @param array $checks The list of all checks (by-ref parameter!) $help .= L10n::t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".');
*/ }
public static function checkKeys(&$checks) self::addCheck($checks, L10n::t('Generate encryption keys'), $res, true, $help);
{ }
$help = '';
$res = false; /**
* PHP functions Check
if (function_exists('openssl_pkey_new')) { *
$res = openssl_pkey_new([ * Checks the following PHP functions
'digest_alg' => 'sha1', * - libCurl
'private_key_bits' => 4096, * - GD Graphics
'encrypt_key' => false * - OpenSSL
]); * - PDO or MySQLi
} * - mb_string
* - XML
// Get private key * - iconv
if (!$res) { * - POSIX
$help .= L10n::t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys') . EOL; *
$help .= L10n::t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".'); * @param array $checks The list of all checks (by-ref parameter!)
} */
self::addCheck($checks, L10n::t('Generate encryption keys'), $res, true, $help); public static function checkFunctions(&$checks)
} {
$ck_funcs = [];
/** self::addCheck($ck_funcs, L10n::t('libCurl PHP module'), true, true, "");
* PHP functions Check self::addCheck($ck_funcs, L10n::t('GD graphics PHP module'), true, true, "");
* self::addCheck($ck_funcs, L10n::t('OpenSSL PHP module'), true, true, "");
* Checks the following PHP functions self::addCheck($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, "");
* - libCurl self::addCheck($ck_funcs, L10n::t('mb_string PHP module'), true, true, "");
* - GD Graphics self::addCheck($ck_funcs, L10n::t('XML PHP module'), true, true, "");
* - OpenSSL self::addCheck($ck_funcs, L10n::t('iconv PHP module'), true, true, "");
* - PDO or MySQLi self::addCheck($ck_funcs, L10n::t('POSIX PHP module'), true, true, "");
* - mb_string
* - XML if (function_exists('apache_get_modules')) {
* - iconv if (! in_array('mod_rewrite',apache_get_modules())) {
* - POSIX self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), false, true, L10n::t('Error: Apache webserver mod-rewrite module is required but not installed.'));
* } else {
* @param array $checks The list of all checks (by-ref parameter!) self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), true, true, "");
*/ }
public static function checkFunctions(&$checks) }
{
$ck_funcs = []; if (!function_exists('curl_init')) {
self::addCheck($ck_funcs, L10n::t('libCurl PHP module'), true, true, ""); $ck_funcs[0]['status'] = false;
self::addCheck($ck_funcs, L10n::t('GD graphics PHP module'), true, true, ""); $ck_funcs[0]['help'] = L10n::t('Error: libCURL PHP module required but not installed.');
self::addCheck($ck_funcs, L10n::t('OpenSSL PHP module'), true, true, ""); }
self::addCheck($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, ""); if (!function_exists('imagecreatefromjpeg')) {
self::addCheck($ck_funcs, L10n::t('mb_string PHP module'), true, true, ""); $ck_funcs[1]['status'] = false;
self::addCheck($ck_funcs, L10n::t('XML PHP module'), true, true, ""); $ck_funcs[1]['help'] = L10n::t('Error: GD graphics PHP module with JPEG support required but not installed.');
self::addCheck($ck_funcs, L10n::t('iconv PHP module'), true, true, ""); }
self::addCheck($ck_funcs, L10n::t('POSIX PHP module'), true, true, ""); if (!function_exists('openssl_public_encrypt')) {
$ck_funcs[2]['status'] = false;
if (function_exists('apache_get_modules')) { $ck_funcs[2]['help'] = L10n::t('Error: openssl PHP module required but not installed.');
if (! in_array('mod_rewrite',apache_get_modules())) { }
self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), false, true, L10n::t('Error: Apache webserver mod-rewrite module is required but not installed.')); if (!function_exists('mysqli_connect') && !class_exists('pdo')) {
} else { $ck_funcs[3]['status'] = false;
self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), true, true, ""); $ck_funcs[3]['help'] = L10n::t('Error: PDO or MySQLi PHP module required but not installed.');
} }
} if (!function_exists('mysqli_connect') && class_exists('pdo') && !in_array('mysql', \PDO::getAvailableDrivers())) {
$ck_funcs[3]['status'] = false;
if (!function_exists('curl_init')) { $ck_funcs[3]['help'] = L10n::t('Error: The MySQL driver for PDO is not installed.');
$ck_funcs[0]['status'] = false; }
$ck_funcs[0]['help'] = L10n::t('Error: libCURL PHP module required but not installed.'); if (!function_exists('mb_strlen')) {
} $ck_funcs[4]['status'] = false;
if (!function_exists('imagecreatefromjpeg')) { $ck_funcs[4]['help'] = L10n::t('Error: mb_string PHP module required but not installed.');
$ck_funcs[1]['status'] = false; }
$ck_funcs[1]['help'] = L10n::t('Error: GD graphics PHP module with JPEG support required but not installed.'); if (!function_exists('iconv_strlen')) {
} $ck_funcs[6]['status'] = false;
if (!function_exists('openssl_public_encrypt')) { $ck_funcs[6]['help'] = L10n::t('Error: iconv PHP module required but not installed.');
$ck_funcs[2]['status'] = false; }
$ck_funcs[2]['help'] = L10n::t('Error: openssl PHP module required but not installed.'); if (!function_exists('posix_kill')) {
} $ck_funcs[7]['status'] = false;
if (!function_exists('mysqli_connect') && !class_exists('pdo')) { $ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.');
$ck_funcs[3]['status'] = false; }
$ck_funcs[3]['help'] = L10n::t('Error: PDO or MySQLi PHP module required but not installed.');
} $checks = array_merge($checks, $ck_funcs);
if (!function_exists('mysqli_connect') && class_exists('pdo') && !in_array('mysql', \PDO::getAvailableDrivers())) {
$ck_funcs[3]['status'] = false; // check for XML DOM Documents being able to be generated
$ck_funcs[3]['help'] = L10n::t('Error: The MySQL driver for PDO is not installed.'); try {
} $xml = new DOMDocument();
if (!function_exists('mb_strlen')) { } catch (Exception $e) {
$ck_funcs[4]['status'] = false; $ck_funcs[5]['status'] = false;
$ck_funcs[4]['help'] = L10n::t('Error: mb_string PHP module required but not installed.'); $ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.');
} }
if (!function_exists('iconv_strlen')) { }
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = L10n::t('Error: iconv PHP module required but not installed.'); /**
} * "config/local.ini.php" - Check
if (!function_exists('posix_kill')) { *
$ck_funcs[7]['status'] = false; * Checks if it's possible to create the "config/local.ini.php"
$ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.'); *
} * @param array $checks The list of all checks (by-ref parameter!)
*/
$checks = array_merge($checks, $ck_funcs); public static function checkLocalIni(&$checks)
{
// check for XML DOM Documents being able to be generated $status = true;
try { $help = "";
$xml = new DOMDocument(); if ((file_exists('config/local.ini.php') && !is_writable('config/local.ini.php')) ||
} catch (Exception $e) { (!file_exists('config/local.ini.php') && !is_writable('.'))) {
$ck_funcs[5]['status'] = false;
$ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.'); $status = false;
} $help = L10n::t('The web installer needs to be able to create a file called "local.ini.php" in the "config" folder of your web server and it is unable to do so.') . EOL;
} $help .= L10n::t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.') . EOL;
$help .= L10n::t('At the end of this procedure, we will give you a text to save in a file named local.ini.php in your Friendica "config" folder.') . EOL;
/** $help .= L10n::t('You can alternatively skip this procedure and perform a manual installation. Please see the file "INSTALL.txt" for instructions.') . EOL;
* "config/local.ini.php" - Check }
*
* Checks if it's possible to create the "config/local.ini.php" self::addCheck($checks, L10n::t('config/local.ini.php is writable'), $status, false, $help);
*
* @param array $checks The list of all checks (by-ref parameter!) }
*/
public static function checkLocalIni(&$checks) /**
{ * Smarty3 Template Check
$status = true; *
$help = ""; * Checks, if the directory of Smarty3 is writable
if ((file_exists('config/local.ini.php') && !is_writable('config/local.ini.php')) || *
(!file_exists('config/local.ini.php') && !is_writable('.'))) { * @param array $checks The list of all checks (by-ref parameter!)
*/
$status = false; public static function checkSmarty3(&$checks)
$help = L10n::t('The web installer needs to be able to create a file called "local.ini.php" in the "config" folder of your web server and it is unable to do so.') . EOL; {
$help .= L10n::t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.') . EOL; $status = true;
$help .= L10n::t('At the end of this procedure, we will give you a text to save in a file named local.ini.php in your Friendica "config" folder.') . EOL; $help = "";
$help .= L10n::t('You can alternatively skip this procedure and perform a manual installation. Please see the file "INSTALL.txt" for instructions.') . EOL; if (!is_writable('view/smarty3')) {
}
$status = false;
self::addCheck($checks, L10n::t('config/local.ini.php is writable'), $status, false, $help); $help = L10n::t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') . EOL;
$help .= L10n::t('In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.') . EOL;
} $help .= L10n::t("Please ensure that the user that your web server runs as \x28e.g. www-data\x29 has write access to this folder.") . EOL;
$help .= L10n::t("Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files \x28.tpl\x29 that it contains.") . EOL;
/** }
* Smarty3 Template Check
* self::addCheck($checks, L10n::t('view/smarty3 is writable'), $status, true, $help);
* Checks, if the directory of Smarty3 is writable }
*
* @param array $checks The list of all checks (by-ref parameter!) /**
*/ * ".htaccess" - Check
public static function checkSmarty3(&$checks) *
{ * Checks, if "url_rewrite" is enabled in the ".htaccess" file
$status = true; *
$help = ""; * @param array $checks The list of all checks (by-ref parameter!)
if (!is_writable('view/smarty3')) { */
public static function checkHtAccess(&$checks)
$status = false; {
$help = L10n::t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') . EOL; $status = true;
$help .= L10n::t('In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.') . EOL; $help = "";
$help .= L10n::t("Please ensure that the user that your web server runs as \x28e.g. www-data\x29 has write access to this folder.") . EOL; $error_msg = "";
$help .= L10n::t("Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files \x28.tpl\x29 that it contains.") . EOL; if (function_exists('curl_init')) {
} $test = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite");
self::addCheck($checks, L10n::t('view/smarty3 is writable'), $status, true, $help); $url = normalise_link(System::baseUrl() . "/install/testrewrite");
} if ($test['body'] != "ok") {
$test = Network::fetchUrlFull($url);
/** }
* ".htaccess" - Check
* if ($test['body'] != "ok") {
* Checks, if "url_rewrite" is enabled in the ".htaccess" file $status = false;
* $help = L10n::t('Url rewrite in .htaccess is not working. Check your server configuration.');
* @param array $checks The list of all checks (by-ref parameter!) $error_msg = [];
*/ $error_msg['head'] = L10n::t('Error message from Curl when fetching');
public static function checkHtAccess(&$checks) $error_msg['url'] = $test['redirect_url'];
{ $error_msg['msg'] = defaults($test, 'error', '');
$status = true; }
$help = ""; self::addCheck($checks, L10n::t('Url rewrite is working'), $status, true, $help, $error_msg);
$error_msg = ""; } else {
if (function_exists('curl_init')) { // cannot check modrewrite if libcurl is not installed
$test = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite"); /// @TODO Maybe issue warning here?
}
$url = normalise_link(System::baseUrl() . "/install/testrewrite"); }
if ($test['body'] != "ok") {
$test = Network::fetchUrlFull($url); /**
} * Imagick Check
*
if ($test['body'] != "ok") { * Checks, if the imagick module is available
$status = false; *
$help = L10n::t('Url rewrite in .htaccess is not working. Check your server configuration.'); * @param array $checks The list of all checks (by-ref parameter!)
$error_msg = []; */
$error_msg['head'] = L10n::t('Error message from Curl when fetching'); public static function checkImagick(&$checks)
$error_msg['url'] = $test['redirect_url']; {
$error_msg['msg'] = defaults($test, 'error', ''); $imagick = false;
} $gif = false;
self::addCheck($checks, L10n::t('Url rewrite is working'), $status, true, $help, $error_msg);
} else { if (class_exists('Imagick')) {
// cannot check modrewrite if libcurl is not installed $imagick = true;
/// @TODO Maybe issue warning here? $supported = Image::supportedTypes();
} if (array_key_exists('image/gif', $supported)) {
} $gif = true;
}
/** }
* Imagick Check if ($imagick == false) {
* self::addCheck($checks, L10n::t('ImageMagick PHP extension is not installed'), $imagick, false, "");
* Checks, if the imagick module is available } else {
* self::addCheck($checks, L10n::t('ImageMagick PHP extension is installed'), $imagick, false, "");
* @param array $checks The list of all checks (by-ref parameter!) if ($imagick) {
*/ self::addCheck($checks, L10n::t('ImageMagick supports GIF'), $gif, false, "");
public static function checkImagick(&$checks) }
{ }
$imagick = false; }
$gif = false;
/**
if (class_exists('Imagick')) { * Installs the Database structure
$imagick = true; *
$supported = Image::supportedTypes(); * @return string A possible error
if (array_key_exists('image/gif', $supported)) { */
$gif = true; public static function installDatabaseStructure()
} {
} $errors = DBStructure::update(false, true, true);
if ($imagick == false) {
self::addCheck($checks, L10n::t('ImageMagick PHP extension is not installed'), $imagick, false, ""); return $errors;
} else { }
self::addCheck($checks, L10n::t('ImageMagick PHP extension is installed'), $imagick, false, ""); }
if ($imagick) {
self::addCheck($checks, L10n::t('ImageMagick supports GIF'), $gif, false, "");
}
}
}
/**
* Installs the Database structure
*
* @return string A possible error
*/
public static function installDatabaseStructure()
{
$errors = DBStructure::update(false, true, true);
return $errors;
}
}

View File

@ -344,6 +344,10 @@ class NotificationsManager extends BaseObject
break; break;
case ACTIVITY_FRIEND: case ACTIVITY_FRIEND:
if (!isset($it['object'])) {
logger('Incomplete data: ' . json_encode($it) . ' - ' . System::callstack(20), LOGGER_DEBUG);
}
$xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">"; $xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
$obj = XML::parseString($xmlhead . $it['object']); $obj = XML::parseString($xmlhead . $it['object']);
$it['fname'] = $obj->title; $it['fname'] = $obj->title;

View File

@ -65,7 +65,7 @@ class System extends BaseObject
while ($func = array_pop($trace)) { while ($func = array_pop($trace)) {
if (!empty($func['class'])) { if (!empty($func['class'])) {
// Don't show multiple calls from the "dba" class to show the essential parts of the callstack // Don't show multiple calls from the "dba" class to show the essential parts of the callstack
if ((($previous['class'] != $func['class']) || ($func['class'] != 'dba')) && ($previous['function'] != 'q')) { if ((($previous['class'] != $func['class']) || ($func['class'] != 'Friendica\Database\DBA')) && ($previous['function'] != 'q')) {
$classparts = explode("\\", $func['class']); $classparts = explode("\\", $func['class']);
$callstack[] = array_pop($classparts).'::'.$func['function']; $callstack[] = array_pop($classparts).'::'.$func['function'];
$previous = $func; $previous = $func;

View File

@ -372,7 +372,7 @@ class DBA
* @usage Example: $r = p("SELECT * FROM `item` WHERE `guid` = ?", $guid); * @usage Example: $r = p("SELECT * FROM `item` WHERE `guid` = ?", $guid);
* *
* Please only use it with complicated queries. * Please only use it with complicated queries.
* For all regular queries please use dba::select or dba::exists * For all regular queries please use DBA::select or DBA::exists
* *
* @param string $sql SQL statement * @param string $sql SQL statement
* @return bool|object statement object or result object * @return bool|object statement object or result object
@ -590,7 +590,7 @@ class DBA
/** /**
* @brief Executes a prepared statement like UPDATE or INSERT that doesn't return data * @brief Executes a prepared statement like UPDATE or INSERT that doesn't return data
* *
* Please use dba::delete, dba::insert, dba::update, ... instead * Please use DBA::delete, DBA::insert, DBA::update, ... instead
* *
* @param string $sql SQL statement * @param string $sql SQL statement
* @return boolean Was the query successfull? False is returned only if an error occurred * @return boolean Was the query successfull? False is returned only if an error occurred
@ -685,7 +685,7 @@ class DBA
/** /**
* Fetches the first row * Fetches the first row
* *
* Please use dba::selectFirst or dba::exists whenever this is possible. * Please use DBA::selectFirst or DBA::exists whenever this is possible.
* *
* @brief Fetches the first row * @brief Fetches the first row
* @param string $sql SQL statement * @param string $sql SQL statement
@ -1303,7 +1303,7 @@ class DBA
* *
* $params = array("order" => array("id", "received" => true), "limit" => 10); * $params = array("order" => array("id", "received" => true), "limit" => 10);
* *
* $data = dba::select($table, $fields, $condition, $params); * $data = DBA::select($table, $fields, $condition, $params);
*/ */
public static function select($table, array $fields = [], array $condition = [], array $params = []) public static function select($table, array $fields = [], array $condition = [], array $params = [])
{ {
@ -1345,7 +1345,7 @@ class DBA
* or: * or:
* $condition = ["`uid` = ? AND `network` IN (?, ?)", 1, 'dfrn', 'dspr']; * $condition = ["`uid` = ? AND `network` IN (?, ?)", 1, 'dfrn', 'dspr'];
* *
* $count = dba::count($table, $condition); * $count = DBA::count($table, $condition);
*/ */
public static function count($table, array $condition = []) public static function count($table, array $condition = [])
{ {
@ -1399,7 +1399,7 @@ class DBA
/* Workaround for MySQL Bug #64791. /* Workaround for MySQL Bug #64791.
* Never mix data types inside any IN() condition. * Never mix data types inside any IN() condition.
* In case of mixed types, cast all as string. * In case of mixed types, cast all as string.
* Logic needs to be consistent with dba::p() data types. * Logic needs to be consistent with DBA::p() data types.
*/ */
$is_int = false; $is_int = false;
$is_alpha = false; $is_alpha = false;
@ -1459,7 +1459,7 @@ class DBA
$limit_string = ''; $limit_string = '';
if (isset($params['limit']) && is_int($params['limit'])) { if (isset($params['limit']) && is_int($params['limit'])) {
$limit_string = " LIMIT " . $params['limit']; $limit_string = " LIMIT " . intval($params['limit']);
} }
if (isset($params['limit']) && is_array($params['limit'])) { if (isset($params['limit']) && is_array($params['limit'])) {
@ -1530,7 +1530,7 @@ class DBA
case 'mysqli': case 'mysqli':
// MySQLi offers both a mysqli_stmt and a mysqli_result class. // MySQLi offers both a mysqli_stmt and a mysqli_result class.
// We should be careful not to assume the object type of $stmt // We should be careful not to assume the object type of $stmt
// because dba::p() has been able to return both types. // because DBA::p() has been able to return both types.
if ($stmt instanceof mysqli_stmt) { if ($stmt instanceof mysqli_stmt) {
$stmt->free_result(); $stmt->free_result();
$ret = $stmt->close(); $ret = $stmt->close();

View File

@ -364,8 +364,13 @@ class Contact extends BaseObject
*/ */
public static function markForArchival(array $contact) public static function markForArchival(array $contact)
{ {
if (!isset($contact['url']) && !empty($contact['id'])) {
if (!isset($contact['url'])) { $fields = ['id', 'url', 'archive', 'self', 'term-date'];
$contact = DBA::selectFirst('contact', [], ['id' => $contact['id']]);
if (!DBA::isResult($contact)) {
return;
}
} elseif (!isset($contact['url'])) {
logger('Empty contact: ' . json_encode($contact) . ' - ' . System::callstack(20), LOGGER_DEBUG); logger('Empty contact: ' . json_encode($contact) . ' - ' . System::callstack(20), LOGGER_DEBUG);
} }
@ -376,10 +381,7 @@ class Contact extends BaseObject
if ($contact['term-date'] <= NULL_DATE) { if ($contact['term-date'] <= NULL_DATE) {
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]); DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE]);
if ($contact['url'] != '') {
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE]);
}
} else { } else {
/* @todo /* @todo
* We really should send a notification to the owner after 2-3 weeks * We really should send a notification to the owner after 2-3 weeks
@ -397,10 +399,7 @@ class Contact extends BaseObject
* the whole process over again. * the whole process over again.
*/ */
DBA::update('contact', ['archive' => 1], ['id' => $contact['id']]); DBA::update('contact', ['archive' => 1], ['id' => $contact['id']]);
DBA::update('contact', ['archive' => 1], ['nurl' => normalise_link($contact['url']), 'self' => false]);
if ($contact['url'] != '') {
DBA::update('contact', ['archive' => 1], ['nurl' => normalise_link($contact['url']), 'self' => false]);
}
} }
} }
} }
@ -423,13 +422,18 @@ class Contact extends BaseObject
return; return;
} }
if (!isset($contact['url']) && !empty($contact['id'])) {
$fields = ['id', 'url', 'batch'];
$contact = DBA::selectFirst('contact', [], ['id' => $contact['id']]);
if (!DBA::isResult($contact)) {
return;
}
}
// It's a miracle. Our dead contact has inexplicably come back to life. // It's a miracle. Our dead contact has inexplicably come back to life.
$fields = ['term-date' => NULL_DATE, 'archive' => false]; $fields = ['term-date' => NULL_DATE, 'archive' => false];
DBA::update('contact', $fields, ['id' => $contact['id']]); DBA::update('contact', $fields, ['id' => $contact['id']]);
DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]);
if (!empty($contact['url'])) {
DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]);
}
if (!empty($contact['batch'])) { if (!empty($contact['batch'])) {
$condition = ['batch' => $contact['batch'], 'contact-type' => self::ACCOUNT_TYPE_RELAY]; $condition = ['batch' => $contact['batch'], 'contact-type' => self::ACCOUNT_TYPE_RELAY];

View File

@ -273,36 +273,25 @@ class Group extends BaseObject
* *
* @param array $group_ids * @param array $group_ids
* @param boolean $check_dead * @param boolean $check_dead
* @param boolean $use_gcontact
* @return array * @return array
*/ */
public static function expand($group_ids, $check_dead = false, $use_gcontact = false) public static function expand($group_ids, $check_dead = false)
{ {
if (!is_array($group_ids) || !count($group_ids)) { if (!is_array($group_ids) || !count($group_ids)) {
return []; return [];
} }
$condition = '`gid` IN (' . substr(str_repeat("?, ", count($group_ids)), 0, -2) . ')'; $stmt = DBA::select('group_member', ['contact-id'], ['gid' => $group_ids]);
if ($use_gcontact) {
$sql = 'SELECT `gcontact`.`id` AS `contact-id` FROM `group_member`
INNER JOIN `contact` ON `contact`.`id` = `group_member`.`contact-id`
INNER JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
WHERE ' . $condition;
$param_arr = array_merge([$sql], $group_ids);
$stmt = call_user_func_array('dba::p', $param_arr);
} else {
$condition_array = array_merge([$condition], $group_ids);
$stmt = DBA::select('group_member', ['contact-id'], $condition_array);
}
$return = []; $return = [];
while($group_member = DBA::fetch($stmt)) { while($group_member = DBA::fetch($stmt)) {
$return[] = $group_member['contact-id']; $return[] = $group_member['contact-id'];
} }
if ($check_dead && !$use_gcontact) { if ($check_dead) {
Contact::pruneUnavailable($return); Contact::pruneUnavailable($return);
} }
return $return; return $return;
} }

View File

@ -933,7 +933,12 @@ class Probe
} }
$prof_data = []; $prof_data = [];
$prof_data["addr"] = $data["addr"];
// The "addr" is not always part of the fetched data
if (!empty($data["addr"])) {
$prof_data["addr"] = $data["addr"];
}
$prof_data["nick"] = $data["nick"]; $prof_data["nick"] = $data["nick"];
$prof_data["dfrn-request"] = $data["request"]; $prof_data["dfrn-request"] = $data["request"];
$prof_data["dfrn-confirm"] = $data["confirm"]; $prof_data["dfrn-confirm"] = $data["confirm"];

View File

@ -1050,7 +1050,7 @@ class Diaspora
return false; return false;
} }
$contact = dba::selectFirst('contact', [], ['id' => $cid]); $contact = DBA::selectFirst('contact', [], ['id' => $cid]);
if (!DBA::isResult($contact)) { if (!DBA::isResult($contact)) {
// This here shouldn't happen at all // This here shouldn't happen at all
logger("Haven't found a contact for user " . $uid . " and handle " . $handle, LOGGER_DEBUG); logger("Haven't found a contact for user " . $uid . " and handle " . $handle, LOGGER_DEBUG);
@ -1079,7 +1079,7 @@ class Diaspora
// It is deactivated by now, due to side effects. See issue https://github.com/friendica/friendica/pull/4033 // It is deactivated by now, due to side effects. See issue https://github.com/friendica/friendica/pull/4033
// It is not removed by now. Possibly the code is needed? // It is not removed by now. Possibly the code is needed?
//if (!$is_comment && $contact["rel"] == Contact::FOLLOWER && in_array($importer["page-flags"], array(Contact::PAGE_FREELOVE))) { //if (!$is_comment && $contact["rel"] == Contact::FOLLOWER && in_array($importer["page-flags"], array(Contact::PAGE_FREELOVE))) {
// dba::update( // DBA::update(
// 'contact', // 'contact',
// array('rel' => Contact::FRIEND, 'writable' => true), // array('rel' => Contact::FRIEND, 'writable' => true),
// array('id' => $contact["id"], 'uid' => $contact["uid"]) // array('id' => $contact["id"], 'uid' => $contact["uid"])
@ -1821,10 +1821,10 @@ class Diaspora
"to_name" => $importer["username"], "to_name" => $importer["username"],
"to_email" => $importer["email"], "to_email" => $importer["email"],
"uid" =>$importer["uid"], "uid" =>$importer["uid"],
"item" => ["subject" => $subject, "body" => $body], "item" => ["id" => $conversation["id"], "title" => $subject, "subject" => $subject, "body" => $body],
"source_name" => $person["name"], "source_name" => $person["name"],
"source_link" => $person["url"], "source_link" => $person["url"],
"source_photo" => $person["thumb"], "source_photo" => $person["photo"],
"verb" => ACTIVITY_POST, "verb" => ACTIVITY_POST,
"otype" => "mail"] "otype" => "mail"]
); );
@ -3075,7 +3075,7 @@ class Diaspora
logger("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code); logger("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code);
if (!$return_code || (($return_code == 503) && (stristr($a->get_curl_headers(), "retry-after")))) { if (!$return_code || (($return_code == 503) && (stristr($a->get_curl_headers(), "retry-after")))) {
if (!$no_queue && ($contact['contact-type'] != Contact::ACCOUNT_TYPE_RELAY)) { if (!$no_queue && !empty($contact['contact-type']) && ($contact['contact-type'] != Contact::ACCOUNT_TYPE_RELAY)) {
logger("queue message"); logger("queue message");
// queue message for redelivery // queue message for redelivery
Queue::add($contact["id"], Protocol::DIASPORA, $envelope, $public_batch, $guid); Queue::add($contact["id"], Protocol::DIASPORA, $envelope, $public_batch, $guid);

View File

@ -716,7 +716,7 @@ class Network
$url = self::stripTrackingQueryParams($url); $url = self::stripTrackingQueryParams($url);
if ($depth > 10) { if ($depth > 10) {
return($url); return $url;
} }
$url = trim($url, "'"); $url = trim($url, "'");
@ -739,16 +739,14 @@ class Network
$a->save_timestamp($stamp1, "network"); $a->save_timestamp($stamp1, "network");
if ($http_code == 0) { if ($http_code == 0) {
return($url); return $url;
} }
if ((($curl_info['http_code'] == "301") || ($curl_info['http_code'] == "302")) if (in_array($http_code, ['301', '302'])) {
&& (($curl_info['redirect_url'] != "") || ($curl_info['location'] != "")) if (!empty($curl_info['redirect_url'])) {
) { return self::finalUrl($curl_info['redirect_url'], ++$depth, $fetchbody);
if ($curl_info['redirect_url'] != "") { } elseif (!empty($curl_info['location'])) {
return(self::finalUrl($curl_info['redirect_url'], ++$depth, $fetchbody)); return self::finalUrl($curl_info['location'], ++$depth, $fetchbody);
} else {
return(self::finalUrl($curl_info['location'], ++$depth, $fetchbody));
} }
} }
@ -759,12 +757,12 @@ class Network
// if the file is too large then exit // if the file is too large then exit
if ($curl_info["download_content_length"] > 1000000) { if ($curl_info["download_content_length"] > 1000000) {
return($url); return $url;
} }
// if it isn't a HTML file then exit // if it isn't a HTML file then exit
if (($curl_info["content_type"] != "") && !strstr(strtolower($curl_info["content_type"]), "html")) { if (!empty($curl_info["content_type"]) && !strstr(strtolower($curl_info["content_type"]), "html")) {
return($url); return $url;
} }
$stamp1 = microtime(true); $stamp1 = microtime(true);
@ -783,7 +781,7 @@ class Network
$a->save_timestamp($stamp1, "network"); $a->save_timestamp($stamp1, "network");
if (trim($body) == "") { if (trim($body) == "") {
return($url); return $url;
} }
// Check for redirect in meta elements // Check for redirect in meta elements
@ -806,7 +804,7 @@ class Network
$pathinfo = explode(";", $path); $pathinfo = explode(";", $path);
foreach ($pathinfo as $value) { foreach ($pathinfo as $value) {
if (substr(strtolower($value), 0, 4) == "url=") { if (substr(strtolower($value), 0, 4) == "url=") {
return(self::finalUrl(substr($value, 4), ++$depth)); return self::finalUrl(substr($value, 4), ++$depth);
} }
} }
} }

View File

@ -84,7 +84,7 @@ class DBClean {
$r = DBA::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND $r = DBA::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND
NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND
`received` < UTC_TIMESTAMP() - INTERVAL ? DAY AND `id` >= ? `received` < UTC_TIMESTAMP() - INTERVAL ? DAY AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $days_unclaimed, $last_id); ORDER BY `id` LIMIT ?", $days_unclaimed, $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found global item orphans: ".$count); logger("found global item orphans: ".$count);
@ -106,7 +106,7 @@ class DBClean {
logger("Deleting items without parents. Last ID: ".$last_id); logger("Deleting items without parents. Last ID: ".$last_id);
$r = DBA::p("SELECT `id` FROM `item` $r = DBA::p("SELECT `id` FROM `item`
WHERE NOT EXISTS (SELECT `id` FROM `item` AS `i` WHERE `item`.`parent` = `i`.`id`) WHERE NOT EXISTS (SELECT `id` FROM `item` AS `i` WHERE `item`.`parent` = `i`.`id`)
AND `id` >= ? ORDER BY `id` LIMIT ".intval($limit), $last_id); AND `id` >= ? ORDER BY `id` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found item orphans without parents: ".$count); logger("found item orphans without parents: ".$count);
@ -132,7 +132,7 @@ class DBClean {
logger("Deleting orphaned data from thread table. Last ID: ".$last_id); logger("Deleting orphaned data from thread table. Last ID: ".$last_id);
$r = DBA::p("SELECT `iid` FROM `thread` $r = DBA::p("SELECT `iid` FROM `thread`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `thread`.`iid`) AND `iid` >= ? WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `thread`.`iid`) AND `iid` >= ?
ORDER BY `iid` LIMIT ".intval($limit), $last_id); ORDER BY `iid` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found thread orphans: ".$count); logger("found thread orphans: ".$count);
@ -158,7 +158,7 @@ class DBClean {
logger("Deleting orphaned data from notify table. Last ID: ".$last_id); logger("Deleting orphaned data from notify table. Last ID: ".$last_id);
$r = DBA::p("SELECT `iid`, `id` FROM `notify` $r = DBA::p("SELECT `iid`, `id` FROM `notify`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `notify`.`iid`) AND `id` >= ? WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `notify`.`iid`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id); ORDER BY `id` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found notify orphans: ".$count); logger("found notify orphans: ".$count);
@ -184,7 +184,7 @@ class DBClean {
logger("Deleting orphaned data from notify-threads table. Last ID: ".$last_id); logger("Deleting orphaned data from notify-threads table. Last ID: ".$last_id);
$r = DBA::p("SELECT `id` FROM `notify-threads` $r = DBA::p("SELECT `id` FROM `notify-threads`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `notify-threads`.`master-parent-item`) AND `id` >= ? WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `notify-threads`.`master-parent-item`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id); ORDER BY `id` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found notify-threads orphans: ".$count); logger("found notify-threads orphans: ".$count);
@ -210,7 +210,7 @@ class DBClean {
logger("Deleting orphaned data from sign table. Last ID: ".$last_id); logger("Deleting orphaned data from sign table. Last ID: ".$last_id);
$r = DBA::p("SELECT `iid`, `id` FROM `sign` $r = DBA::p("SELECT `iid`, `id` FROM `sign`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `sign`.`iid`) AND `id` >= ? WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `sign`.`iid`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id); ORDER BY `id` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found sign orphans: ".$count); logger("found sign orphans: ".$count);
@ -236,7 +236,7 @@ class DBClean {
logger("Deleting orphaned data from term table. Last ID: ".$last_id); logger("Deleting orphaned data from term table. Last ID: ".$last_id);
$r = DBA::p("SELECT `oid`, `tid` FROM `term` $r = DBA::p("SELECT `oid`, `tid` FROM `term`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `term`.`oid`) AND `tid` >= ? WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `term`.`oid`) AND `tid` >= ?
ORDER BY `tid` LIMIT ".intval($limit), $last_id); ORDER BY `tid` LIMIT ?", $last_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found term orphans: ".$count); logger("found term orphans: ".$count);
@ -303,7 +303,7 @@ class DBClean {
$r = DBA::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND $r = DBA::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND
NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND
`received` < UTC_TIMESTAMP() - INTERVAL 90 DAY AND `id` >= ? AND `id` <= ? `received` < UTC_TIMESTAMP() - INTERVAL 90 DAY AND `id` >= ? AND `id` <= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id, $till_id); ORDER BY `id` LIMIT ?", $last_id, $till_id, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found global item entries from expired threads: ".$count); logger("found global item entries from expired threads: ".$count);
@ -326,7 +326,7 @@ class DBClean {
logger("Deleting old conversations. Last created: ".$last_id); logger("Deleting old conversations. Last created: ".$last_id);
$r = DBA::p("SELECT `received`, `item-uri` FROM `conversation` $r = DBA::p("SELECT `received`, `item-uri` FROM `conversation`
WHERE `received` < UTC_TIMESTAMP() - INTERVAL ? DAY WHERE `received` < UTC_TIMESTAMP() - INTERVAL ? DAY
ORDER BY `received` LIMIT ".intval($limit), $days); ORDER BY `received` LIMIT ?", $days, $limit);
$count = DBA::numRows($r); $count = DBA::numRows($r);
if ($count > 0) { if ($count > 0) {
logger("found old conversations: ".$count); logger("found old conversations: ".$count);

View File

@ -216,7 +216,7 @@ class DiscoverPoCo
$x = Network::fetchUrl(get_server()."/lsearch?p=1&n=500&search=".urlencode($search)); $x = Network::fetchUrl(get_server()."/lsearch?p=1&n=500&search=".urlencode($search));
$j = json_decode($x); $j = json_decode($x);
if (count($j->results)) { if (!empty($j->results)) {
foreach ($j->results as $jj) { foreach ($j->results as $jj) {
// Check if the contact already exists // Check if the contact already exists
$exists = q("SELECT `id`, `last_contact`, `last_failure`, `updated` FROM `gcontact` WHERE `nurl` = '%s'", normalise_link($jj->url)); $exists = q("SELECT `id`, `last_contact`, `last_failure`, `updated` FROM `gcontact` WHERE `nurl` = '%s'", normalise_link($jj->url));

View File

@ -380,7 +380,8 @@
'cursor' : 'pointer' 'cursor' : 'pointer'
}); });
var div = document.createElement("div"); var div = document.createElement("div");
div.setAttribute('class', 'ajaxbutton-wrapper');
addStyles(div, { addStyles(div, {
'display' : 'block', 'display' : 'block',
'position' : 'absolute', 'position' : 'absolute',

View File

@ -439,8 +439,10 @@
<input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" /> <input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
<input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" /> <input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" />
<input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" /> <input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" />
<input type="hidden" name="marital" id="profile-edit-marital" value="{{$marital.2}}" />
<input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" /> <input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" />
<input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" /> <input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" />
<input type="hidden" name="sexual" id="profile-edit-sexual" value="{{$sexual.2}}" />
<input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" /> <input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" />
<input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" /> <input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" />
<input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" /> <input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />

View File

@ -15,14 +15,14 @@ function theme_post(App $a)
} }
if (isset($_POST['frio-settings-submit'])) { if (isset($_POST['frio-settings-submit'])) {
PConfig::set(local_user(), 'frio', 'scheme', defaults($_POST, 'frio_scheme')); PConfig::set(local_user(), 'frio', 'scheme', defaults($_POST, 'frio_scheme', ''));
PConfig::set(local_user(), 'frio', 'nav_bg', defaults($_POST, 'frio_nav_bg')); PConfig::set(local_user(), 'frio', 'nav_bg', defaults($_POST, 'frio_nav_bg', ''));
PConfig::set(local_user(), 'frio', 'nav_icon_color', defaults($_POST, 'frio_nav_icon_color')); PConfig::set(local_user(), 'frio', 'nav_icon_color', defaults($_POST, 'frio_nav_icon_color', ''));
PConfig::set(local_user(), 'frio', 'link_color', defaults($_POST, 'frio_link_color')); PConfig::set(local_user(), 'frio', 'link_color', defaults($_POST, 'frio_link_color', ''));
PConfig::set(local_user(), 'frio', 'background_color', defaults($_POST, 'frio_background_color')); PConfig::set(local_user(), 'frio', 'background_color', defaults($_POST, 'frio_background_color', ''));
PConfig::set(local_user(), 'frio', 'contentbg_transp', defaults($_POST, 'frio_contentbg_transp')); PConfig::set(local_user(), 'frio', 'contentbg_transp', defaults($_POST, 'frio_contentbg_transp', ''));
PConfig::set(local_user(), 'frio', 'background_image', defaults($_POST, 'frio_background_image')); PConfig::set(local_user(), 'frio', 'background_image', defaults($_POST, 'frio_background_image', ''));
PConfig::set(local_user(), 'frio', 'bg_image_option', defaults($_POST, 'frio_bg_image_option')); PConfig::set(local_user(), 'frio', 'bg_image_option', defaults($_POST, 'frio_bg_image_option', ''));
PConfig::set(local_user(), 'frio', 'css_modified', time()); PConfig::set(local_user(), 'frio', 'css_modified', time());
} }
} }

View File

@ -958,6 +958,10 @@ nav.navbar a, nav.navbar .btn-link {
color: #fff!important; color: #fff!important;
background-color: $menu_background_hover_color !important; background-color: $menu_background_hover_color !important;
} }
#photo-edit-link-wrap {
color: #555;
margin-bottom: 15px;
}
.nav-pills.preferences .dropdown .dropdown-toggle, .nav-pills.preferences .dropdown .dropdown-toggle,
.nav-pills.preferences > li > .btn { .nav-pills.preferences > li > .btn {
color: #bebebe; color: #bebebe;
@ -1418,6 +1422,15 @@ section #jotOpen {
color: #fff; color: #fff;
} }
.fa.lock:before {
font-family: FontAwesome;
content: "\f023";
}
.fa.unlock:before {
font-family: FontAwesome;
content: "\f09c";
}
/* Filebrowser */ /* Filebrowser */
.fbrowser .breadcrumb { .fbrowser .breadcrumb {
margin-bottom: 0px; margin-bottom: 0px;

View File

@ -12,7 +12,7 @@ $(document).ready(function(){
// with AjaxUpload. // with AjaxUpload.
$(".fbrowser").remove(); $(".fbrowser").remove();
// Remove the AjaxUpload element. // Remove the AjaxUpload element.
$("[name=userfile]").parent().remove(); $(".ajaxbutton-wrapper").remove();
}); });
// Clear bs modal on close. // Clear bs modal on close.

View File

@ -44,7 +44,7 @@ if (!isset($minimal)) {
$uid = Profile::getThemeUid(); $uid = Profile::getThemeUid();
} }
$scheme = PConfig::get($uid, 'frio', 'scheme', PConfig::get($uid, 'frio', 'schema')); $scheme = PConfig::get($uid, 'frio', 'scheme', PConfig::get($uid, 'frio', 'schema'));
if (($scheme) && ($scheme != '---')) { if ($scheme && ($scheme != '---')) {
if (file_exists('view/theme/frio/scheme/' . $scheme . '.php')) { if (file_exists('view/theme/frio/scheme/' . $scheme . '.php')) {
$schemefile = 'view/theme/frio/scheme/' . $scheme . '.php'; $schemefile = 'view/theme/frio/scheme/' . $scheme . '.php';
require_once $schemefile; require_once $schemefile;
@ -52,7 +52,7 @@ if (!isset($minimal)) {
} else { } else {
$nav_bg = PConfig::get($uid, 'frio', 'nav_bg'); $nav_bg = PConfig::get($uid, 'frio', 'nav_bg');
} }
if (!$nav_bg) { if (empty($nav_bg)) {
$nav_bg = "#708fa0"; $nav_bg = "#708fa0";
} }
echo ' echo '

View File

@ -1,8 +1,13 @@
<div class="wall-item-actions" id="wall-item-like-buttons-{{$id}}"> <div class="wall-item-actions" id="wall-item-like-buttons-{{$id}}">
<button type="button" class="btn-link button-likes" id="like-{{$id}}" title="{{$likethis}}" onclick="dolike({{$id}},'like'); return false;" data-toggle="button"><i class="fa fa-thumbs-up" aria-hidden="true"></i>&nbsp;</button> <button type="button" class="btn-link button-likes" id="like-{{$id}}" title="{{$likethis}}" onclick="dolike({{$id}},'like'); return false;" data-toggle="button">
<i class="faded-icon page-action fa fa-thumbs-up" aria-hidden="true"></i>
</button>
{{if $nolike}} {{if $nolike}}
<button type="button" class="btn-link button-likes" id="dislike-{{$id}}" title="{{$nolike}}" onclick="dolike({{$id}},'dislike'); return false;" data-toggle="button"><i class="fa fa-thumbs-down" aria-hidden="true"></i>&nbsp;</button> <span class="icon-padding"> </span>
<button type="button" class="btn-link button-likes" id="dislike-{{$id}}" title="{{$nolike}}" onclick="dolike({{$id}},'dislike'); return false;" data-toggle="button">
<i class="faded-icon page-action fa fa-thumbs-down" aria-hidden="true"></i>
</button>
{{/if}} {{/if}}
<img id="like-rotator-{{$id}}" class="like-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait}}" style="display: none;" /> <img id="like-rotator-{{$id}}" class="like-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait}}" style="display: none;" />
</div> </div>

View File

@ -4,16 +4,30 @@
<div id="live-photos"></div> <div id="live-photos"></div>
<div id="photo-view-{{$id}}" class="generic-page-wrapper"> <div id="photo-view-{{$id}}" class="generic-page-wrapper">
<h3><a href="{{$album.0}}">{{$album.1}}</a></h3> <div class="pull-left" id="photo-edit-link-wrap">
<a class="page-action faded-icon" id="photo-album-link" href="{{$album.0}}" title="{{$album.1}}" data-toggle="tooltip">
<div id="photo-edit-link-wrap"> <i class="fa fa-folder-open"></i>&nbsp;{{$album.1}}
{{if $tools}} </a>
<a id="photo-edit-link" href="{{$tools.edit.0}}">{{$tools.edit.1}}</a>
|
<a id="photo-toprofile-link" href="{{$tools.profile.0}}">{{$tools.profile.1}}</a>
{{/if}}
{{if $lock}} | <img src="images/lock_icon.gif" class="lockview" alt="{{$lock}}" onclick="lockview(event,'photo/{{$id}}');" /> {{/if}}
</div> </div>
<div class="pull-right" id="photo-edit-link-wrap">
{{if $tools}}
<span class="icon-padding"> </span>
<a id="photo-edit-link" href="{{$tools.edit.0}}" title="{{$tools.edit.1}}" data-toggle="tooltip">
<i class="page-action faded-icon fa fa-pencil"></i>
</a>
<span class="icon-padding"> </span>
<a id="photo-toprofile-link" href="{{$tools.profile.0}}" title="{{$tools.profile.1}}" data-toggle="tooltip">
<i class="page-action faded-icon fa fa-user"></i>
</a>
{{/if}}
{{if $lock}}
<span class="icon-padding"> </span>
<a id="photo-lock-link" onclick="lockview(event,'photo/{{$id}}');" title="{{$lock}}" data-toggle="tooltip">
<i class="page-action faded-icon fa fa-lock"></i>
</a>
{{/if}}
</div>
<div class="clear"></div>
<div id="photo-view-wrapper"> <div id="photo-view-wrapper">
<div id="photo-photo"> <div id="photo-photo">

View File

@ -0,0 +1 @@
<input id="photos-upload-choose" type="file" name="userfile" />

View File

@ -0,0 +1,2 @@
<button id="photos-upload-submit" class="btn btn-primary">{{$submit|escape:'html'}}</button>

View File

@ -5,49 +5,68 @@
<div id="photos-usage-message">{{$usage}}</div> <div id="photos-usage-message">{{$usage}}</div>
<form action="photos/{{$nickname}}" enctype="multipart/form-data" method="post" name="photos-upload-form" id="photos-upload-form"> <form action="photos/{{$nickname}}" enctype="multipart/form-data" method="post" name="photos-upload-form" id="photos-upload-form">
<div id="photos-upload-new-wrapper" > <div id="photos-upload-div" class="form-group">
<div id="photos-upload-newalbum-div"> <label id="photos-upload-text" for="photos-upload-newalbum" >{{$newalbum}}</label>
<label id="photos-upload-newalbum-text" for="photos-upload-newalbum" >{{$newalbum}}</label>
</div>
<input class="form-control" id="photos-upload-newalbum" type="text" name="newalbum" />
</div>
<div id="photos-upload-new-end"></div>
<div id="photos-upload-exist-wrapper"> <input id="photos-upload-album-select" class="form-control" placeholder="{{$existalbumtext}}" list="dl-photo-upload" type="text" name="album" size="4">
<div id="photos-upload-existing-album-div"> <datalist id="dl-photo-upload">{{$albumselect}}</datalist>
<label id="photos-upload-existing-album-text" for="photos-upload-album-select">{{$existalbumtext}}</label>
</div>
<select class="form-control" id="photos-upload-album-select" name="album" size="4">
{{$albumselect}}
</select>
</div> </div>
<div id="photos-upload-exist-end"></div> <div id="photos-upload-end" class="clearfix"></div>
<div id="photos-upload-noshare-div" class="photos-upload-noshare-div pull-left" > <div id="photos-upload-noshare-div" class="photos-upload-noshare-div checkbox pull-left" >
<input id="photos-upload-noshare" type="checkbox" name="not_visible" value="1" checked/> <input id="photos-upload-noshare" type="checkbox" name="not_visible" value="1" checked/>
<label id="photos-upload-noshare-text" for="photos-upload-noshare" >{{$nosharetext}}</label> <label id="photos-upload-noshare-text" for="photos-upload-noshare" >{{$nosharetext}}</label>
</div> </div>
<div id="photos-upload-perms" class="photos-upload-perms pull-right" > {{if $alt_uploader}}
<a href="#photos-upload-permissions-wrapper" id="photos-upload-perms-menu" class="button popupbox" /> <div id="photos-upload-perms" class="pull-right">
<span id="jot-perms-icon" class="icon {{$lockstate}}" ></span>{{$permissions}} <button class="btn btn-default btn-sm" data-toggle="modal" data-target="#aclModal" onclick="return false;">
</a> <i id="jot-perms-icon" class="fa {{$lockstate}}"></i> {{$permissions}}
</div> </button>
<div id="photos-upload-perms-end" class="clear"></div> </div>
<div class="clearfix"></div>
<div style="display: none;"> <div id="photos-upload-spacer"></div>
<div id="photos-upload-permissions-wrapper">
{{$aclselect}} {{$alt_uploader}}
{{/if}}
{{if $default_upload_submit}}
<div class="clearfix"></div>
<div id="photos-upload-spacer"></div>
<div class="photos-upload-wrapper">
<div id="photos-upload-perms" class="btn-group pull-right">
<button class="btn btn-default" data-toggle="modal" data-target="#aclModal" onclick="return false;">
<i id="jot-perms-icon" class="fa {{$lockstate}}"></i>
</button>
{{$default_upload_submit}}
</div>
{{$default_upload_box}}
</div>
<div class="clearfix"></div>
{{/if}}
<div class="photos-upload-end" class="clearfix"></div>
{{* The modal for advanced-expire *}}
<div id="aclModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" class="modal-header">
<button id="modal-close" type="button" class="close" data-dismiss="modal" aria-hidden="true">
&times;
</button>
<h4 id="modal-title" class="modal-title">{{$permissions}}</h4>
</div>
<div id="photos-upload-permissions-wrapper" class="modal-body">
{{$aclselect}}
</div>
</div>
</div> </div>
</div> </div>
<div id="photos-upload-spacer"></div>
{{$alt_uploader}}
{{$default_upload_box}}
{{$default_upload_submit}}
<div class="photos-upload-end" ></div>
</form> </form>
</div> </div>

View File

@ -434,8 +434,10 @@
<input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" /> <input type="hidden" name="religion" id="profile-edit-religion" value="{{$religion.2}}" />
<input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" /> <input type="hidden" id="likes-jot-text" name="likes" value="{{$likes.2}}" />
<input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" /> <input type="hidden" id="dislikes-jot-text" name="dislikes" value="{{$dislikes.2}}" />
<input type="hidden" name="marital" id="profile-edit-marital" value="{{$marital.2}}" />
<input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" /> <input type="hidden" name="with" id="profile-edit-with" value="{{$with.2}}" />
<input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" /> <input type="hidden" name="howlong" id="profile-edit-howlong" value="{{$howlong.2}}" />
<input type="hidden" name="sexual" id="profile-edit-sexual" value="{{$sexual.2}}" />
<input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" /> <input type="hidden" id="romance-jot-text" name="romance" value="{{$romance.2}}" />
<input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" /> <input type="hidden" id="work-jot-text" name="work" value="{{$work.2}}" />
<input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" /> <input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />