Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
9b5bef6dea
67
doc/api.md
67
doc/api.md
|
@ -634,6 +634,73 @@ Friendica doesn't allow showing the friends of other users.
|
|||
* trim_user
|
||||
* 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 (*)
|
||||
|
|
|
@ -2888,6 +2888,7 @@ function api_format_items($r, $user_info, $filter_user = false, $type = "json")
|
|||
'favorited' => $item['starred'] ? true : false,
|
||||
'user' => $status_user ,
|
||||
'friendica_owner' => $owner_user,
|
||||
'friendica_private' => $item['private'] == 1,
|
||||
//'entities' => NULL,
|
||||
'statusnet_html' => $converted["html"],
|
||||
'statusnet_conversation_id' => $item['parent'],
|
||||
|
|
|
@ -471,6 +471,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
. "'; var profile_page = " . $a->pager['page'] . "; </script>\r\n";
|
||||
}
|
||||
} elseif ($mode === 'profile') {
|
||||
$items = conversation_add_children($items, false, $order, $uid);
|
||||
$profile_owner = $a->profile['profile_uid'];
|
||||
|
||||
if (!$update) {
|
||||
|
@ -490,6 +491,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
}
|
||||
}
|
||||
} elseif ($mode === 'notes') {
|
||||
$items = conversation_add_children($items, false, $order, $uid);
|
||||
$profile_owner = local_user();
|
||||
|
||||
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";
|
||||
}
|
||||
} elseif ($mode === 'display') {
|
||||
$items = conversation_add_children($items, false, $order, $uid);
|
||||
$profile_owner = $a->profile['uid'];
|
||||
|
||||
if (!$update) {
|
||||
|
|
|
@ -5,9 +5,9 @@ use Friendica\Database\DBA;
|
|||
/**
|
||||
* @brief execute SQL query with printf style args - deprecated
|
||||
*
|
||||
* Please use the dba:: functions instead:
|
||||
* dba::select, dba::exists, dba::insert
|
||||
* dba::delete, dba::update, dba::p, dba::e
|
||||
* Please use the DBA:: functions instead:
|
||||
* DBA::select, DBA::exists, DBA::insert
|
||||
* DBA::delete, DBA::update, DBA::p, DBA::e
|
||||
*
|
||||
* @param $args Query parameters (1 to N parameters of different types)
|
||||
* @return array|bool Query array
|
||||
|
|
|
@ -32,6 +32,20 @@ function notification($params)
|
|||
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
|
||||
L10n::pushLang($params['language']);
|
||||
|
||||
|
@ -510,7 +524,7 @@ function notification($params)
|
|||
}
|
||||
|
||||
// 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'] == SYSTEM_EMAIL) {
|
||||
|
||||
|
@ -661,7 +675,7 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
|
||||
$profiles = $notification_data["profiles"];
|
||||
|
||||
$fields = ['notify-flags', 'language', 'username', 'email', 'nickname'];
|
||||
$fields = ['nickname'];
|
||||
$user = DBA::selectFirst('user', $fields, ['uid' => $uid]);
|
||||
if (!DBA::isResult($user)) {
|
||||
return false;
|
||||
|
@ -724,10 +738,6 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
|
|||
// Generate the notification array
|
||||
$params = [];
|
||||
$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["parent"] = $item["parent"];
|
||||
$params["link"] = System::baseUrl().'/display/'.urlencode($item["guid"]);
|
||||
|
|
|
@ -371,7 +371,7 @@ function drop_item($id)
|
|||
|
||||
if ((local_user() == $item['uid']) || $contact_id) {
|
||||
// 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
|
||||
// so add any arguments as hidden inputs
|
||||
$query = explode_querystring($a->query_string);
|
||||
|
@ -395,7 +395,7 @@ function drop_item($id)
|
|||
]);
|
||||
}
|
||||
// Now check how the user responded to the confirmation query
|
||||
if ($_REQUEST['canceled']) {
|
||||
if (!empty($_REQUEST['canceled'])) {
|
||||
goaway(System::baseUrl() . '/' . $_SESSION['return_url']);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use Friendica\Core\Config;
|
|||
use Friendica\Core\L10n;
|
||||
use Friendica\Core\PConfig;
|
||||
use Friendica\Database\DBA;
|
||||
use Friendica\Model\Contact;
|
||||
|
||||
function community_init(App $a)
|
||||
{
|
||||
|
@ -35,6 +36,25 @@ function community_content(App $a, $update = 0)
|
|||
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) {
|
||||
$content = $a->argv[1];
|
||||
} else {
|
||||
|
@ -135,7 +155,7 @@ function community_content(App $a, $update = 0)
|
|||
|
||||
$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)) {
|
||||
info(L10n::t('No results.') . EOL);
|
||||
|
@ -164,7 +184,7 @@ function community_content(App $a, $update = 0)
|
|||
}
|
||||
}
|
||||
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));
|
||||
} 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 (!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`
|
||||
INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
|
||||
INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
|
||||
WHERE `thread`.`visible` AND NOT `thread`.`deleted` AND NOT `thread`.`moderated`
|
||||
AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin`
|
||||
ORDER BY `thread`.`commented` DESC LIMIT " . intval($start) . ", " . intval($itemspage)
|
||||
);
|
||||
AND NOT `thread`.`private` AND `thread`.`wall` AND `thread`.`origin` $sql_accounttype
|
||||
ORDER BY `thread`.`commented` DESC LIMIT ?, ?", $values);
|
||||
return DBA::toArray($r);
|
||||
} 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`
|
||||
INNER JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
INNER JOIN `contact` AS `author` ON `author`.`id`=`item`.`author-id`
|
||||
WHERE `thread`.`uid` = 0 AND NOT `author`.`hidden` AND NOT `author`.`blocked`
|
||||
ORDER BY `thread`.`commented` DESC LIMIT " . intval($start) . ", " . intval($itemspage));
|
||||
INNER JOIN `contact` AS `owner` ON `owner`.`id`=`item`.`owner-id`
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ function dfrn_notify_post(App $a) {
|
|||
|
||||
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
|
||||
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');
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ function dfrn_notify_content(App $a) {
|
|||
|
||||
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
|
||||
if (!DBA::isResult($user)) {
|
||||
logger('User not found for nickname ' . $$a->argv[1]);
|
||||
logger('User not found for nickname ' . $a->argv[1]);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,12 @@ function dfrn_poll_content(App $a)
|
|||
}
|
||||
|
||||
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
|
||||
if ($dfrn_version < 2.2) {
|
||||
$s = Network::fetchUrl($r[0]['poll']
|
||||
|
|
|
@ -333,35 +333,34 @@ function display_content(App $a, $update = false, $update_uid = 0)
|
|||
return '';
|
||||
}
|
||||
|
||||
$condition = ["`item`.`parent-uri` = (SELECT `parent-uri` FROM `item` WHERE `id` = ?)
|
||||
AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, local_user()];
|
||||
$params = ['order' => ['uid', 'parent' => true, 'gravity', 'id']];
|
||||
$items_obj = Item::selectForUser(local_user(), [], $condition, $params);
|
||||
$condition = ["`id` = ? AND `item`.`uid` IN (0, ?) " . $sql_extra, $item_id, local_user()];
|
||||
$fields = ['parent-uri', 'body', 'title', 'author-name', 'author-avatar', 'plink'];
|
||||
$item = Item::selectFirstForUser(local_user(), $fields, $condition);
|
||||
|
||||
if (!DBA::isResult($items_obj)) {
|
||||
if (!DBA::isResult($item)) {
|
||||
notice(L10n::t('Item not found.') . EOL);
|
||||
return $o;
|
||||
}
|
||||
|
||||
$item['uri'] = $item['parent-uri'];
|
||||
|
||||
if ($unseen) {
|
||||
$condition = ['parent-uri' => $item_parent_uri, 'uid' => local_user(), 'unseen' => true];
|
||||
Item::update(['unseen' => false], $condition);
|
||||
}
|
||||
|
||||
$items = Item::inArray($items_obj);
|
||||
$conversation_items = conv_sort($items, "`commented`");
|
||||
|
||||
if (!$update) {
|
||||
$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
|
||||
$description = trim(HTML::toPlaintext(BBCode::convert($items[0]["body"], false), 0, true));
|
||||
$title = trim(HTML::toPlaintext(BBCode::convert($items[0]["title"], false), 0, true));
|
||||
$author_name = $items[0]["author-name"];
|
||||
$description = trim(HTML::toPlaintext(BBCode::convert($item["body"], false), 0, true));
|
||||
$title = trim(HTML::toPlaintext(BBCode::convert($item["title"], false), 0, true));
|
||||
$author_name = $item["author-name"];
|
||||
|
||||
$image = $a->remove_baseurl($items[0]["author-avatar"]);
|
||||
$image = $a->remove_baseurl($item["author-avatar"]);
|
||||
|
||||
if ($title == "") {
|
||||
$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:description" content="'.$description.'" />'."\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
|
||||
$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:title" content="'.$title.'" />'."\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 name="og:article:author" content="'.$author_name.'" />'."\n";
|
||||
// article:tag
|
||||
|
|
|
@ -16,9 +16,7 @@ use Friendica\Util\Proxy as ProxyUtils;
|
|||
function follow_post(App $a)
|
||||
{
|
||||
if (!local_user()) {
|
||||
notice(L10n::t('Permission denied.'));
|
||||
goaway($_SESSION['return_url']);
|
||||
// NOTREACHED
|
||||
System::httpExit(403, ['title' => L10n::t('Access denied.')]);
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['cancel'])) {
|
||||
|
|
|
@ -72,7 +72,20 @@ function install_post(App $a) {
|
|||
// connect to db
|
||||
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;
|
||||
break;
|
||||
|
|
|
@ -65,26 +65,13 @@ function notes_content(App $a, $update = false)
|
|||
|
||||
$params = ['order' => ['created' => true],
|
||||
'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;
|
||||
|
||||
if (DBA::isResult($r)) {
|
||||
$count = count($r);
|
||||
$parents_arr = [];
|
||||
|
||||
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 .= conversation($a, DBA::toArray($r), 'notes', $update);
|
||||
}
|
||||
|
||||
$o .= alt_pager($a, $count);
|
||||
|
|
|
@ -1093,6 +1093,12 @@ function photos_content(App $a)
|
|||
'$albumselect' => $albumselect,
|
||||
'$permissions' => L10n::t('Permissions'),
|
||||
'$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'],
|
||||
'$default_upload_box' => ($ret['default_upload'] ? $default_upload_box : ''),
|
||||
'$default_upload_submit' => ($ret['default_upload'] ? $default_upload_submit : ''),
|
||||
|
|
|
@ -23,7 +23,7 @@ use Friendica\Util\DateTimeFormat;
|
|||
|
||||
function profile_init(App $a)
|
||||
{
|
||||
if (!x($a->page, 'aside')) {
|
||||
if (empty($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');
|
||||
$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" />';
|
||||
}
|
||||
|
||||
if (x($a->profile, 'openidserver')) {
|
||||
if (!empty($a->profile['openidserver'])) {
|
||||
$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'];
|
||||
$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', '');
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ function profile_content(App $a, $update = 0)
|
|||
|
||||
$contact_id = 0;
|
||||
|
||||
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) {
|
||||
if (!empty($_SESSION['remote'])) {
|
||||
foreach ($_SESSION['remote'] as $v) {
|
||||
if ($v['uid'] == $a->profile['profile_uid']) {
|
||||
$contact_id = $v['cid'];
|
||||
|
@ -171,14 +171,14 @@ function profile_content(App $a, $update = 0)
|
|||
$is_owner = local_user() == $a->profile['profile_uid'];
|
||||
$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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$update) {
|
||||
$tab = false;
|
||||
if (x($_GET, 'tab')) {
|
||||
if (!empty($_GET['tab'])) {
|
||||
$tab = notags(trim($_GET['tab']));
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ function profile_content(App $a, $update = 0)
|
|||
$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'] .= 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();
|
||||
|
||||
if (can_write_wall($a->profile['profile_uid'])) {
|
||||
|
@ -227,7 +227,7 @@ function profile_content(App $a, $update = 0)
|
|||
$sql_extra2 = '';
|
||||
|
||||
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
|
||||
// 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 . "'";
|
||||
}
|
||||
|
||||
$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`
|
||||
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
|
||||
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)
|
||||
);
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
if (!DBA::isResult($items)) {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
$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` ",
|
||||
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` ",
|
||||
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()))));
|
||||
}
|
||||
if ($datequery2) {
|
||||
if (!empty($datequery2)) {
|
||||
$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
|
||||
$r = q("SELECT `uid` FROM `user` WHERE `uid` = %d AND `page-flags` IN (%d, %d)",
|
||||
intval($a->profile['profile_uid']),
|
||||
intval(Contact::PAGE_COMMUNITY),
|
||||
intval(Contact::PAGE_PRVGROUP)
|
||||
);
|
||||
|
||||
if (!DBA::isResult($r)) {
|
||||
$condition = ['uid' => $a->profile['profile_uid'], 'page-flags' => [Contact::PAGE_COMMUNITY, Contact::PAGE_PRVGROUP]];
|
||||
if (!DBA::exists('user', $condition)) {
|
||||
$sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id'])));
|
||||
} else {
|
||||
$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']));
|
||||
|
||||
$r = q("SELECT `thread`.`iid` AS `item_id`, `thread`.`network` AS `item_network`
|
||||
$items = q("SELECT `item`.`uri`
|
||||
FROM `thread`
|
||||
STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
|
||||
$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
|
||||
// search for new items (update routine)
|
||||
$_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')) {
|
||||
$o .= Profile::getBirthdays();
|
||||
$o .= Profile::getEventsReminderHTML();
|
||||
}
|
||||
|
||||
|
||||
if ($is_owner) {
|
||||
$unseen = Item::exists(['wall' => true, 'unseen' => true, 'uid' => local_user()]);
|
||||
if ($unseen) {
|
||||
|
|
|
@ -23,7 +23,7 @@ function redir_init(App $a) {
|
|||
}
|
||||
|
||||
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()]]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
notice(L10n::t('Contact not found.'));
|
||||
|
@ -80,7 +80,7 @@ function redir_init(App $a) {
|
|||
}
|
||||
|
||||
// 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']);
|
||||
|
||||
if ($contact['duplex'] && $contact['issued-id']) {
|
||||
|
|
|
@ -140,6 +140,8 @@ class App
|
|||
* @brief App constructor.
|
||||
*
|
||||
* @param string $basepath Path to the app base folder
|
||||
*
|
||||
* @throws Exception if the Basepath is not usable
|
||||
*/
|
||||
public function __construct($basepath)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Friendica\Core\Console;
|
|||
|
||||
use Asika\SimpleConsole\Console;
|
||||
use Friendica\App;
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Core\Config;
|
||||
use Friendica\Core\Install;
|
||||
use Friendica\Core\Theme;
|
||||
|
@ -20,19 +21,51 @@ class AutomaticInstallation extends Console
|
|||
return <<<HELP
|
||||
Installation - Install Friendica automatically
|
||||
Synopsis
|
||||
bin/console autoinstall [-h|--help|-?] [-v] [-a]
|
||||
bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
|
||||
|
||||
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.
|
||||
|
||||
Options
|
||||
-h|--help|-? Show help information
|
||||
-v Show more debug information.
|
||||
-a All setup checks are required (except .htaccess)
|
||||
-f prepared config file (e.g. ".htconfig.php" itself)
|
||||
-h|--help|-? Show help information
|
||||
-v Show more debug information.
|
||||
-a All setup checks are required (except .htaccess)
|
||||
-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;
|
||||
}
|
||||
|
||||
|
@ -41,18 +74,59 @@ HELP;
|
|||
// Initialise the app
|
||||
$this->out("Initializing setup...\n");
|
||||
|
||||
$a = get_app();
|
||||
$db_host = '';
|
||||
$db_user = '';
|
||||
$db_pass = '';
|
||||
$db_data = '';
|
||||
// if a config file is set,
|
||||
$config_file = $this->getOption(['f', 'file']);
|
||||
|
||||
$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");
|
||||
require_once $config_file;
|
||||
// load the app after copying the 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");
|
||||
|
||||
|
@ -99,15 +173,9 @@ HELP;
|
|||
Theme::install(Config::get('system', 'theme'));
|
||||
$this->out(" Complete\n\n");
|
||||
} 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");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,427 +1,409 @@
|
|||
<?php
|
||||
/**
|
||||
* @file src/Core/Install.php
|
||||
*/
|
||||
namespace Friendica\Core;
|
||||
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\App;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Util\Network;
|
||||
|
||||
use Exception;
|
||||
use DOMDocument;
|
||||
|
||||
/**
|
||||
* Contains methods for installation purpose of Friendica
|
||||
*/
|
||||
class Install extends BaseObject
|
||||
{
|
||||
/**
|
||||
* Sets the install-mode for further methods
|
||||
*/
|
||||
public static function setInstallMode()
|
||||
{
|
||||
self::getApp()->mode = App::MODE_INSTALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the current installation environment. There are optional and mandatory checks.
|
||||
*
|
||||
* @param string $phpath Optional path to the PHP binary (Default is 'php')
|
||||
*
|
||||
* @return array First element is a list of all checks and their results,
|
||||
* the second element is a list of passed checks
|
||||
*/
|
||||
public static function check($phpath = 'php')
|
||||
{
|
||||
$checks = [];
|
||||
|
||||
self::checkFunctions($checks);
|
||||
|
||||
self::checkImagick($checks);
|
||||
|
||||
self::checkLocalIni($checks);
|
||||
|
||||
self::checkSmarty3($checks);
|
||||
|
||||
self::checkKeys($checks);
|
||||
|
||||
self::checkPHP($phpath, $checks);
|
||||
|
||||
self::checkHtAccess($checks);
|
||||
|
||||
$checkspassed = array_reduce($checks,
|
||||
function ($v, $c) {
|
||||
if (!empty($c['require'])) {
|
||||
$v = $v && $c['status'];
|
||||
}
|
||||
return $v;
|
||||
},
|
||||
true);
|
||||
|
||||
return array($checks, $checkspassed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the installation of Friendica in the given environment.
|
||||
* - Creates `config/local.ini.php`
|
||||
* - Installs Database Structure
|
||||
*
|
||||
* @param string $urlpath Path based on the URL of Friendica (e.g. '/friendica')
|
||||
* @param string $dbhost Hostname/IP of the Friendica Database
|
||||
* @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')
|
||||
* @param string $timezone Timezone of the Friendica Installaton (e.g. 'Europe/Berlin')
|
||||
* @param string $language 2-letter ISO 639-1 code (eg. 'en')
|
||||
* @param string $adminmail Mail-Adress of the administrator
|
||||
* @param int $rino Rino-enabled (1 = true, 0 = false)
|
||||
*/
|
||||
public static function install($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail)
|
||||
{
|
||||
$tpl = get_markup_template('local.ini.tpl');
|
||||
$txt = replace_macros($tpl,[
|
||||
'$dbhost' => $dbhost,
|
||||
'$dbuser' => $dbuser,
|
||||
'$dbpass' => $dbpass,
|
||||
'$dbdata' => $dbdata,
|
||||
'$timezone' => $timezone,
|
||||
'$language' => $language,
|
||||
'$urlpath' => $urlpath,
|
||||
'$phpath' => $phpath,
|
||||
'$adminmail' => $adminmail,
|
||||
]);
|
||||
|
||||
$result = file_put_contents('config/local.ini.php', $txt);
|
||||
if (! $result) {
|
||||
self::getApp()->data['txt'] = $txt;
|
||||
}
|
||||
|
||||
$errors = self::installDatabaseStructure();
|
||||
|
||||
if ($errors) {
|
||||
self::getApp()->data['db_failed'] = $errors;
|
||||
} else {
|
||||
self::getApp()->data['db_installed'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param bool $status 1 = check passed, 0 = check not passed
|
||||
* @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
|
||||
*/
|
||||
private static function addCheck(&$checks, $title, $status, $required, $help, $error_msg = "")
|
||||
{
|
||||
$checks[] = [
|
||||
'title' => $title,
|
||||
'status' => $status,
|
||||
'required' => $required,
|
||||
'help' => $help,
|
||||
'error_msg' => $error_msg,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP Check
|
||||
*
|
||||
* Checks the PHP environment.
|
||||
*
|
||||
* - Checks if a PHP binary is available
|
||||
* - Checks if it is the CLI version
|
||||
* - Checks if "register_argc_argv" is enabled
|
||||
*
|
||||
* @param string $phpath Optional. The Path to the PHP-Binary
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkPHP(&$phpath, &$checks)
|
||||
{
|
||||
$passed = $passed2 = $passed3 = false;
|
||||
if (strlen($phpath)) {
|
||||
$passed = file_exists($phpath);
|
||||
} else {
|
||||
$phpath = trim(shell_exec('which php'));
|
||||
$passed = strlen($phpath);
|
||||
}
|
||||
$help = "";
|
||||
if (!$passed) {
|
||||
$help .= L10n::t('Could not find a command line version of PHP in the web server PATH.') . EOL;
|
||||
$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 .= EOL . EOL;
|
||||
$tpl = get_markup_template('field_input.tpl');
|
||||
$help .= replace_macros($tpl, [
|
||||
'$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 = "";
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
|
||||
|
||||
if ($passed) {
|
||||
$cmd = "$phpath -v";
|
||||
$result = trim(shell_exec($cmd));
|
||||
$passed2 = (strpos($result, "(cli)") !== false);
|
||||
list($result) = explode("\n", $result);
|
||||
$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);
|
||||
}
|
||||
|
||||
if ($passed2) {
|
||||
$str = autoname(8);
|
||||
$cmd = "$phpath testargs.php $str";
|
||||
$result = trim(shell_exec($cmd));
|
||||
$passed3 = $result == $str;
|
||||
$help = "";
|
||||
if (!$passed3) {
|
||||
$help .= L10n::t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . EOL;
|
||||
$help .= L10n::t('This is required for message delivery to work.');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('PHP register_argc_argv'), $passed3, true, $help);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenSSL Check
|
||||
*
|
||||
* Checks the OpenSSL Environment
|
||||
*
|
||||
* - Checks, if the command "openssl_pkey_new" is available
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkKeys(&$checks)
|
||||
{
|
||||
$help = '';
|
||||
$res = false;
|
||||
|
||||
if (function_exists('openssl_pkey_new')) {
|
||||
$res = openssl_pkey_new([
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 4096,
|
||||
'encrypt_key' => false
|
||||
]);
|
||||
}
|
||||
|
||||
// Get private key
|
||||
if (!$res) {
|
||||
$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".');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('Generate encryption keys'), $res, true, $help);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP functions Check
|
||||
*
|
||||
* Checks the following PHP functions
|
||||
* - libCurl
|
||||
* - GD Graphics
|
||||
* - OpenSSL
|
||||
* - PDO or MySQLi
|
||||
* - mb_string
|
||||
* - XML
|
||||
* - iconv
|
||||
* - POSIX
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkFunctions(&$checks)
|
||||
{
|
||||
$ck_funcs = [];
|
||||
self::addCheck($ck_funcs, L10n::t('libCurl PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('GD graphics PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('OpenSSL PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('mb_string PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('XML PHP module'), true, true, "");
|
||||
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('apache_get_modules')) {
|
||||
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.'));
|
||||
} else {
|
||||
self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), true, true, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('curl_init')) {
|
||||
$ck_funcs[0]['status'] = false;
|
||||
$ck_funcs[0]['help'] = L10n::t('Error: libCURL PHP module required but not installed.');
|
||||
}
|
||||
if (!function_exists('imagecreatefromjpeg')) {
|
||||
$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('openssl_public_encrypt')) {
|
||||
$ck_funcs[2]['status'] = false;
|
||||
$ck_funcs[2]['help'] = L10n::t('Error: openssl PHP module required but not installed.');
|
||||
}
|
||||
if (!function_exists('mysqli_connect') && !class_exists('pdo')) {
|
||||
$ck_funcs[3]['status'] = false;
|
||||
$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;
|
||||
$ck_funcs[3]['help'] = L10n::t('Error: The MySQL driver for PDO is not installed.');
|
||||
}
|
||||
if (!function_exists('mb_strlen')) {
|
||||
$ck_funcs[4]['status'] = false;
|
||||
$ck_funcs[4]['help'] = L10n::t('Error: mb_string 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.');
|
||||
}
|
||||
if (!function_exists('posix_kill')) {
|
||||
$ck_funcs[7]['status'] = false;
|
||||
$ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.');
|
||||
}
|
||||
|
||||
$checks = array_merge($checks, $ck_funcs);
|
||||
|
||||
// check for XML DOM Documents being able to be generated
|
||||
try {
|
||||
$xml = new DOMDocument();
|
||||
} catch (Exception $e) {
|
||||
$ck_funcs[5]['status'] = false;
|
||||
$ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "config/local.ini.php" - Check
|
||||
*
|
||||
* Checks if it's possible to create the "config/local.ini.php"
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkLocalIni(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
if ((file_exists('config/local.ini.php') && !is_writable('config/local.ini.php')) ||
|
||||
(!file_exists('config/local.ini.php') && !is_writable('.'))) {
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('config/local.ini.php is writable'), $status, false, $help);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty3 Template Check
|
||||
*
|
||||
* Checks, if the directory of Smarty3 is writable
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkSmarty3(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
if (!is_writable('view/smarty3')) {
|
||||
|
||||
$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;
|
||||
$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;
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('view/smarty3 is writable'), $status, true, $help);
|
||||
}
|
||||
|
||||
/**
|
||||
* ".htaccess" - Check
|
||||
*
|
||||
* Checks, if "url_rewrite" is enabled in the ".htaccess" file
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkHtAccess(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
$error_msg = "";
|
||||
if (function_exists('curl_init')) {
|
||||
$test = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite");
|
||||
|
||||
$url = normalise_link(System::baseUrl() . "/install/testrewrite");
|
||||
if ($test['body'] != "ok") {
|
||||
$test = Network::fetchUrlFull($url);
|
||||
}
|
||||
|
||||
if ($test['body'] != "ok") {
|
||||
$status = false;
|
||||
$help = L10n::t('Url rewrite in .htaccess is not working. Check your server configuration.');
|
||||
$error_msg = [];
|
||||
$error_msg['head'] = L10n::t('Error message from Curl when fetching');
|
||||
$error_msg['url'] = $test['redirect_url'];
|
||||
$error_msg['msg'] = defaults($test, 'error', '');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('Url rewrite is working'), $status, true, $help, $error_msg);
|
||||
} else {
|
||||
// cannot check modrewrite if libcurl is not installed
|
||||
/// @TODO Maybe issue warning here?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imagick Check
|
||||
*
|
||||
* Checks, if the imagick module is available
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkImagick(&$checks)
|
||||
{
|
||||
$imagick = false;
|
||||
$gif = false;
|
||||
|
||||
if (class_exists('Imagick')) {
|
||||
$imagick = true;
|
||||
$supported = Image::supportedTypes();
|
||||
if (array_key_exists('image/gif', $supported)) {
|
||||
$gif = true;
|
||||
}
|
||||
}
|
||||
if ($imagick == false) {
|
||||
self::addCheck($checks, L10n::t('ImageMagick PHP extension is not installed'), $imagick, false, "");
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* @file src/Core/Install.php
|
||||
*/
|
||||
namespace Friendica\Core;
|
||||
|
||||
use DOMDocument;
|
||||
use Exception;
|
||||
use Friendica\BaseObject;
|
||||
use Friendica\Database\DBStructure;
|
||||
use Friendica\Object\Image;
|
||||
use Friendica\Util\Network;
|
||||
|
||||
/**
|
||||
* Contains methods for installation purpose of Friendica
|
||||
*/
|
||||
class Install extends BaseObject
|
||||
{
|
||||
/**
|
||||
* Checks the current installation environment. There are optional and mandatory checks.
|
||||
*
|
||||
* @param string $phpath Optional path to the PHP binary (Default is 'php')
|
||||
*
|
||||
* @return array First element is a list of all checks and their results,
|
||||
* the second element is a list of passed checks
|
||||
*/
|
||||
public static function check($phpath = 'php')
|
||||
{
|
||||
$checks = [];
|
||||
|
||||
self::checkFunctions($checks);
|
||||
|
||||
self::checkImagick($checks);
|
||||
|
||||
self::checkLocalIni($checks);
|
||||
|
||||
self::checkSmarty3($checks);
|
||||
|
||||
self::checkKeys($checks);
|
||||
|
||||
self::checkPHP($phpath, $checks);
|
||||
|
||||
self::checkHtAccess($checks);
|
||||
|
||||
$checkspassed = array_reduce($checks,
|
||||
function ($v, $c) {
|
||||
if (!empty($c['require'])) {
|
||||
$v = $v && $c['status'];
|
||||
}
|
||||
return $v;
|
||||
},
|
||||
true);
|
||||
|
||||
return array($checks, $checkspassed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the installation of Friendica in the given environment.
|
||||
* - Creates `config/local.ini.php`
|
||||
* - Installs Database Structure
|
||||
*
|
||||
* @param string $urlpath Path based on the URL of Friendica (e.g. '/friendica')
|
||||
* @param string $dbhost Hostname/IP of the Friendica Database
|
||||
* @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')
|
||||
* @param string $timezone Timezone of the Friendica Installaton (e.g. 'Europe/Berlin')
|
||||
* @param string $language 2-letter ISO 639-1 code (eg. 'en')
|
||||
* @param string $adminmail Mail-Adress of the administrator
|
||||
*/
|
||||
public static function createConfig($urlpath, $dbhost, $dbuser, $dbpass, $dbdata, $phpath, $timezone, $language, $adminmail)
|
||||
{
|
||||
$tpl = get_markup_template('local.ini.tpl');
|
||||
$txt = replace_macros($tpl,[
|
||||
'$dbhost' => $dbhost,
|
||||
'$dbuser' => $dbuser,
|
||||
'$dbpass' => $dbpass,
|
||||
'$dbdata' => $dbdata,
|
||||
'$timezone' => $timezone,
|
||||
'$language' => $language,
|
||||
'$urlpath' => $urlpath,
|
||||
'$phpath' => $phpath,
|
||||
'$adminmail' => $adminmail,
|
||||
]);
|
||||
|
||||
$result = file_put_contents('config/local.ini.php', $txt);
|
||||
if (!$result) {
|
||||
self::getApp()->data['txt'] = $txt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param bool $status 1 = check passed, 0 = check not passed
|
||||
* @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
|
||||
*/
|
||||
private static function addCheck(&$checks, $title, $status, $required, $help, $error_msg = "")
|
||||
{
|
||||
$checks[] = [
|
||||
'title' => $title,
|
||||
'status' => $status,
|
||||
'required' => $required,
|
||||
'help' => $help,
|
||||
'error_msg' => $error_msg,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP Check
|
||||
*
|
||||
* Checks the PHP environment.
|
||||
*
|
||||
* - Checks if a PHP binary is available
|
||||
* - Checks if it is the CLI version
|
||||
* - Checks if "register_argc_argv" is enabled
|
||||
*
|
||||
* @param string $phpath Optional. The Path to the PHP-Binary
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkPHP($phpath, &$checks)
|
||||
{
|
||||
$passed = $passed2 = $passed3 = false;
|
||||
if (strlen($phpath)) {
|
||||
$passed = file_exists($phpath);
|
||||
} else {
|
||||
$phpath = trim(shell_exec('which php'));
|
||||
$passed = strlen($phpath);
|
||||
}
|
||||
$help = "";
|
||||
if (!$passed) {
|
||||
$help .= L10n::t('Could not find a command line version of PHP in the web server PATH.') . EOL;
|
||||
$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 .= EOL . EOL;
|
||||
$tpl = get_markup_template('field_input.tpl');
|
||||
$help .= replace_macros($tpl, [
|
||||
'$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 = "";
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
|
||||
|
||||
if ($passed) {
|
||||
$cmd = "$phpath -v";
|
||||
$result = trim(shell_exec($cmd));
|
||||
$passed2 = (strpos($result, "(cli)") !== false);
|
||||
list($result) = explode("\n", $result);
|
||||
$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);
|
||||
}
|
||||
|
||||
if ($passed2) {
|
||||
$str = autoname(8);
|
||||
$cmd = "$phpath testargs.php $str";
|
||||
$result = trim(shell_exec($cmd));
|
||||
$passed3 = $result == $str;
|
||||
$help = "";
|
||||
if (!$passed3) {
|
||||
$help .= L10n::t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . EOL;
|
||||
$help .= L10n::t('This is required for message delivery to work.');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('PHP register_argc_argv'), $passed3, true, $help);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OpenSSL Check
|
||||
*
|
||||
* Checks the OpenSSL Environment
|
||||
*
|
||||
* - Checks, if the command "openssl_pkey_new" is available
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkKeys(&$checks)
|
||||
{
|
||||
$help = '';
|
||||
$res = false;
|
||||
|
||||
if (function_exists('openssl_pkey_new')) {
|
||||
$res = openssl_pkey_new([
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 4096,
|
||||
'encrypt_key' => false
|
||||
]);
|
||||
}
|
||||
|
||||
// Get private key
|
||||
if (!$res) {
|
||||
$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".');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('Generate encryption keys'), $res, true, $help);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP functions Check
|
||||
*
|
||||
* Checks the following PHP functions
|
||||
* - libCurl
|
||||
* - GD Graphics
|
||||
* - OpenSSL
|
||||
* - PDO or MySQLi
|
||||
* - mb_string
|
||||
* - XML
|
||||
* - iconv
|
||||
* - POSIX
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkFunctions(&$checks)
|
||||
{
|
||||
$ck_funcs = [];
|
||||
self::addCheck($ck_funcs, L10n::t('libCurl PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('GD graphics PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('OpenSSL PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('mb_string PHP module'), true, true, "");
|
||||
self::addCheck($ck_funcs, L10n::t('XML PHP module'), true, true, "");
|
||||
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('apache_get_modules')) {
|
||||
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.'));
|
||||
} else {
|
||||
self::addCheck($ck_funcs, L10n::t('Apache mod_rewrite module'), true, true, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('curl_init')) {
|
||||
$ck_funcs[0]['status'] = false;
|
||||
$ck_funcs[0]['help'] = L10n::t('Error: libCURL PHP module required but not installed.');
|
||||
}
|
||||
if (!function_exists('imagecreatefromjpeg')) {
|
||||
$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('openssl_public_encrypt')) {
|
||||
$ck_funcs[2]['status'] = false;
|
||||
$ck_funcs[2]['help'] = L10n::t('Error: openssl PHP module required but not installed.');
|
||||
}
|
||||
if (!function_exists('mysqli_connect') && !class_exists('pdo')) {
|
||||
$ck_funcs[3]['status'] = false;
|
||||
$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;
|
||||
$ck_funcs[3]['help'] = L10n::t('Error: The MySQL driver for PDO is not installed.');
|
||||
}
|
||||
if (!function_exists('mb_strlen')) {
|
||||
$ck_funcs[4]['status'] = false;
|
||||
$ck_funcs[4]['help'] = L10n::t('Error: mb_string 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.');
|
||||
}
|
||||
if (!function_exists('posix_kill')) {
|
||||
$ck_funcs[7]['status'] = false;
|
||||
$ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.');
|
||||
}
|
||||
|
||||
$checks = array_merge($checks, $ck_funcs);
|
||||
|
||||
// check for XML DOM Documents being able to be generated
|
||||
try {
|
||||
$xml = new DOMDocument();
|
||||
} catch (Exception $e) {
|
||||
$ck_funcs[5]['status'] = false;
|
||||
$ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "config/local.ini.php" - Check
|
||||
*
|
||||
* Checks if it's possible to create the "config/local.ini.php"
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkLocalIni(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
if ((file_exists('config/local.ini.php') && !is_writable('config/local.ini.php')) ||
|
||||
(!file_exists('config/local.ini.php') && !is_writable('.'))) {
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('config/local.ini.php is writable'), $status, false, $help);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty3 Template Check
|
||||
*
|
||||
* Checks, if the directory of Smarty3 is writable
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkSmarty3(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
if (!is_writable('view/smarty3')) {
|
||||
|
||||
$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;
|
||||
$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;
|
||||
}
|
||||
|
||||
self::addCheck($checks, L10n::t('view/smarty3 is writable'), $status, true, $help);
|
||||
}
|
||||
|
||||
/**
|
||||
* ".htaccess" - Check
|
||||
*
|
||||
* Checks, if "url_rewrite" is enabled in the ".htaccess" file
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkHtAccess(&$checks)
|
||||
{
|
||||
$status = true;
|
||||
$help = "";
|
||||
$error_msg = "";
|
||||
if (function_exists('curl_init')) {
|
||||
$test = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite");
|
||||
|
||||
$url = normalise_link(System::baseUrl() . "/install/testrewrite");
|
||||
if ($test['body'] != "ok") {
|
||||
$test = Network::fetchUrlFull($url);
|
||||
}
|
||||
|
||||
if ($test['body'] != "ok") {
|
||||
$status = false;
|
||||
$help = L10n::t('Url rewrite in .htaccess is not working. Check your server configuration.');
|
||||
$error_msg = [];
|
||||
$error_msg['head'] = L10n::t('Error message from Curl when fetching');
|
||||
$error_msg['url'] = $test['redirect_url'];
|
||||
$error_msg['msg'] = defaults($test, 'error', '');
|
||||
}
|
||||
self::addCheck($checks, L10n::t('Url rewrite is working'), $status, true, $help, $error_msg);
|
||||
} else {
|
||||
// cannot check modrewrite if libcurl is not installed
|
||||
/// @TODO Maybe issue warning here?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imagick Check
|
||||
*
|
||||
* Checks, if the imagick module is available
|
||||
*
|
||||
* @param array $checks The list of all checks (by-ref parameter!)
|
||||
*/
|
||||
public static function checkImagick(&$checks)
|
||||
{
|
||||
$imagick = false;
|
||||
$gif = false;
|
||||
|
||||
if (class_exists('Imagick')) {
|
||||
$imagick = true;
|
||||
$supported = Image::supportedTypes();
|
||||
if (array_key_exists('image/gif', $supported)) {
|
||||
$gif = true;
|
||||
}
|
||||
}
|
||||
if ($imagick == false) {
|
||||
self::addCheck($checks, L10n::t('ImageMagick PHP extension is not installed'), $imagick, false, "");
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,6 +344,10 @@ class NotificationsManager extends BaseObject
|
|||
break;
|
||||
|
||||
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' ?" . ">";
|
||||
$obj = XML::parseString($xmlhead . $it['object']);
|
||||
$it['fname'] = $obj->title;
|
||||
|
|
|
@ -65,7 +65,7 @@ class System extends BaseObject
|
|||
while ($func = array_pop($trace)) {
|
||||
if (!empty($func['class'])) {
|
||||
// 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']);
|
||||
$callstack[] = array_pop($classparts).'::'.$func['function'];
|
||||
$previous = $func;
|
||||
|
|
|
@ -372,7 +372,7 @@ class DBA
|
|||
* @usage Example: $r = p("SELECT * FROM `item` WHERE `guid` = ?", $guid);
|
||||
*
|
||||
* 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
|
||||
* @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
|
||||
*
|
||||
* Please use dba::delete, dba::insert, dba::update, ... instead
|
||||
* Please use DBA::delete, DBA::insert, DBA::update, ... instead
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return boolean Was the query successfull? False is returned only if an error occurred
|
||||
|
@ -685,7 +685,7 @@ class DBA
|
|||
/**
|
||||
* 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
|
||||
* @param string $sql SQL statement
|
||||
|
@ -1303,7 +1303,7 @@ class DBA
|
|||
*
|
||||
* $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 = [])
|
||||
{
|
||||
|
@ -1345,7 +1345,7 @@ class DBA
|
|||
* or:
|
||||
* $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 = [])
|
||||
{
|
||||
|
@ -1399,7 +1399,7 @@ class DBA
|
|||
/* Workaround for MySQL Bug #64791.
|
||||
* Never mix data types inside any IN() condition.
|
||||
* 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_alpha = false;
|
||||
|
@ -1459,7 +1459,7 @@ class DBA
|
|||
|
||||
$limit_string = '';
|
||||
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'])) {
|
||||
|
@ -1530,7 +1530,7 @@ class DBA
|
|||
case 'mysqli':
|
||||
// MySQLi offers both a mysqli_stmt and a mysqli_result class.
|
||||
// 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) {
|
||||
$stmt->free_result();
|
||||
$ret = $stmt->close();
|
||||
|
|
|
@ -364,8 +364,13 @@ class Contact extends BaseObject
|
|||
*/
|
||||
public static function markForArchival(array $contact)
|
||||
{
|
||||
|
||||
if (!isset($contact['url'])) {
|
||||
if (!isset($contact['url']) && !empty($contact['id'])) {
|
||||
$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);
|
||||
}
|
||||
|
||||
|
@ -376,10 +381,7 @@ class Contact extends BaseObject
|
|||
|
||||
if ($contact['term-date'] <= NULL_DATE) {
|
||||
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
|
||||
|
||||
if ($contact['url'] != '') {
|
||||
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE]);
|
||||
}
|
||||
DBA::update('contact', ['term-date' => DateTimeFormat::utcNow()], ['`nurl` = ? AND `term-date` <= ? AND NOT `self`', normalise_link($contact['url']), NULL_DATE]);
|
||||
} else {
|
||||
/* @todo
|
||||
* 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.
|
||||
*/
|
||||
DBA::update('contact', ['archive' => 1], ['id' => $contact['id']]);
|
||||
|
||||
if ($contact['url'] != '') {
|
||||
DBA::update('contact', ['archive' => 1], ['nurl' => normalise_link($contact['url']), 'self' => false]);
|
||||
}
|
||||
DBA::update('contact', ['archive' => 1], ['nurl' => normalise_link($contact['url']), 'self' => false]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,13 +422,18 @@ class Contact extends BaseObject
|
|||
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.
|
||||
$fields = ['term-date' => NULL_DATE, 'archive' => false];
|
||||
DBA::update('contact', $fields, ['id' => $contact['id']]);
|
||||
|
||||
if (!empty($contact['url'])) {
|
||||
DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]);
|
||||
}
|
||||
DBA::update('contact', $fields, ['nurl' => normalise_link($contact['url'])]);
|
||||
|
||||
if (!empty($contact['batch'])) {
|
||||
$condition = ['batch' => $contact['batch'], 'contact-type' => self::ACCOUNT_TYPE_RELAY];
|
||||
|
|
|
@ -273,36 +273,25 @@ class Group extends BaseObject
|
|||
*
|
||||
* @param array $group_ids
|
||||
* @param boolean $check_dead
|
||||
* @param boolean $use_gcontact
|
||||
* @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)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$condition = '`gid` IN (' . substr(str_repeat("?, ", count($group_ids)), 0, -2) . ')';
|
||||
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);
|
||||
}
|
||||
$stmt = DBA::select('group_member', ['contact-id'], ['gid' => $group_ids]);
|
||||
|
||||
$return = [];
|
||||
while($group_member = DBA::fetch($stmt)) {
|
||||
$return[] = $group_member['contact-id'];
|
||||
}
|
||||
|
||||
if ($check_dead && !$use_gcontact) {
|
||||
if ($check_dead) {
|
||||
Contact::pruneUnavailable($return);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
|
|
@ -933,7 +933,12 @@ class Probe
|
|||
}
|
||||
|
||||
$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["dfrn-request"] = $data["request"];
|
||||
$prof_data["dfrn-confirm"] = $data["confirm"];
|
||||
|
|
|
@ -1050,7 +1050,7 @@ class Diaspora
|
|||
return false;
|
||||
}
|
||||
|
||||
$contact = dba::selectFirst('contact', [], ['id' => $cid]);
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $cid]);
|
||||
if (!DBA::isResult($contact)) {
|
||||
// This here shouldn't happen at all
|
||||
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 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))) {
|
||||
// dba::update(
|
||||
// DBA::update(
|
||||
// 'contact',
|
||||
// array('rel' => Contact::FRIEND, 'writable' => true),
|
||||
// array('id' => $contact["id"], 'uid' => $contact["uid"])
|
||||
|
@ -1821,10 +1821,10 @@ class Diaspora
|
|||
"to_name" => $importer["username"],
|
||||
"to_email" => $importer["email"],
|
||||
"uid" =>$importer["uid"],
|
||||
"item" => ["subject" => $subject, "body" => $body],
|
||||
"item" => ["id" => $conversation["id"], "title" => $subject, "subject" => $subject, "body" => $body],
|
||||
"source_name" => $person["name"],
|
||||
"source_link" => $person["url"],
|
||||
"source_photo" => $person["thumb"],
|
||||
"source_photo" => $person["photo"],
|
||||
"verb" => ACTIVITY_POST,
|
||||
"otype" => "mail"]
|
||||
);
|
||||
|
@ -3075,7 +3075,7 @@ class Diaspora
|
|||
logger("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code);
|
||||
|
||||
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");
|
||||
// queue message for redelivery
|
||||
Queue::add($contact["id"], Protocol::DIASPORA, $envelope, $public_batch, $guid);
|
||||
|
|
|
@ -716,7 +716,7 @@ class Network
|
|||
$url = self::stripTrackingQueryParams($url);
|
||||
|
||||
if ($depth > 10) {
|
||||
return($url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
$url = trim($url, "'");
|
||||
|
@ -739,16 +739,14 @@ class Network
|
|||
$a->save_timestamp($stamp1, "network");
|
||||
|
||||
if ($http_code == 0) {
|
||||
return($url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
if ((($curl_info['http_code'] == "301") || ($curl_info['http_code'] == "302"))
|
||||
&& (($curl_info['redirect_url'] != "") || ($curl_info['location'] != ""))
|
||||
) {
|
||||
if ($curl_info['redirect_url'] != "") {
|
||||
return(self::finalUrl($curl_info['redirect_url'], ++$depth, $fetchbody));
|
||||
} else {
|
||||
return(self::finalUrl($curl_info['location'], ++$depth, $fetchbody));
|
||||
if (in_array($http_code, ['301', '302'])) {
|
||||
if (!empty($curl_info['redirect_url'])) {
|
||||
return self::finalUrl($curl_info['redirect_url'], ++$depth, $fetchbody);
|
||||
} elseif (!empty($curl_info['location'])) {
|
||||
return self::finalUrl($curl_info['location'], ++$depth, $fetchbody);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,12 +757,12 @@ class Network
|
|||
|
||||
// if the file is too large then exit
|
||||
if ($curl_info["download_content_length"] > 1000000) {
|
||||
return($url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
// if it isn't a HTML file then exit
|
||||
if (($curl_info["content_type"] != "") && !strstr(strtolower($curl_info["content_type"]), "html")) {
|
||||
return($url);
|
||||
if (!empty($curl_info["content_type"]) && !strstr(strtolower($curl_info["content_type"]), "html")) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
@ -783,7 +781,7 @@ class Network
|
|||
$a->save_timestamp($stamp1, "network");
|
||||
|
||||
if (trim($body) == "") {
|
||||
return($url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Check for redirect in meta elements
|
||||
|
@ -806,7 +804,7 @@ class Network
|
|||
$pathinfo = explode(";", $path);
|
||||
foreach ($pathinfo as $value) {
|
||||
if (substr(strtolower($value), 0, 4) == "url=") {
|
||||
return(self::finalUrl(substr($value, 4), ++$depth));
|
||||
return self::finalUrl(substr($value, 4), ++$depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class DBClean {
|
|||
$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
|
||||
`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);
|
||||
if ($count > 0) {
|
||||
logger("found global item orphans: ".$count);
|
||||
|
@ -106,7 +106,7 @@ class DBClean {
|
|||
logger("Deleting items without parents. Last ID: ".$last_id);
|
||||
$r = DBA::p("SELECT `id` FROM `item`
|
||||
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);
|
||||
if ($count > 0) {
|
||||
logger("found item orphans without parents: ".$count);
|
||||
|
@ -132,7 +132,7 @@ class DBClean {
|
|||
logger("Deleting orphaned data from thread table. Last ID: ".$last_id);
|
||||
$r = DBA::p("SELECT `iid` FROM `thread`
|
||||
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);
|
||||
if ($count > 0) {
|
||||
logger("found thread orphans: ".$count);
|
||||
|
@ -158,7 +158,7 @@ class DBClean {
|
|||
logger("Deleting orphaned data from notify table. Last ID: ".$last_id);
|
||||
$r = DBA::p("SELECT `iid`, `id` FROM `notify`
|
||||
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);
|
||||
if ($count > 0) {
|
||||
logger("found notify orphans: ".$count);
|
||||
|
@ -184,7 +184,7 @@ class DBClean {
|
|||
logger("Deleting orphaned data from notify-threads table. Last ID: ".$last_id);
|
||||
$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` >= ?
|
||||
ORDER BY `id` LIMIT ".intval($limit), $last_id);
|
||||
ORDER BY `id` LIMIT ?", $last_id, $limit);
|
||||
$count = DBA::numRows($r);
|
||||
if ($count > 0) {
|
||||
logger("found notify-threads orphans: ".$count);
|
||||
|
@ -210,7 +210,7 @@ class DBClean {
|
|||
logger("Deleting orphaned data from sign table. Last ID: ".$last_id);
|
||||
$r = DBA::p("SELECT `iid`, `id` FROM `sign`
|
||||
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);
|
||||
if ($count > 0) {
|
||||
logger("found sign orphans: ".$count);
|
||||
|
@ -236,7 +236,7 @@ class DBClean {
|
|||
logger("Deleting orphaned data from term table. Last ID: ".$last_id);
|
||||
$r = DBA::p("SELECT `oid`, `tid` FROM `term`
|
||||
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);
|
||||
if ($count > 0) {
|
||||
logger("found term orphans: ".$count);
|
||||
|
@ -303,7 +303,7 @@ class DBClean {
|
|||
$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
|
||||
`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);
|
||||
if ($count > 0) {
|
||||
logger("found global item entries from expired threads: ".$count);
|
||||
|
@ -326,7 +326,7 @@ class DBClean {
|
|||
logger("Deleting old conversations. Last created: ".$last_id);
|
||||
$r = DBA::p("SELECT `received`, `item-uri` FROM `conversation`
|
||||
WHERE `received` < UTC_TIMESTAMP() - INTERVAL ? DAY
|
||||
ORDER BY `received` LIMIT ".intval($limit), $days);
|
||||
ORDER BY `received` LIMIT ?", $days, $limit);
|
||||
$count = DBA::numRows($r);
|
||||
if ($count > 0) {
|
||||
logger("found old conversations: ".$count);
|
||||
|
|
|
@ -216,7 +216,7 @@ class DiscoverPoCo
|
|||
$x = Network::fetchUrl(get_server()."/lsearch?p=1&n=500&search=".urlencode($search));
|
||||
$j = json_decode($x);
|
||||
|
||||
if (count($j->results)) {
|
||||
if (!empty($j->results)) {
|
||||
foreach ($j->results as $jj) {
|
||||
// Check if the contact already exists
|
||||
$exists = q("SELECT `id`, `last_contact`, `last_failure`, `updated` FROM `gcontact` WHERE `nurl` = '%s'", normalise_link($jj->url));
|
||||
|
|
|
@ -380,7 +380,8 @@
|
|||
'cursor' : 'pointer'
|
||||
});
|
||||
|
||||
var div = document.createElement("div");
|
||||
var div = document.createElement("div");
|
||||
div.setAttribute('class', 'ajaxbutton-wrapper');
|
||||
addStyles(div, {
|
||||
'display' : 'block',
|
||||
'position' : 'absolute',
|
||||
|
|
|
@ -439,8 +439,10 @@
|
|||
<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="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="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="work-jot-text" name="work" value="{{$work.2}}" />
|
||||
<input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />
|
||||
|
|
|
@ -15,14 +15,14 @@ function theme_post(App $a)
|
|||
}
|
||||
|
||||
if (isset($_POST['frio-settings-submit'])) {
|
||||
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_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', 'background_color', defaults($_POST, 'frio_background_color'));
|
||||
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', 'bg_image_option', defaults($_POST, 'frio_bg_image_option'));
|
||||
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_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', 'background_color', defaults($_POST, 'frio_background_color', ''));
|
||||
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', 'bg_image_option', defaults($_POST, 'frio_bg_image_option', ''));
|
||||
PConfig::set(local_user(), 'frio', 'css_modified', time());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -958,6 +958,10 @@ nav.navbar a, nav.navbar .btn-link {
|
|||
color: #fff!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 > li > .btn {
|
||||
color: #bebebe;
|
||||
|
@ -1418,6 +1422,15 @@ section #jotOpen {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.fa.lock:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f023";
|
||||
}
|
||||
.fa.unlock:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f09c";
|
||||
}
|
||||
|
||||
/* Filebrowser */
|
||||
.fbrowser .breadcrumb {
|
||||
margin-bottom: 0px;
|
||||
|
|
|
@ -12,7 +12,7 @@ $(document).ready(function(){
|
|||
// with AjaxUpload.
|
||||
$(".fbrowser").remove();
|
||||
// Remove the AjaxUpload element.
|
||||
$("[name=userfile]").parent().remove();
|
||||
$(".ajaxbutton-wrapper").remove();
|
||||
});
|
||||
|
||||
// Clear bs modal on close.
|
||||
|
|
|
@ -44,7 +44,7 @@ if (!isset($minimal)) {
|
|||
$uid = Profile::getThemeUid();
|
||||
}
|
||||
$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')) {
|
||||
$schemefile = 'view/theme/frio/scheme/' . $scheme . '.php';
|
||||
require_once $schemefile;
|
||||
|
@ -52,7 +52,7 @@ if (!isset($minimal)) {
|
|||
} else {
|
||||
$nav_bg = PConfig::get($uid, 'frio', 'nav_bg');
|
||||
}
|
||||
if (!$nav_bg) {
|
||||
if (empty($nav_bg)) {
|
||||
$nav_bg = "#708fa0";
|
||||
}
|
||||
echo '
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
|
||||
<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> </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}}
|
||||
<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> </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}}
|
||||
<img id="like-rotator-{{$id}}" class="like-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait}}" style="display: none;" />
|
||||
</div>
|
||||
|
|
|
@ -4,16 +4,30 @@
|
|||
<div id="live-photos"></div>
|
||||
|
||||
<div id="photo-view-{{$id}}" class="generic-page-wrapper">
|
||||
<h3><a href="{{$album.0}}">{{$album.1}}</a></h3>
|
||||
|
||||
<div id="photo-edit-link-wrap">
|
||||
{{if $tools}}
|
||||
<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 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">
|
||||
<i class="fa fa-folder-open"></i> {{$album.1}}
|
||||
</a>
|
||||
</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-photo">
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<input id="photos-upload-choose" type="file" name="userfile" />
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<button id="photos-upload-submit" class="btn btn-primary">{{$submit|escape:'html'}}</button>
|
|
@ -5,49 +5,68 @@
|
|||
<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">
|
||||
<div id="photos-upload-new-wrapper" >
|
||||
<div id="photos-upload-newalbum-div">
|
||||
<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-div" class="form-group">
|
||||
<label id="photos-upload-text" for="photos-upload-newalbum" >{{$newalbum}}</label>
|
||||
|
||||
<div id="photos-upload-exist-wrapper">
|
||||
<div id="photos-upload-existing-album-div">
|
||||
<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>
|
||||
<input id="photos-upload-album-select" class="form-control" placeholder="{{$existalbumtext}}" list="dl-photo-upload" type="text" name="album" size="4">
|
||||
<datalist id="dl-photo-upload">{{$albumselect}}</datalist>
|
||||
</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/>
|
||||
<label id="photos-upload-noshare-text" for="photos-upload-noshare" >{{$nosharetext}}</label>
|
||||
</div>
|
||||
|
||||
<div id="photos-upload-perms" class="photos-upload-perms pull-right" >
|
||||
<a href="#photos-upload-permissions-wrapper" id="photos-upload-perms-menu" class="button popupbox" />
|
||||
<span id="jot-perms-icon" class="icon {{$lockstate}}" ></span>{{$permissions}}
|
||||
</a>
|
||||
</div>
|
||||
<div id="photos-upload-perms-end" class="clear"></div>
|
||||
{{if $alt_uploader}}
|
||||
<div id="photos-upload-perms" class="pull-right">
|
||||
<button class="btn btn-default btn-sm" data-toggle="modal" data-target="#aclModal" onclick="return false;">
|
||||
<i id="jot-perms-icon" class="fa {{$lockstate}}"></i> {{$permissions}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div style="display: none;">
|
||||
<div id="photos-upload-permissions-wrapper">
|
||||
{{$aclselect}}
|
||||
<div id="photos-upload-spacer"></div>
|
||||
|
||||
{{$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">
|
||||
×
|
||||
</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 id="photos-upload-spacer"></div>
|
||||
|
||||
{{$alt_uploader}}
|
||||
|
||||
{{$default_upload_box}}
|
||||
{{$default_upload_submit}}
|
||||
|
||||
<div class="photos-upload-end" ></div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -434,8 +434,10 @@
|
|||
<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="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="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="work-jot-text" name="work" value="{{$work.2}}" />
|
||||
<input type="hidden" id="education-jot-text" name="education" value="{{$education.2}}" />
|
||||
|
|
Loading…
Reference in New Issue
Block a user