1
1
Fork 0

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

This commit is contained in:
Michael 2018-01-03 01:15:27 +00:00
commit 6925299e5a
65 changed files with 3063 additions and 4000 deletions

106
boot.php
View file

@ -37,7 +37,6 @@ require_once 'include/datetime.php';
require_once 'include/pgettext.php';
require_once 'include/nav.php';
require_once 'include/identity.php';
require_once 'update.php';
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Asparagus');
@ -573,6 +572,51 @@ function x($s, $k = null)
}
}
/**
* Return the provided variable value if it exists and is truthy or the provided
* default value instead.
*
* Works with initialized variables and potentially uninitialized array keys
*
* Usages:
* - defaults($var, $default)
* - defaults($array, 'key', $default)
*
* @brief Returns a defaut value if the provided variable or array key is falsy
* @see x()
* @return mixed
*/
function defaults() {
$args = func_get_args();
if (count($args) < 2) {
throw new BadFunctionCallException('defaults() requires at least 2 parameters');
}
if (count($args) > 3) {
throw new BadFunctionCallException('defaults() cannot use more than 3 parameters');
}
if (count($args) === 3 && !is_array($args[0])) {
throw new BadFunctionCallException('defaults($arr, $key, $def) requires an array as first parameter');
}
if (count($args) === 3 && is_null($args[1])) {
throw new BadFunctionCallException('defaults($arr, $key, $def) $key is null');
}
$default = array_pop($args);
if (call_user_func_array('x', $args)) {
if (count($args) === 1) {
$return = $args[0];
} else {
$return = $args[0][$args[1]];
}
} else {
$return = $default;
}
return $return;
}
/**
* @brief Returns the baseurl.
*
@ -619,10 +663,17 @@ function is_ajax()
function check_db($via_worker)
{
$build = Config::get('system', 'build');
if (!x($build)) {
if (empty($build)) {
Config::set('system', 'build', DB_UPDATE_VERSION);
$build = DB_UPDATE_VERSION;
}
// We don't support upgrading from very old versions anymore
if ($build < NEW_UPDATE_ROUTINE_VERSION) {
die('You try to update from a version prior to database version 1170. The direct upgrade path is not supported. Please update to version 3.5.4 before updating to this version.');
}
if ($build != DB_UPDATE_VERSION) {
// When we cannot execute the database update via the worker, we will do it directly
if (!Worker::add(PRIORITY_CRITICAL, 'DBUpdate') && $via_worker) {
@ -647,7 +698,7 @@ function check_url(App $a)
// and www.example.com vs example.com.
// We will only change the url to an ip address if there is no existing setting
if (!x($url)) {
if (empty($url)) {
$url = Config::set('system', 'url', System::baseUrl());
}
if ((!link_compare($url, System::baseUrl())) && (!preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/", $a->get_hostname))) {
@ -664,25 +715,21 @@ function check_url(App $a)
function update_db(App $a)
{
$build = Config::get('system', 'build');
if (!x($build)) {
$build = Config::set('system', 'build', DB_UPDATE_VERSION);
if (empty($build)) {
Config::set('system', 'build', DB_UPDATE_VERSION);
$build = DB_UPDATE_VERSION;
}
if ($build != DB_UPDATE_VERSION) {
require_once 'update.php';
$stored = intval($build);
$current = intval(DB_UPDATE_VERSION);
if ($stored < $current) {
Config::load('database');
// We're reporting a different version than what is currently installed.
// Run any existing update scripts to bring the database up to current.
// make sure that boot.php and update.php are the same release, we might be
// updating right this very second and the correct version of the update.php
// file may not be here yet. This can happen on a very busy site.
if (DB_UPDATE_VERSION == UPDATE_VERSION) {
// Compare the current structure with the defined structure
$t = Config::get('database', 'dbupdate_' . DB_UPDATE_VERSION);
if (!is_null($t)) {
return;
@ -690,19 +737,7 @@ function update_db(App $a)
Config::set('database', 'dbupdate_' . DB_UPDATE_VERSION, time());
// run old update routine (wich could modify the schema and
// conflits with new routine)
for ($x = $stored; $x < NEW_UPDATE_ROUTINE_VERSION; $x++) {
$r = run_update_function($x);
if (!$r) {
break;
}
}
if ($stored < NEW_UPDATE_ROUTINE_VERSION) {
$stored = NEW_UPDATE_ROUTINE_VERSION;
}
// run new update routine
// run update routine
// it update the structure in one call
$retval = DBStructure::update(false, true);
if ($retval) {
@ -716,7 +751,7 @@ function update_db(App $a)
}
// run any left update_nnnn functions in update.php
for ($x = $stored; $x < $current; $x ++) {
for ($x = $stored + 1; $x <= $current; $x++) {
$r = run_update_function($x);
if (!$r) {
break;
@ -724,7 +759,6 @@ function update_db(App $a)
}
}
}
}
return;
}
@ -996,7 +1030,7 @@ function remote_user()
if (local_user()) {
return false;
}
if ((x($_SESSION, 'authenticated')) && (x($_SESSION, 'visitor_id'))) {
if (x($_SESSION, 'authenticated') && x($_SESSION, 'visitor_id')) {
return intval($_SESSION['visitor_id']);
}
return false;
@ -1051,7 +1085,7 @@ function info($s)
function get_max_import_size()
{
$a = get_app();
return ((x($a->config, 'max_import_size')) ? $a->config['max_import_size'] : 0 );
return (x($a->config, 'max_import_size') ? $a->config['max_import_size'] : 0);
}
@ -1601,14 +1635,11 @@ function argv($x)
function infinite_scroll_data($module)
{
if (PConfig::get(local_user(), 'system', 'infinite_scroll')
&& ($module == "network") && ($_GET["mode"] != "minimal")
&& $module == 'network'
&& defaults($_GET, 'mode', '') != 'minimal'
) {
// get the page number
if (is_string($_GET["page"])) {
$pageno = $_GET["page"];
} else {
$pageno = 1;
}
$pageno = defaults($_GET, 'page', 1);
$reload_uri = "";
@ -1619,7 +1650,8 @@ function infinite_scroll_data($module)
}
}
if (($a->page_offset != "") && ! strstr($reload_uri, "&offset=")) {
$a = get_app();
if ($a->page_offset != "" && !strstr($reload_uri, "&offset=")) {
$reload_uri .= "&offset=" . urlencode($a->page_offset);
}

View file

@ -1,5 +1,6 @@
Where to get started to help improve Friendica?
===============================================
# Where to get started to help improve Friendica
<!-- markdownlint-disable MD010 MD013 -->
* [Home](help)
@ -10,29 +11,25 @@ A project like Friendica is the sum of many different contributions.
We are looking for helpers in all areas, whether you write text or code, whether you spread the word to convince people or design new icons.
Whether you feel like an expert or like a newbie - join us with your ideas!
Contact us
---
## Contact us
The discussion of Friendica development takes place in the following Friendica forums:
* The main [forum for Friendica development](https://forum.friendi.ca/profile/developers)
* The [forum for Friendica theme development](https://friendica.eu/profile/ftdevs)
Help other users
---
## Help other users
Remember the questions you had when you first tried Friendica?
A good place to start can be to help new people find their way around Friendica in the [general support forum](https://forum.friendi.ca/prufile/helpers).
Welcome them, answer their questions, point them to documentation or ping other helpers directly if you can't help but think you know who can.
Translation
---
## Translation
The documentation contains help on how to translate Friendica [at Transifex](/help/translations) where the UI is translated.
If you don't want to translate the UI, or it is already done to your satisfaction, you might want to work on the translation of the /help files?
Design
---
## Design
Are you good at designing things?
If you have seen Friendica you probably have ideas to improve it, haven't you?
@ -43,8 +40,7 @@ If you have seen Friendica you probably have ideas to improve it, haven't you?
We can't promise we have the right skills in the group but we'll try.
* Choose a thing to start with, e.g. work on the icon set of your favorite theme
Programming
---
## Programming
### Composer
@ -60,6 +56,7 @@ It's a command-line tool that downloads required libraries into the `vendor` fol
For the sake of consistency between contribution and general code readability, Friendica follows the widespread [PSR-2 coding standards](http://www.php-fig.org/psr/psr-2/) to the exception of a few rules.
Here's a few primers if you are new to Friendica or to the PSR-2 coding standards:
* Indentation is tabs, period (not PSR-2).
* By default, strings are enclosed in single quotes, but feel free to use double quotes if it makes more sense (SQL queries, adding tabs and line feeds).
* Operators are wrapped by spaces, e.g. `$var === true`, `$var = 1 + 2` and `'string' . $concat . 'enation'`

View file

@ -692,6 +692,23 @@ On error:
---
### account/update_profile (POST; AUTH)
#### Parameters
* name (optional): full name of the user
* description (optional): a description of the user
#### Unsupported parameters
* url
* location
* profile_link_color
* include_entities
* skip_status
---
### friendships/incoming (*; AUTH)
#### Unsupported parameters
@ -1205,7 +1222,6 @@ The following API calls from the Twitter API are not implemented in either Frien
* friendships/lookup
* account/settings
* account/update_delivery_device
* account/update_profile
* blocks/ids
* users/show
* users/search

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,6 @@ use Friendica\Network\Probe;
use League\HTMLToMarkdown\HtmlConverter;
require_once 'include/oembed.php';
require_once 'include/event.php';
require_once 'library/markdown.php';
require_once 'include/html2bbcode.php';

View file

@ -2,13 +2,13 @@
use Friendica\App;
use Friendica\Content\Smilies;
use Friendica\Content\OEmbed;
use Friendica\Core\Cache;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Model\Contact;
use Friendica\Util\Map;
require_once 'include/oembed.php';
require_once 'include/event.php';
require_once 'mod/proxy.php';
require_once 'include/plaintext.php';
@ -232,7 +232,7 @@ function tryoembed($match) {
$url = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
array("https://www.youtube.com/", "https://player.vimeo.com/"), $url);
$o = oembed_fetch_url($url);
$o = OEmbed::fetchURL($url);
if (!is_object($o)) {
return $match[0];
@ -246,7 +246,7 @@ function tryoembed($match) {
return $match[0];
}
$html = oembed_format_object($o);
$html = OEmbed::formatObject($o);
return $html;
}
@ -435,60 +435,65 @@ function bb_replace_images($body, $images) {
return $newbody;
}
function bb_ShareAttributes($share, $simplehtml) {
function bb_ShareAttributes($share, $simplehtml)
{
$attributes = $share[2];
$author = "";
preg_match("/author='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$author = html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
}
preg_match('/author="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$author = $matches[1];
}
$profile = "";
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$profile = $matches[1];
}
preg_match('/profile="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$profile = $matches[1];
}
$avatar = "";
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$avatar = $matches[1];
}
preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$avatar = $matches[1];
}
$link = "";
preg_match("/link='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$link = $matches[1];
}
preg_match('/link="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$link = $matches[1];
}
$posted = "";
$itemcache = get_itemcachepath();
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$posted = $matches[1];
}
preg_match('/posted="(.*?)"/ism', $attributes, $matches);
if ($matches[1] != "")
if (x($matches, 1)) {
$posted = $matches[1];
// relative dates only make sense when they aren't cached
if ($itemcache == "")
$reldate = (($posted) ? " " . relative_date($posted) : '');
}
// We only call this so that a previously unknown contact can be added.
// This is important for the function "get_contact_details_by_url".
@ -497,26 +502,31 @@ function bb_ShareAttributes($share, $simplehtml) {
$data = Contact::getDetailsByURL($profile);
if (isset($data["name"]) && ($data["name"] != "") && isset($data["addr"]) && ($data["addr"] != ""))
if (x($data, "name") && x($data, "addr")) {
$userid_compact = $data["name"] . " (" . $data["addr"] . ")";
else
} else {
$userid_compact = GetProfileUsername($profile, $author, true);
}
if (isset($data["addr"]) && ($data["addr"] != ""))
if (x($data, "addr")) {
$userid = $data["addr"];
else
} else {
$userid = GetProfileUsername($profile, $author, false);
}
if (isset($data["name"]) && ($data["name"] != ""))
if (x($data, "name")) {
$author = $data["name"];
}
if (isset($data["micro"]) && ($data["micro"] != ""))
if (x($data, "micro")) {
$avatar = $data["micro"];
}
$preshare = trim($share[1]);
if ($preshare != "")
if ($preshare != "") {
$preshare .= "<br /><br />";
}
switch ($simplehtml) {
case 1:
@ -530,27 +540,31 @@ function bb_ShareAttributes($share, $simplehtml) {
$text = trim($share[1]);
if ($text != "")
if ($text != "") {
$text .= "<hr />";
}
if (substr(normalise_link($link), 0, 19) != "http://twitter.com/") {
$text .= $headline . '<blockquote>' . trim($share[3]) . "</blockquote><br />";
if ($link != "")
if ($link != "") {
$text .= '<br /><a href="' . $link . '">[l]</a>';
} else
}
} else {
$text .= '<br /><a href="' . $link . '">' . $link . '</a>';
}
break;
case 4:
$headline .= '<br /><b>' . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8');
$headline .= sprintf(t('<a href="%1$s" target="_blank">%2$s</a> %3$s'), $link, $userid, $posted);
$headline .= t('<a href="%1$s" target="_blank">%2$s</a> %3$s', $link, $userid, $posted);
$headline .= ":</b><br />";
$text = trim($share[1]);
if ($text != "")
if ($text != "") {
$text .= "<hr />";
}
$text .= $headline . '<blockquote class="shared_content">' . trim($share[3]) . "</blockquote><br />";
@ -570,8 +584,9 @@ function bb_ShareAttributes($share, $simplehtml) {
case 9: // Google+/Facebook
$text = $preshare . html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8') . ' ' . $userid_compact . ": <br />" . $share[3];
if ($link != "")
if ($link != "") {
$text .= "<br /><br />" . $link;
}
break;
default:
$text = trim($share[1]) . "\n";
@ -579,14 +594,12 @@ function bb_ShareAttributes($share, $simplehtml) {
$avatar = proxy_url($avatar, false, PROXY_SIZE_THUMB);
$tpl = get_markup_template('shared_content.tpl');
$text .= replace_macros($tpl,
array(
$text .= replace_macros($tpl, array(
'$profile' => $profile,
'$avatar' => $avatar,
'$author' => $author,
'$link' => $link,
'$posted' => $posted,
'$reldate' => $reldate,
'$content' => trim($share[3])
)
);
@ -1263,7 +1276,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $simplehtml = fa
// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
// oembed tag
$Text = oembed_bbcode2html($Text);
$Text = OEmbed::BBCode2HTML($Text);
// Avoid triple linefeeds through oembed
$Text = str_replace("<br style='clear:left'></span><br /><br />", "<br style='clear:left'></span><br />", $Text);

View file

@ -545,8 +545,10 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
$profile_owner = $a->profile['profile_uid'];
if (!$update) {
$tab = 'posts';
if (x($_GET, 'tab')) {
$tab = notags(trim($_GET['tab']));
$tab = ( $tab ? $tab : 'posts' );
}
if ($tab === 'posts') {
/*
* This is ugly, but we can't pass the profile_uid through the session to the ajax updater,
@ -649,20 +651,10 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
$threadsid++;
$comment = '';
$owner_url = '';
$owner_name = '';
$sparkle = '';
if ($mode === 'search' || $mode === 'community') {
if (((activity_match($item['verb'], ACTIVITY_LIKE)) || (activity_match($item['verb'], ACTIVITY_DISLIKE)))
&& ($item['id'] != $item['parent']))
continue;
$nickname = $item['nickname'];
} else {
$nickname = $a->user['nickname'];
}
// prevent private email from leaking.
if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
continue;
@ -815,7 +807,6 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
'like' => '',
'dislike' => '',
'comment' => '',
//'conv' => (($preview) ? '' : array('href'=> 'display/' . $nickname . '/' . $item['id'], 'title'=> t('View in context'))),
'conv' => (($preview) ? '' : array('href'=> 'display/'.$item['guid'], 'title'=> t('View in context'))),
'previewing' => $previewing,
'wait' => t('Please wait'),
@ -1199,10 +1190,11 @@ function format_like($cnt, array $arr, $type, $id) {
return $o;
}
function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
{
$o = '';
$geotag = (x($x, 'allow_location') ? replace_macros(get_markup_template('jot_geotag.tpl'), array()) : '');
$geotag = x($x, 'allow_location') ? replace_macros(get_markup_template('jot_geotag.tpl'), array()) : '';
$tpl = get_markup_template('jot-header.tpl');
$a->page['htmlhead'] .= replace_macros($tpl, array(
@ -1266,7 +1258,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
$o .= replace_macros($tpl,array(
'$return_path' => $query_str,
'$action' => 'item',
'$share' => (x($x,'button') ? $x['button'] : t('Share')),
'$share' => defaults($x, 'button', t('Share')),
'$upload' => t('Upload photo'),
'$shortupload' => t('upload photo'),
'$attach' => t('Attach file'),
@ -1281,26 +1273,25 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
'$shortsetloc' => t('set location'),
'$noloc' => t('Clear browser location'),
'$shortnoloc' => t('clear location'),
'$title' => $x['title'],
'$title' => defaults($x, 'title', ''),
'$placeholdertitle' => t('Set title'),
'$category' => $x['category'],
'$placeholdercategory' => (Feature::isEnabled(local_user(), 'categories') ? t('Categories (comma-separated list)') : ''),
'$category' => defaults($x, 'category', ''),
'$placeholdercategory' => Feature::isEnabled(local_user(), 'categories') ? t('Categories (comma-separated list)') : '',
'$wait' => t('Please wait'),
'$permset' => t('Permission settings'),
'$shortpermset' => t('permissions'),
'$ptyp' => (($notes_cid) ? 'note' : 'wall'),
'$content' => $x['content'],
'$post_id' => $x['post_id'],
'$ptyp' => $notes_cid ? 'note' : 'wall',
'$content' => defaults($x, 'content', ''),
'$post_id' => defaults($x, 'post_id', ''),
'$baseurl' => System::baseUrl(true),
'$defloc' => $x['default_location'],
'$visitor' => $x['visitor'],
'$pvisit' => (($notes_cid) ? 'none' : $x['visitor']),
'$pvisit' => $notes_cid ? 'none' : $x['visitor'],
'$public' => t('Public post'),
'$jotnets' => $jotnets,
'$lockstate' => $x['lockstate'],
'$bang' => $x['bang'],
'$profile_uid' => $x['profile_uid'],
'$preview' => ((Feature::isEnabled($x['profile_uid'],'preview')) ? t('Preview') : ''),
'$preview' => Feature::isEnabled($x['profile_uid'], 'preview') ? t('Preview') : '',
'$jotplugins' => $jotplugins,
'$notes_cid' => $notes_cid,
'$sourceapp' => t($a->sourcename),
@ -1579,9 +1570,9 @@ function get_responses($conv_responses, $response_verbs, $ob, $item) {
$ret = array();
foreach ($response_verbs as $v) {
$ret[$v] = array();
$ret[$v]['count'] = ((x($conv_responses[$v], $item['uri'])) ? $conv_responses[$v][$item['uri']] : '');
$ret[$v]['list'] = ((x($conv_responses[$v], $item['uri'])) ? $conv_responses[$v][$item['uri'] . '-l'] : '');
$ret[$v]['self'] = ((x($conv_responses[$v], $item['uri'])) ? $conv_responses[$v][$item['uri'] . '-self'] : '0');
$ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], '');
$ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', '');
$ret[$v]['self'] = defaults($conv_responses[$v], $item['uri'] . '-self', '0');
if (count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'

View file

@ -1,172 +0,0 @@
<?php
use Friendica\Core\Config;
require_once 'library/ASNValue.class.php';
require_once 'library/asn1.php';
// supported algorithms are 'sha256', 'sha1'
function rsa_sign($data, $key, $alg = 'sha256') {
openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
return $sig;
}
function rsa_verify($data, $sig, $key, $alg = 'sha256') {
return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
}
function DerToPem($Der, $Private = false) {
//Encode:
$Der = base64_encode($Der);
//Split lines:
$lines = str_split($Der, 65);
$body = implode("\n", $lines);
//Get title:
$title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
//Add wrapping:
$result = "-----BEGIN {$title}-----\n";
$result .= $body . "\n";
$result .= "-----END {$title}-----\n";
return $result;
}
function DerToRsa($Der) {
//Encode:
$Der = base64_encode($Der);
//Split lines:
$lines = str_split($Der, 64);
$body = implode("\n", $lines);
//Get title:
$title = 'RSA PUBLIC KEY';
//Add wrapping:
$result = "-----BEGIN {$title}-----\n";
$result .= $body . "\n";
$result .= "-----END {$title}-----\n";
return $result;
}
function pkcs8_encode($Modulus, $PublicExponent) {
//Encode key sequence
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
$modulus->SetIntBuffer($Modulus);
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
$publicExponent->SetIntBuffer($PublicExponent);
$keySequenceItems = array($modulus, $publicExponent);
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
$keySequence->SetSequence($keySequenceItems);
//Encode bit string
$bitStringValue = $keySequence->Encode();
$bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte
$bitString = new ASNValue(ASNValue::TAG_BITSTRING);
$bitString->Value = $bitStringValue;
//Encode body
$bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode();
$body = new ASNValue(ASNValue::TAG_SEQUENCE);
$body->Value = $bodyValue;
//Get DER encoded public key:
$PublicDER = $body->Encode();
return $PublicDER;
}
function pkcs1_encode($Modulus, $PublicExponent) {
//Encode key sequence
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
$modulus->SetIntBuffer($Modulus);
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
$publicExponent->SetIntBuffer($PublicExponent);
$keySequenceItems = array($modulus, $publicExponent);
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
$keySequence->SetSequence($keySequenceItems);
//Encode bit string
$bitStringValue = $keySequence->Encode();
return $bitStringValue;
}
function metopem($m, $e) {
$der = pkcs8_encode($m, $e);
$key = DerToPem($der, false);
return $key;
}
function pubrsatome($key, &$m, &$e)
{
require_once 'library/asn1.php';
$lines = explode("\n", $key);
unset($lines[0]);
unset($lines[count($lines)]);
$x = base64_decode(implode('', $lines));
$r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData);
}
function rsatopem($key) {
pubrsatome($key, $m, $e);
return metopem($m, $e);
}
function pemtorsa($key) {
pemtome($key, $m, $e);
return metorsa($m, $e);
}
function pemtome($key, &$m, &$e)
{
$lines = explode("\n", $key);
unset($lines[0]);
unset($lines[count($lines)]);
$x = base64_decode(implode('', $lines));
$r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
}
function metorsa($m, $e) {
$der = pkcs1_encode($m, $e);
$key = DerToRsa($der);
return $key;
}
function salmon_key($pubkey) {
pemtome($pubkey, $m, $e);
return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true) ;
}
function new_keypair($bits) {
$openssl_options = array(
'digest_alg' => 'sha1',
'private_key_bits' => $bits,
'encrypt_key' => false
);
$conf = Config::get('system', 'openssl_conf_file');
if ($conf) {
$openssl_options['config'] = $conf;
}
$result = openssl_pkey_new($openssl_options);
if (empty($result)) {
logger('new_keypair: failed');
return false;
}
// Get private key
$response = array('prvkey' => '', 'pubkey' => '');
openssl_pkey_export($result, $response['prvkey']);
// Get public key
$pkey = openssl_pkey_get_details($result);
$response['pubkey'] = $pkey["key"];
return $response;
}

View file

@ -13,7 +13,7 @@ use Friendica\Util\Map;
require_once 'include/bbcode.php';
require_once 'include/datetime.php';
require_once "include/conversation.php";
require_once 'include/conversation.php';
function format_event_html($ev, $simple = false) {
if (! ((is_array($ev)) && count($ev))) {
@ -626,6 +626,9 @@ function process_events($arr) {
// Show edit and drop actions only if the user is the owner of the event and the event
// is a real event (no bithdays).
$edit = null;
$copy = null;
$drop = null;
if (local_user() && local_user() == $rr['uid'] && $rr['type'] == 'event') {
$edit = ((! $rr['cid']) ? array(System::baseUrl() . '/events/event/' . $rr['id'], t('Edit event'), '', '') : null);
$copy = ((! $rr['cid']) ? array(System::baseUrl() . '/events/copy/' . $rr['id'], t('Duplicate event'), '', '') : null);

View file

@ -1,8 +1,8 @@
<?php
/**
* @file include/identity.php
*/
use Friendica\App;
use Friendica\Content\Feature;
use Friendica\Content\ForumManager;
@ -41,21 +41,34 @@ require_once 'mod/proxy.php';
* @param string $nickname string
* @param int $profile int
* @param array $profiledata array
* @param boolean $show_connect Show connect link
*/
function profile_load(App $a, $nickname, $profile = 0, $profiledata = array())
function profile_load(App $a, $nickname, $profile = 0, $profiledata = array(), $show_connect = true)
{
$user = q(
"SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname)
);
if (!$user && count($user) && !count($profiledata)) {
if (!$user && !count($user) && !count($profiledata)) {
logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
notice(t('Requested account is not available.') . EOL);
$a->error = 404;
return;
}
if (!x($a->page, 'aside')) {
$a->page['aside'] = '';
}
if ($profiledata) {
$a->page['aside'] .= profile_sidebar($profiledata, true, $show_connect);
if (!DBM::is_result($user)) {
return;
}
}
$pdata = get_profiledata_by_nick($nickname, $user[0]['uid'], $profile);
if (empty($pdata) && empty($profiledata)) {
@ -72,9 +85,10 @@ function profile_load(App $a, $nickname, $profile = 0, $profiledata = array())
"SELECT `pub_keywords` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
intval($pdata['profile_uid'])
);
if ($x && count($x))
if ($x && count($x)) {
$pdata['pub_keywords'] = $x[0]['pub_keywords'];
}
}
$a->profile = $pdata;
$a->profile_uid = $pdata['profile_uid'];
@ -82,7 +96,7 @@ function profile_load(App $a, $nickname, $profile = 0, $profiledata = array())
$a->profile['mobile-theme'] = PConfig::get($a->profile['profile_uid'], 'system', 'mobile_theme');
$a->profile['network'] = NETWORK_DFRN;
$a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename'];
$a->page['title'] = $a->profile['name'] . ' @ ' . $a->config['sitename'];
if (!$profiledata && !PConfig::get(local_user(), 'system', 'always_my_theme')) {
$_SESSION['theme'] = $a->profile['theme'];
@ -96,45 +110,38 @@ function profile_load(App $a, $nickname, $profile = 0, $profiledata = array())
$a->set_template_engine(); // reset the template engine to the default in case the user's theme doesn't specify one
$theme_info_file = "view/theme/" . current_theme() . "/theme.php";
$theme_info_file = 'view/theme/' . current_theme() . '/theme.php';
if (file_exists($theme_info_file)) {
require_once $theme_info_file;
}
if (! (x($a->page, 'aside'))) {
if (!x($a->page, 'aside')) {
$a->page['aside'] = '';
}
if (local_user() && local_user() == $a->profile['uid'] && $profiledata) {
$a->page['aside'] .= replace_macros(
get_markup_template('profile_edlink.tpl'),
array(
get_markup_template('profile_edlink.tpl'), array(
'$editprofile' => t('Edit profile'),
'$profid' => $a->profile['id']
)
);
}
$block = (((Config::get('system', 'block_public')) && (! local_user()) && (! remote_user())) ? true : false);
$block = ((Config::get('system', 'block_public') && !local_user() && !remote_user()) ? true : false);
/**
* @todo
* By now, the contact block isn't shown, when a different profile is given
* But: When this profile was on the same server, then we could display the contacts
*/
if ($profiledata) {
$a->page['aside'] .= profile_sidebar($profiledata, true);
} else {
$a->page['aside'] .= profile_sidebar($a->profile, $block);
if (!$profiledata) {
$a->page['aside'] .= profile_sidebar($a->profile, $block, $show_connect);
}
/*if (! $block)
$a->page['aside'] .= contact_block();*/
return;
}
/**
* @brief Get all profil data of a local user
*
@ -143,11 +150,12 @@ function profile_load(App $a, $nickname, $profile = 0, $profiledata = array())
* Passing a non-zero profile ID can also allow a preview of a selected profile
* by the owner
*
* Includes all available profile data
*
* @param string $nickname nick
* @param int $uid uid
* @param int $profile ID of the profile
* @returns array
* Includes all available profile data
*/
function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
{
@ -197,7 +205,6 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
return $r;
}
/**
* @brief Formats a profile for display in the sidebar.
*
@ -206,6 +213,7 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
*
* @param array $profile
* @param int $block
* @param boolean $show_connect Show connect link
*
* @return HTML string stuitable for sidebar inclusion
*
@ -216,35 +224,34 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
* @hooks 'profile_sidebar'
* array $arr
*/
function profile_sidebar($profile, $block = 0)
function profile_sidebar($profile, $block = 0, $show_connect = true)
{
$a = get_app();
$o = '';
$location = false;
$address = false;
// $pdesc = true;
// This function can also use contact information in $profile
$is_contact = x($profile, 'cid');
if ((! is_array($profile)) && (! count($profile))) {
if (!is_array($profile) && !count($profile)) {
return $o;
}
$profile['picdate'] = urlencode($profile['picdate']);
$profile['picdate'] = urlencode(defaults($profile, 'picdate', ''));
if (($profile['network'] != "") && ($profile['network'] != NETWORK_DFRN)) {
if (($profile['network'] != '') && ($profile['network'] != NETWORK_DFRN)) {
$profile['network_name'] = format_network_name($profile['network'], $profile['url']);
} else {
$profile['network_name'] = "";
$profile['network_name'] = '';
}
call_hooks('profile_sidebar_enter', $profile);
// don't show connect link to yourself
$connect = (($profile['uid'] != local_user()) ? t('Connect') : false);
$connect = $profile['uid'] != local_user() ? t('Connect') : false;
// don't show connect link to authenticated visitors either
if (remote_user() && count($_SESSION['remote'])) {
@ -256,12 +263,16 @@ function profile_sidebar($profile, $block = 0)
}
}
if (!$show_connect) {
$connect = false;
}
// Is the local user already connected to that user?
if ($connect && local_user()) {
if (isset($profile["url"])) {
$profile_url = normalise_link($profile["url"]);
if (isset($profile['url'])) {
$profile_url = normalise_link($profile['url']);
} else {
$profile_url = normalise_link(System::baseUrl()."/profile/".$profile["nickname"]);
$profile_url = normalise_link(System::baseUrl() . '/profile/' . $profile['nickname']);
}
if (dba::exists('contact', array('pending' => false, 'uid' => local_user(), 'nurl' => $profile_url))) {
@ -269,21 +280,24 @@ function profile_sidebar($profile, $block = 0)
}
}
if ($connect && ($profile['network'] != NETWORK_DFRN) && !isset($profile['remoteconnect']))
if ($connect && ($profile['network'] != NETWORK_DFRN) && !isset($profile['remoteconnect'])) {
$connect = false;
}
$remoteconnect = null;
if (isset($profile['remoteconnect']))
if (isset($profile['remoteconnect'])) {
$remoteconnect = $profile['remoteconnect'];
}
if ($connect && ($profile['network'] == NETWORK_DFRN) && !isset($remoteconnect))
$subscribe_feed = t("Atom feed");
else
if ($connect && ($profile['network'] == NETWORK_DFRN) && !isset($remoteconnect)) {
$subscribe_feed = t('Atom feed');
} else {
$subscribe_feed = false;
}
if (remote_user() || (get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))) {
if (remote_user() || (get_my_url() && x($profile, 'unkmail') && ($profile['uid'] != local_user()))) {
$wallmessage = t('Message');
$wallmessage_link = "wallmessage/".$profile["nickname"];
$wallmessage_link = 'wallmessage/' . $profile['nickname'];
if (remote_user()) {
$r = q(
@ -301,9 +315,9 @@ function profile_sidebar($profile, $block = 0)
);
}
if ($r) {
$remote_url = $r[0]["url"];
$message_path = preg_replace("=(.*)/profile/(.*)=ism", "$1/message/new/", $remote_url);
$wallmessage_link = $message_path.base64_encode($profile["addr"]);
$remote_url = $r[0]['url'];
$message_path = preg_replace('=(.*)/profile/(.*)=ism', '$1/message/new/', $remote_url);
$wallmessage_link = $message_path . base64_encode($profile['addr']);
}
} else {
$wallmessage = false;
@ -312,7 +326,7 @@ function profile_sidebar($profile, $block = 0)
// show edit profile to yourself
if (!$is_contact && $profile['uid'] == local_user() && Feature::isEnabled(local_user(), 'multi_profiles')) {
$profile['edit'] = array(System::baseUrl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles'));
$profile['edit'] = array(System::baseUrl() . '/profiles', t('Profiles'), '', t('Manage/edit profiles'));
$r = q(
"SELECT * FROM `profile` WHERE `uid` = %d",
local_user()
@ -339,7 +353,7 @@ function profile_sidebar($profile, $block = 0)
}
}
if (!$is_contact && $profile['uid'] == local_user() && !Feature::isEnabled(local_user(), 'multi_profiles')) {
$profile['edit'] = array(System::baseUrl(). '/profiles/'.$profile['id'], t('Edit profile'),"", t('Edit profile'));
$profile['edit'] = array(System::baseUrl() . '/profiles/' . $profile['id'], t('Edit profile'), '', t('Edit profile'));
$profile['menu'] = array(
'chg_photo' => t('Change profile photo'),
'cr_new' => null,
@ -350,28 +364,23 @@ function profile_sidebar($profile, $block = 0)
// Fetch the account type
$account_type = Contact::getAccountType($profile);
if ((x($profile, 'address') == 1)
|| (x($profile, 'location') == 1)
|| (x($profile, 'locality') == 1)
|| (x($profile, 'region') == 1)
|| (x($profile, 'postal-code') == 1)
|| (x($profile, 'country-name') == 1)
if (x($profile, 'address')
|| x($profile, 'location')
|| x($profile, 'locality')
|| x($profile, 'region')
|| x($profile, 'postal-code')
|| x($profile, 'country-name')
) {
$location = t('Location:');
}
$gender = ((x($profile, 'gender') == 1) ? t('Gender:') : false);
$gender = x($profile, 'gender') ? t('Gender:') : false;
$marital = x($profile, 'marital') ? t('Status:') : false;
$homepage = x($profile, 'homepage') ? t('Homepage:') : false;
$about = x($profile, 'about') ? t('About:') : false;
$xmpp = x($profile, 'xmpp') ? t('XMPP:') : false;
$marital = ((x($profile, 'marital') == 1) ? t('Status:') : false);
$homepage = ((x($profile, 'homepage') == 1) ? t('Homepage:') : false);
$about = ((x($profile, 'about') == 1) ? t('About:') : false);
$xmpp = ((x($profile, 'xmpp') == 1) ? t('XMPP:') : false);
if (($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) {
if ((x($profile, 'hidewall') || $block) && !local_user() && !remote_user()) {
$location = $pdesc = $gender = $marital = $homepage = $about = false;
}
@ -379,7 +388,7 @@ function profile_sidebar($profile, $block = 0)
$firstname = $split_name['first'];
$lastname = $split_name['last'];
if ($profile['guid'] != "") {
if (x($profile, 'guid')) {
$diaspora = array(
'guid' => $profile['guid'],
'podloc' => System::baseUrl(),
@ -396,6 +405,9 @@ function profile_sidebar($profile, $block = 0)
$diaspora = false;
}
$contact_block = '';
$updated = '';
$contacts = 0;
if (!$block) {
$contact_block = contact_block();
@ -405,7 +417,7 @@ function profile_sidebar($profile, $block = 0)
intval($a->profile['uid'])
);
if (DBM::is_result($r)) {
$updated = date("c", strtotime($r[0]['updated']));
$updated = date('c', strtotime($r[0]['updated']));
}
$r = q(
@ -431,24 +443,22 @@ function profile_sidebar($profile, $block = 0)
$p[$k] = $v;
}
if (isset($p["about"])) {
$p["about"] = bbcode($p["about"]);
if (isset($p['about'])) {
$p['about'] = bbcode($p['about']);
}
if (isset($p["address"])) {
$p["address"] = bbcode($p["address"]);
if (isset($p['address'])) {
$p['address'] = bbcode($p['address']);
} else {
$p["address"] = bbcode($p["location"]);
$p['address'] = bbcode($p['location']);
}
if (isset($p["photo"])) {
$p["photo"] = proxy_url($p["photo"], false, PROXY_SIZE_SMALL);
if (isset($p['photo'])) {
$p['photo'] = proxy_url($p['photo'], false, PROXY_SIZE_SMALL);
}
$tpl = get_markup_template('profile_vcard.tpl');
$o .= replace_macros(
$tpl,
array(
$o .= replace_macros($tpl, array(
'$profile' => $p,
'$xmpp' => $xmpp,
'$connect' => $connect,
@ -459,7 +469,6 @@ function profile_sidebar($profile, $block = 0)
'$account_type' => $account_type,
'$location' => $location,
'$gender' => $gender,
// '$pdesc' => $pdesc,
'$marital' => $marital,
'$homepage' => $homepage,
'$about' => $about,
@ -468,8 +477,7 @@ function profile_sidebar($profile, $block = 0)
'$updated' => $updated,
'$diaspora' => $diaspora,
'$contact_block' => $contact_block,
)
);
));
$arr = array('profile' => &$profile, 'entry' => &$o);
@ -478,7 +486,6 @@ function profile_sidebar($profile, $block = 0)
return $o;
}
function get_birthdays()
{
$a = get_app();
@ -498,7 +505,7 @@ function get_birthdays()
$bd_format = t('g A l F d'); // 8 AM Friday January 18
$bd_short = t('F d');
$cachekey = "get_birthdays:".local_user();
$cachekey = 'get_birthdays:' . local_user();
$r = Cache::get($cachekey);
if (is_null($r)) {
$s = dba::p(
@ -547,7 +554,7 @@ function get_birthdays()
$sparkle = '';
$url = $rr['url'];
if ($rr['network'] === NETWORK_DFRN) {
$sparkle = " sparkle";
$sparkle = ' sparkle';
$url = System::baseUrl() . '/redir/' . $rr['cid'];
}
@ -559,10 +566,8 @@ function get_birthdays()
}
}
}
$tpl = get_markup_template("birthdays_reminder.tpl");
return replace_macros(
$tpl,
array(
$tpl = get_markup_template('birthdays_reminder.tpl');
return replace_macros($tpl, array(
'$baseurl' => System::baseUrl(),
'$classtoday' => $classtoday,
'$count' => $total,
@ -571,11 +576,9 @@ function get_birthdays()
'$events' => $r,
'$lbr' => '{', // raw brackets mess up if/endif macro processing
'$rbr' => '}'
)
);
));
}
function get_events()
{
require_once 'include/bbcode.php';
@ -594,7 +597,7 @@ function get_events()
*/
$bd_format = t('g A l F d'); // 8 AM Friday January 18
$bd_short = t('F d');
$classtoday = '';
$s = dba::p(
"SELECT `event`.* FROM `event`
@ -608,7 +611,6 @@ function get_events()
$r = array();
if (DBM::is_result($s)) {
$now = strtotime('now');
$istoday = false;
while ($rr = dba::fetch($s)) {
@ -641,7 +643,7 @@ function get_events()
$today = ((substr($strt, 0, 10) === datetime_convert('UTC', $a->timezone, 'now', 'Y-m-d')) ? true : false);
$rr['title'] = $title;
$rr['description'] = $desciption;
$rr['description'] = $description;
$rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? $a->timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
$rr['startime'] = $strt;
$rr['today'] = $today;
@ -651,18 +653,15 @@ function get_events()
dba::close($s);
$classtoday = (($istoday) ? 'event-today' : '');
}
$tpl = get_markup_template("events_reminder.tpl");
return replace_macros(
$tpl,
array(
$tpl = get_markup_template('events_reminder.tpl');
return replace_macros($tpl, array(
'$baseurl' => System::baseUrl(),
'$classtoday' => $classtoday,
'$count' => count($r),
'$event_reminders' => t('Event Reminders'),
'$event_title' => t('Events this week:'),
'$events' => $r,
)
);
));
}
function advanced_profile(App $a)
@ -671,8 +670,7 @@ function advanced_profile(App $a)
$uid = $a->profile['uid'];
$o .= replace_macros(
get_markup_template('section_title.tpl'),
array(
get_markup_template('section_title.tpl'), array(
'$title' => t('Profile')
)
);
@ -692,13 +690,13 @@ function advanced_profile(App $a)
$year_bd_format = t('j F, Y');
$short_bd_format = t('j F');
$val = ((intval($a->profile['dob']))
? day_translate(datetime_convert('UTC', 'UTC', $a->profile['dob'] . ' 00:00 +00:00', $year_bd_format))
: day_translate(datetime_convert('UTC', 'UTC', '2001-' . substr($a->profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format)));
$val = intval($a->profile['dob']) ?
day_translate(datetime_convert('UTC', 'UTC', $a->profile['dob'] . ' 00:00 +00:00', $year_bd_format))
: day_translate(datetime_convert('UTC', 'UTC', '2001-' . substr($a->profile['dob'], 5) . ' 00:00 +00:00', $short_bd_format));
$profile['birthday'] = array(t('Birthday:'), $val);
}
if (!empty($a->profile['dob'])
&& $a->profile['dob'] > '0001-01-01'
&& $age = age($a->profile['dob'], $a->profile['timezone'], '')
@ -797,18 +795,15 @@ function advanced_profile(App $a)
}
if ($a->profile['uid'] == local_user()) {
$profile['edit'] = array(System::baseUrl(). '/profiles/'.$a->profile['id'], t('Edit profile'),"", t('Edit profile'));
$profile['edit'] = array(System::baseUrl() . '/profiles/' . $a->profile['id'], t('Edit profile'), '', t('Edit profile'));
}
return replace_macros(
$tpl,
array(
return replace_macros($tpl, array(
'$title' => t('Profile'),
'$basic' => t('Basic'),
'$advanced' => t('Advanced'),
'$profile' => $profile
)
);
));
}
return '';
@ -816,12 +811,11 @@ function advanced_profile(App $a)
function profile_tabs($a, $is_owner = false, $nickname = null)
{
//echo "<pre>"; var_dump($a->user); killme();
if (is_null($nickname)) {
$nickname = $a->user['nickname'];
}
$tab = false;
if (x($_GET, 'tab')) {
$tab = notags(trim($_GET['tab']));
}
@ -832,7 +826,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
array(
'label' => t('Status'),
'url' => $url,
'sel' => ((!isset($tab) && $a->argv[0]=='profile') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'profile' ? 'active' : '',
'title' => t('Status Messages and Posts'),
'id' => 'status-tab',
'accesskey' => 'm',
@ -840,7 +834,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
array(
'label' => t('Profile'),
'url' => $url . '/?tab=profile',
'sel' => ((isset($tab) && $tab=='profile') ? 'active' : ''),
'sel' => $tab == 'profile' ? 'active' : '',
'title' => t('Profile Details'),
'id' => 'profile-tab',
'accesskey' => 'r',
@ -848,7 +842,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
array(
'label' => t('Photos'),
'url' => System::baseUrl() . '/photos/' . $nickname,
'sel' => ((!isset($tab) && $a->argv[0]=='photos') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'photos' ? 'active' : '',
'title' => t('Photo Albums'),
'id' => 'photo-tab',
'accesskey' => 'h',
@ -856,7 +850,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
array(
'label' => t('Videos'),
'url' => System::baseUrl() . '/videos/' . $nickname,
'sel' => ((!isset($tab) && $a->argv[0]=='videos') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'videos' ? 'active' : '',
'title' => t('Videos'),
'id' => 'video-tab',
'accesskey' => 'v',
@ -868,7 +862,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
$tabs[] = array(
'label' => t('Events'),
'url' => System::baseUrl() . '/events',
'sel' =>((!isset($tab) && $a->argv[0]=='events') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'events' ? 'active' : '',
'title' => t('Events and Calendar'),
'id' => 'events-tab',
'accesskey' => 'e',
@ -879,7 +873,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
$tabs[] = array(
'label' => t('Events'),
'url' => System::baseUrl() . '/cal/' . $nickname,
'sel' =>((!isset($tab) && $a->argv[0]=='cal') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'cal' ? 'active' : '',
'title' => t('Events and Calendar'),
'id' => 'events-tab',
'accesskey' => 'e',
@ -890,7 +884,7 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
$tabs[] = array(
'label' => t('Personal Notes'),
'url' => System::baseUrl() . '/notes',
'sel' =>((!isset($tab) && $a->argv[0]=='notes') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'notes' ? 'active' : '',
'title' => t('Only You Can See This'),
'id' => 'notes-tab',
'accesskey' => 't',
@ -901,14 +895,14 @@ function profile_tabs($a, $is_owner = false, $nickname = null)
$tabs[] = array(
'label' => t('Contacts'),
'url' => System::baseUrl() . '/viewcontacts/' . $nickname,
'sel' => ((!isset($tab) && $a->argv[0]=='viewcontacts') ? 'active' : ''),
'sel' => !$tab && $a->argv[0] == 'viewcontacts' ? 'active' : '',
'title' => t('Contacts'),
'id' => 'viewcontacts-tab',
'accesskey' => 'k',
);
}
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => $tab, 'tabs' => $tabs);
call_hooks('profile_tabs', $arr);
$tpl = get_markup_template('common_tabs.tpl');
@ -932,9 +926,9 @@ function zrl_init(App $a)
// The check fetches the cached value from gprobe to reduce the load for this system
$urlparts = parse_url($tmp_str);
$result = Cache::get("gprobe:" . $urlparts["host"]);
if ((!is_null($result)) && (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))) {
logger("DDoS attempt detected for " . $urlparts["host"] . " by " . $_SERVER["REMOTE_ADDR"] . ". server data: " . print_r($_SERVER, true), LOGGER_DEBUG);
$result = Cache::get('gprobe:' . $urlparts['host']);
if ((!is_null($result)) && (in_array($result['network'], array(NETWORK_FEED, NETWORK_PHANTOM)))) {
logger('DDoS attempt detected for ' . $urlparts['host'] . ' by ' . $_SERVER['REMOTE_ADDR'] . '. server data: ' . print_r($_SERVER, true), LOGGER_DEBUG);
return;
}

View file

@ -20,8 +20,6 @@ use Friendica\Protocol\OStatus;
use Friendica\Protocol\Feed;
require_once 'include/bbcode.php';
require_once 'include/oembed.php';
require_once 'include/crypto.php';
require_once 'include/tags.php';
require_once 'include/files.php';
require_once 'include/text.php';
@ -423,7 +421,7 @@ function uri_to_guid($uri, $host = "") {
* @return array Item array with removed conversation data
*/
function store_conversation($arr) {
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)) && !empty($arr['uri'])) {
if (in_array(defaults($arr, 'network', NETWORK_PHANTOM), array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)) && !empty($arr['uri'])) {
$conversation = array('item-uri' => $arr['uri'], 'received' => DBM::date());
if (isset($arr['parent-uri']) && ($arr['parent-uri'] != $arr['uri'])) {
@ -481,8 +479,8 @@ function store_conversation($arr) {
}
/// @TODO add type-hint array
function item_store($arr, $force_parent = false, $notify = false, $dontcache = false) {
function item_store($arr, $force_parent = false, $notify = false, $dontcache = false)
{
$a = get_app();
// If it is a posting where users should get notifications, then define it as wall posting
@ -504,6 +502,8 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
$arr['guid'] = uri_to_guid($arr['uri'], $a->get_hostname());
}
}
} else {
$arr['network'] = trim(defaults($arr, 'network', NETWORK_PHANTOM));
}
if ($notify) {
@ -583,7 +583,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
* We have to check several networks since Friendica posts could be repeated
* via OStatus (maybe Diasporsa as well)
*/
if (in_array(trim($arr['network']), array(NETWORK_DIASPORA, NETWORK_DFRN, NETWORK_OSTATUS, ""))) {
if (in_array($arr['network'], array(NETWORK_DIASPORA, NETWORK_DFRN, NETWORK_OSTATUS, ""))) {
$r = q("SELECT `id`, `network` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` IN ('%s', '%s', '%s') LIMIT 1",
dbesc(trim($arr['uri'])),
intval($uid),
@ -646,7 +646,6 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
$arr['attach'] = ((x($arr, 'attach')) ? notags(trim($arr['attach'])) : '');
$arr['app'] = ((x($arr, 'app')) ? notags(trim($arr['app'])) : '');
$arr['origin'] = ((x($arr, 'origin')) ? intval($arr['origin']) : 0 );
$arr['network'] = ((x($arr, 'network')) ? trim($arr['network']) : '');
$arr['postopts'] = ((x($arr, 'postopts')) ? trim($arr['postopts']) : '');
$arr['resource-id'] = ((x($arr, 'resource-id')) ? trim($arr['resource-id']) : '');
$arr['event-id'] = ((x($arr, 'event-id')) ? intval($arr['event-id']) : 0 );
@ -676,18 +675,19 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
$arr['plink'] = System::baseUrl() . '/display/' . urlencode($arr['guid']);
}
if ($arr['network'] == "") {
if ($arr['network'] == NETWORK_PHANTOM) {
$r = q("SELECT `network` FROM `contact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
dbesc(normalise_link($arr['author-link'])),
intval($arr['uid'])
);
if (!DBM::is_result($r))
if (!DBM::is_result($r)) {
$r = q("SELECT `network` FROM `gcontact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' LIMIT 1",
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
dbesc(normalise_link($arr['author-link']))
);
}
if (!DBM::is_result($r)) {
$r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
@ -735,7 +735,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
logger("Contact-id was missing for post ".$arr["guid"]." from user id ".$uid." - now set to ".$arr["contact-id"], LOGGER_DEBUG);
}
if ($arr["gcontact-id"] == 0) {
if (!x($arr, "gcontact-id")) {
/*
* The gcontact should mostly behave like the contact. But is is supposed to be global for the system.
* This means that wall posts, repeated posts, etc. should have the gcontact id of the owner.

View file

@ -79,22 +79,27 @@ function do_like($item_id, $verb) {
}
$item = $items[0];
$uid = $item['uid'];
if (! can_write_wall($a, $item['uid'])) {
logger('like: unable to write on wall ' . $item['uid']);
if (($uid == 0) && local_user()) {
$uid = local_user();
}
if (!can_write_wall($a, $uid)) {
logger('like: unable to write on wall ' . $uid);
return false;
}
// Retrieves the local post owner
$owners = q("SELECT `contact`.* FROM `contact`
WHERE `contact`.`self` = 1
WHERE `contact`.`self`
AND `contact`.`uid` = %d",
intval($item['uid'])
intval($uid)
);
if (DBM::is_result($owners)) {
$owner_self_contact = $owners[0];
} else {
logger('like: unknown owner ' . $item['uid']);
logger('like: unknown owner ' . $uid);
return false;
}
@ -112,11 +117,11 @@ function do_like($item_id, $verb) {
}
// Contact-id is the uid-dependant author contact
if (local_user() == $item['uid']) {
if (local_user() == $uid) {
$item_contact_id = $owner_self_contact['id'];
$item_contact = $owner_self_contact;
} else {
$item_contact_id = Contact::getIdForURL($author_contact['url'], $item['uid']);
$item_contact_id = Contact::getIdForURL($author_contact['url'], $uid);
$contacts = q("SELECT * FROM `contact` WHERE `id` = %d",
intval($item_contact_id)
@ -240,9 +245,8 @@ EOT;
// @todo: Explain this block
if (! $item['visible']) {
q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d",
intval($item['id']),
intval($item['uid'])
q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
intval($item['id'])
);
}

View file

@ -1,317 +0,0 @@
<?php
/**
* @file include/oembed.php
*/
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\System;
use Friendica\ParseUrl;
use Friendica\Core\Config;
use Friendica\Database\DBM;
function oembed_replacecb($matches){
$embedurl=$matches[1];
$j = oembed_fetch_url($embedurl);
$s = oembed_format_object($j);
return $s;
}
/**
* @brief Get data from an URL to embed its content.
*
* @param string $embedurl The URL from which the data should be fetched.
* @param bool $no_rich_type If set to true rich type content won't be fetched.
*
* @return bool|object Returns object with embed content or false if no embedable
* content exists
*/
function oembed_fetch_url($embedurl, $no_rich_type = false) {
$embedurl = trim($embedurl, "'");
$embedurl = trim($embedurl, '"');
$a = get_app();
$condition = array('url' => normalise_link($embedurl));
$r = dba::select('oembed', array('content'), $condition, array('limit' => 1));
if (DBM::is_result($r)) {
$txt = $r["content"];
} else {
$txt = Cache::get($a->videowidth . $embedurl);
}
// These media files should now be caught in bbcode.php
// left here as a fallback in case this is called from another source
$noexts = array("mp3", "mp4", "ogg", "ogv", "oga", "ogm", "webm");
$ext = pathinfo(strtolower($embedurl), PATHINFO_EXTENSION);
if (is_null($txt)) {
$txt = "";
if (!in_array($ext, $noexts)){
// try oembed autodiscovery
$redirects = 0;
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*");
if ($html_text) {
$dom = @DOMDocument::loadHTML($html_text);
if ($dom) {
$xpath = new DOMXPath($dom);
$attr = "oembed";
$xattr = oe_build_xpath("class","oembed");
$entries = $xpath->query("//link[@type='application/json+oembed']");
foreach ($entries as $e) {
$href = $e->getAttributeNode("href")->nodeValue;
$txt = fetch_url($href . '&maxwidth=' . $a->videowidth);
break;
}
$entries = $xpath->query("//link[@type='text/json+oembed']");
foreach ($entries as $e) {
$href = $e->getAttributeNode("href")->nodeValue;
$txt = fetch_url($href . '&maxwidth=' . $a->videowidth);
break;
}
}
}
}
$txt = trim($txt);
if ($txt[0] != "{") {
$txt = '{"type":"error"}';
} else { //save in cache
$j = json_decode($txt);
if ($j->type != "error") {
dba::insert('oembed', array('url' => normalise_link($embedurl),
'content' => $txt, 'created' => datetime_convert()), true);
}
Cache::set($a->videowidth.$embedurl, $txt, CACHE_DAY);
}
}
$j = json_decode($txt);
if (!is_object($j)) {
return false;
}
// Always embed the SSL version
if (isset($j->html)) {
$j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html);
}
$j->embedurl = $embedurl;
// If fetching information doesn't work, then improve via internal functions
if (($j->type == "error") || ($no_rich_type && ($j->type == "rich"))) {
$data = ParseUrl::getSiteinfoCached($embedurl, true, false);
$j->type = $data["type"];
if ($j->type == "photo") {
$j->url = $data["url"];
//$j->width = $data["images"][0]["width"];
//$j->height = $data["images"][0]["height"];
}
if (isset($data["title"])) {
$j->title = $data["title"];
}
if (isset($data["text"])) {
$j->description = $data["text"];
}
if (is_array($data["images"])) {
$j->thumbnail_url = $data["images"][0]["src"];
$j->thumbnail_width = $data["images"][0]["width"];
$j->thumbnail_height = $data["images"][0]["height"];
}
}
call_hooks('oembed_fetch_url', $embedurl, $j);
return $j;
}
function oembed_format_object($j){
require_once("mod/proxy.php");
$embedurl = $j->embedurl;
$jhtml = oembed_iframe($j->embedurl,(isset($j->width) ? $j->width : null), (isset($j->height) ? $j->height : null) );
$ret="<span class='oembed ".$j->type."'>";
switch ($j->type) {
case "video":
if (isset($j->thumbnail_url)) {
$tw = (isset($j->thumbnail_width) && intval($j->thumbnail_width)) ? $j->thumbnail_width:200;
$th = (isset($j->thumbnail_height) && intval($j->thumbnail_height)) ? $j->thumbnail_height:180;
// make sure we don't attempt divide by zero, fallback is a 1:1 ratio
$tr = (($th) ? $tw/$th : 1);
$th=120; $tw = $th*$tr;
$tpl=get_markup_template('oembed_video.tpl');
$ret.=replace_macros($tpl, array(
'$baseurl' => System::baseUrl(),
'$embedurl' => $embedurl,
'$escapedhtml' => base64_encode($jhtml),
'$tw' => $tw,
'$th' => $th,
'$turl' => $j->thumbnail_url,
));
} else {
$ret=$jhtml;
}
//$ret.="<br>";
break;
case "photo":
$ret.= "<img width='".$j->width."' src='".proxy_url($j->url)."'>";
break;
case "link":
break;
case "rich":
// not so safe..
if (!Config::get("system","no_oembed_rich_content")) {
$ret.= proxy_parse_html($jhtml);
}
break;
}
// add link to source if not present in "rich" type
if ($j->type!='rich' || !strpos($j->html,$embedurl) ){
$ret .= "<h4>";
if (isset($j->title)) {
if (isset($j->provider_name)) {
$ret .= $j->provider_name.": ";
}
$embedlink = (isset($j->title))?$j->title:$embedurl;
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
if (isset($j->author_name)) {
$ret.=" (".$j->author_name.")";
}
} elseif (isset($j->provider_name) || isset($j->author_name)) {
$embedlink = "";
if (isset($j->provider_name)) {
$embedlink .= $j->provider_name;
}
if (isset($j->author_name)) {
if ($embedlink != "") {
$embedlink .= ": ";
}
$embedlink .= $j->author_name;
}
if (trim($embedlink) == "") {
$embedlink = $embedurl;
}
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
}
//if (isset($j->author_name)) $ret.=" by ".$j->author_name;
//if (isset($j->provider_name)) $ret.=" on ".$j->provider_name;
$ret .= "</h4>";
} else {
// add <a> for html2bbcode conversion
$ret .= "<a href='$embedurl' rel='oembed'>$embedurl</a>";
}
$ret.="</span>";
$ret = str_replace("\n","",$ret);
return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
}
/**
* @brief Generates the iframe HTML for an oembed attachment.
*
* Width and height are given by the remote, and are regularly too small for
* the generated iframe.
*
* The width is entirely discarded for the actual width of the post, while fixed
* height is used as a starting point before the inevitable resizing.
*
* Since the iframe is automatically resized on load, there are no need for ugly
* and impractical scrollbars.
*
* @param string $src Original remote URL to embed
* @param string $width
* @param string $height
* @return string formatted HTML
*
* @see oembed_format_object()
*/
function oembed_iframe($src, $width, $height) {
$a = get_app();
if (!$height || strstr($height,'%')) {
$height = '200';
}
$width = '100%';
$s = System::baseUrl() . '/oembed/' . base64url_encode($src);
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $s . '" allowfullscreen scrolling="no" frameborder="no">' . t('Embedded content') . '</iframe>';
}
function oembed_bbcode2html($text){
$stopoembed = Config::get("system","no_oembed");
if ($stopoembed == true){
return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "<!-- oembed $1 --><i>". t('Embedding disabled') ." : $1</i><!-- /oembed $1 -->" ,$text);
}
return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", 'oembed_replacecb' ,$text);
}
function oe_build_xpath($attr, $value){
// http://westhoffswelt.de/blog/0036_xpath_to_select_html_by_class.html
return "contains( normalize-space( @$attr ), ' $value ' ) or substring( normalize-space( @$attr ), 1, string-length( '$value' ) + 1 ) = '$value ' or substring( normalize-space( @$attr ), string-length( @$attr ) - string-length( '$value' ) ) = ' $value' or @$attr = '$value'";
}
function oe_get_inner_html($node) {
$innerHTML= '';
$children = $node->childNodes;
foreach ($children as $child) {
$innerHTML .= $child->ownerDocument->saveXML($child);
}
return $innerHTML;
}
/**
* Find <span class='oembed'>..<a href='url' rel='oembed'>..</a></span>
* and replace it with [embed]url[/embed]
*/
function oembed_html2bbcode($text) {
// start parser only if 'oembed' is in text
if (strpos($text, "oembed")) {
// convert non ascii chars to html entities
$html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
// If it doesn't parse at all, just return the text.
$dom = @DOMDocument::loadHTML($html_text);
if (! $dom) {
return $text;
}
$xpath = new DOMXPath($dom);
$attr = "oembed";
$xattr = oe_build_xpath("class","oembed");
$entries = $xpath->query("//span[$xattr]");
$xattr = "@rel='oembed'";//oe_build_xpath("rel","oembed");
foreach ($entries as $e) {
$href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue;
if (!is_null($href)) {
$e->parentNode->replaceChild(new DOMText("[embed]".$href."[/embed]"), $e);
}
}
return oe_get_inner_html( $dom->getElementsByTagName("body")->item(0) );
} else {
return $text;
}
}

View file

@ -1,4 +1,5 @@
<?php
/**
* @file include/tags.php
*/
@ -8,11 +9,13 @@ use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Model\Contact;
function create_tags_from_item($itemid) {
function create_tags_from_item($itemid)
{
$profile_base = System::baseUrl();
$profile_data = parse_url($profile_base);
$profile_base_friendica = $profile_data['host'].$profile_data['path']."/profile/";
$profile_base_diaspora = $profile_data['host'].$profile_data['path']."/u/";
$profile_path = defaults($profile_data, 'path', '');
$profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/';
$profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/';
$messages = q("SELECT `guid`, `uid`, `id`, `edited`, `deleted`, `created`, `received`, `title`, `body`, `tag`, `parent` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
@ -28,39 +31,44 @@ function create_tags_from_item($itemid) {
intval(TERM_HASHTAG),
intval(TERM_MENTION));
if ($message["deleted"])
if ($message['deleted']) {
return;
}
$taglist = explode(",", $message["tag"]);
$taglist = explode(',', $message['tag']);
$tags = "";
foreach ($taglist as $tag)
if ((substr(trim($tag), 0, 1) == "#") || (substr(trim($tag), 0, 1) == "@"))
$tags .= " ".trim($tag);
else
$tags .= " #".trim($tag);
$tags = '';
foreach ($taglist as $tag) {
if ((substr(trim($tag), 0, 1) == '#') || (substr(trim($tag), 0, 1) == '@')) {
$tags .= ' ' . trim($tag);
} else {
$tags .= ' #' . trim($tag);
}
}
$data = " ".$message["title"]." ".$message["body"]." ".$tags." ";
$data = ' ' . $message['title'] . ' ' . $message['body'] . ' ' . $tags . ' ';
// ignore anything in a code block
$data = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $data);
$tags = array();
$pattern = "/\W\#([^\[].*?)[\s'\".,:;\?!\[\]\/]/ism";
if (preg_match_all($pattern, $data, $matches))
foreach ($matches[1] as $match)
$tags["#".strtolower($match)] = "";
$pattern = '/\W\#([^\[].*?)[\s\'".,:;\?!\[\]\/]/ism';
if (preg_match_all($pattern, $data, $matches)) {
foreach ($matches[1] as $match) {
$tags['#' . strtolower($match)] = '';
}
}
$pattern = "/\W([\#@])\[url\=(.*?)\](.*?)\[\/url\]/ism";
$pattern = '/\W([\#@])\[url\=(.*?)\](.*?)\[\/url\]/ism';
if (preg_match_all($pattern, $data, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match)
foreach ($matches as $match) {
$tags[$match[1] . strtolower(trim($match[3], ',.:;[]/\"?!'))] = $match[2];
}
}
foreach ($tags as $tag => $link) {
if (substr(trim($tag), 0, 1) == "#") {
if (substr(trim($tag), 0, 1) == '#') {
// try to ignore #039 or #1 or anything like that
if (ctype_digit(substr(trim($tag), 1)))
continue;
@ -69,7 +77,7 @@ function create_tags_from_item($itemid) {
continue;
$type = TERM_HASHTAG;
$term = substr($tag, 1);
} elseif (substr(trim($tag), 0, 1) == "@") {
} elseif (substr(trim($tag), 0, 1) == '@') {
$type = TERM_MENTION;
$term = substr($tag, 1);
} else { // This shouldn't happen
@ -77,78 +85,78 @@ function create_tags_from_item($itemid) {
$term = $tag;
}
if ($message["uid"] == 0) {
if ($message['uid'] == 0) {
$global = true;
q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
intval(TERM_OBJ_POST), dbesc($message['guid']));
} else {
$isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
intval(TERM_OBJ_POST), dbesc($message['guid']));
$global = (count($isglobal) > 0);
}
$r = q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`, `guid`, `created`, `received`, `global`)
VALUES (%d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d)",
intval($message["uid"]), intval($itemid), intval(TERM_OBJ_POST), intval($type), dbesc($term),
dbesc($link), dbesc($message["guid"]), dbesc($message["created"]), dbesc($message["received"]), intval($global));
intval($message['uid']), intval($itemid), intval(TERM_OBJ_POST), intval($type), dbesc($term),
dbesc($link), dbesc($message['guid']), dbesc($message['created']), dbesc($message['received']), intval($global));
// Search for mentions
if ((substr($tag, 0, 1) == '@') && (strpos($link, $profile_base_friendica) || strpos($link, $profile_base_diaspora))) {
$users = q("SELECT `uid` FROM `contact` WHERE self AND (`url` = '%s' OR `nurl` = '%s')", $link, $link);
foreach ($users AS $user) {
if ($user["uid"] == $message["uid"]) {
if ($user['uid'] == $message['uid']) {
q("UPDATE `item` SET `mention` = 1 WHERE `id` = %d", intval($itemid));
q("UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d", intval($message["parent"]));
q("UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d", intval($message['parent']));
}
}
}
}
}
function create_tags_from_itemuri($itemuri, $uid) {
function create_tags_from_itemuri($itemuri, $uid)
{
$messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
if (count($messages)) {
foreach ($messages as $message) {
create_tags_from_item($message["id"]);
create_tags_from_item($message['id']);
}
}
}
function update_items() {
function update_items()
{
$messages = dba::p("SELECT `oid`,`item`.`guid`, `item`.`created`, `item`.`received` FROM `term` INNER JOIN `item` ON `item`.`id`=`term`.`oid` WHERE `term`.`otype` = 1 AND `term`.`guid` = ''");
logger("fetched messages: ".dba::num_rows($messages));
logger('fetched messages: ' . dba::num_rows($messages));
while ($message = dba::fetch($messages)) {
if ($message["uid"] == 0) {
if ($message['uid'] == 0) {
$global = true;
q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
intval(TERM_OBJ_POST), dbesc($message['guid']));
} else {
$isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
intval(TERM_OBJ_POST), dbesc($message["guid"]));
intval(TERM_OBJ_POST), dbesc($message['guid']));
$global = (count($isglobal) > 0);
}
q("UPDATE `term` SET `guid` = '%s', `created` = '%s', `received` = '%s', `global` = %d WHERE `otype` = %d AND `oid` = %d",
dbesc($message["guid"]), dbesc($message["created"]), dbesc($message["received"]),
intval($global), intval(TERM_OBJ_POST), intval($message["oid"]));
dbesc($message['guid']), dbesc($message['created']), dbesc($message['received']),
intval($global), intval(TERM_OBJ_POST), intval($message['oid']));
}
dba::close($messages);
$messages = dba::p("SELECT `guid` FROM `item` WHERE `uid` = 0");
logger("fetched messages: ".dba::num_rows($messages));
logger('fetched messages: ' . dba::num_rows($messages));
while ($message = dba::fetch(messages)) {
q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($message["guid"]));
q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($message['guid']));
}
dba::close($messages);
@ -166,21 +174,22 @@ function update_items() {
*
* @return arr Alphabetical sorted array of used tags of an user.
*/
function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
require_once('include/security.php');
function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
require_once 'include/security.php';
$item_condition = item_condition();
$sql_options = item_permissions_sql($uid);
$limit = $count ? sprintf("LIMIT %d", intval($count)) : "";
$limit = $count ? sprintf('LIMIT %d', intval($count)) : '';
if ($flags) {
if ($flags === 'wall') {
$sql_options .= " AND `item`.`wall` ";
$sql_options .= ' AND `item`.`wall` ';
}
}
if ($owner_id) {
$sql_options .= " AND `item`.`owner-id` = ".intval($owner_id)." ";
$sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' ';
}
// Fetch tags
@ -212,32 +221,32 @@ function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HA
*
* @return string HTML formatted output.
*/
function wtagblock($uid, $count = 0,$owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
function wtagblock($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
{
$o = '';
$r = tagadelic($uid, $count, $owner_id, $flags, $type);
if (count($r)) {
$contact = dba::select(
"contact",
array("url"),
array("id" => $uid),
array("limit" => 1)
'contact',
array('url'),
array('id' => $uid),
array('limit' => 1)
);
$url = System::removedBaseUrl($contact['url']);
foreach ($r as $rr) {
$tag['level'] = $rr[2];
$tag['url'] = $url."?tag=".urlencode($rr[0]);
$tag['url'] = $url . '?tag=' . urlencode($rr[0]);
$tag['name'] = $rr[0];
$tags[] = $tag;
}
$tpl = get_markup_template("tagblock_widget.tpl");
$tpl = get_markup_template('tagblock_widget.tpl');
$o = replace_macros($tpl, array(
'$title' => t('Tags'),
'$tags' => $tags
));
}
return $o;
}
@ -248,7 +257,8 @@ function wtagblock($uid, $count = 0,$owner_id = 0, $flags = '', $type = TERM_HAS
* @param array $arr Array of tags/terms with tag/term name and total count of use.
* @return array Alphabetical sorted array of used tags/terms of an user.
*/
function tag_calc($arr) {
function tag_calc($arr)
{
$tags = array();
$min = 1e9;
$max = -1e9;
@ -285,7 +295,8 @@ function tag_calc($arr) {
*
* @return int
*/
function tags_sort($a, $b) {
function tags_sort($a, $b)
{
if (strtolower($a[0]) == strtolower($b[0])) {
return 0;
}
@ -298,21 +309,22 @@ function tags_sort($a, $b) {
* @param int $limit Max number of displayed tags.
* @return string HTML formattat output.
*/
function tagcloud_wall_widget($limit = 50) {
function tagcloud_wall_widget($limit = 50)
{
$a = get_app();
if (!$a->profile['profile_uid'] || !$a->profile['url']) {
return "";
return '';
}
if (Feature::isEnabled($a->profile['profile_uid'], 'tagadelic')) {
$owner_id = Contact::getIdForURL($a->profile['url']);
if (!$owner_id) {
return "";
return '';
}
return wtagblock($a->profile['profile_uid'], $limit, $owner_id, 'wall');
}
return "";
return '';
}

View file

@ -994,7 +994,7 @@ function contact_block() {
function micropro($contact, $redirect = false, $class = '', $textmode = false) {
// Use the contact URL if no address is available
if ($contact["addr"] == "") {
if (!x($contact, "addr")) {
$contact["addr"] = $contact["url"];
}
@ -1020,7 +1020,7 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
}
return replace_macros(get_markup_template(($textmode)?'micropro_txt.tpl':'micropro_img.tpl'),array(
'$click' => (($contact['click']) ? $contact['click'] : ''),
'$click' => defaults($contact, 'click', ''),
'$class' => $class,
'$url' => $url,
'$photo' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
@ -1202,11 +1202,15 @@ function redir_private_images($a, &$item)
}
}
function put_item_in_cache(&$item, $update = false) {
if (($item["rendered-hash"] != hash("md5", $item["body"])) || ($item["rendered-hash"] == "") ||
($item["rendered-html"] == "") || Config::get("system", "ignore_cache")) {
function put_item_in_cache(&$item, $update = false)
{
$rendered_hash = defaults($item, 'rendered-hash', '');
if ($rendered_hash == ''
|| $item["rendered-html"] == ""
|| $rendered_hash != hash("md5", $item["body"])
|| Config::get("system", "ignore_cache")
) {
// The function "redir_private_images" changes the body.
// I'm not sure if we should store it permanently, so we save the old value.
$body = $item["body"];

View file

@ -97,6 +97,7 @@ if (!$a->is_backend()) {
session_start();
$a->save_timestamp($stamp1, "parser");
} else {
$_SESSION = [];
Worker::executeIfIdle();
}
@ -148,7 +149,7 @@ if ((x($_GET, 'zrl')) && (!$install && !$maintenance)) {
// header('Link: <' . System::baseUrl() . '/amcd>; rel="acct-mgmt";');
if (x($_COOKIE["Friendica"]) || (x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || ($a->module === 'login')) {
if (x($_COOKIE, "Friendica") || (x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || ($a->module === 'login')) {
require "include/auth.php";
}

View file

@ -534,7 +534,7 @@ function admin_page_federation(App $a)
// off one % two of them are needed in the query
// Add more platforms if you like, when one returns 0 known nodes it is not
// displayed on the stats page.
$platforms = array('Friendi%%a', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon', 'Pleroma');
$platforms = array('Friendi%%a', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon', 'Pleroma', 'socialhome');
$colors = array(
'Friendi%%a' => '#ffc018', // orange from the logo
'Diaspora' => '#a1a1a1', // logo is black and white, makes a gray
@ -544,7 +544,8 @@ function admin_page_federation(App $a)
'GNU Social' => '#a22430', // dark red from the logo
'StatusNet' => '#789240', // the green from the logo (red and blue have already others
'Mastodon' => '#1a9df9', // blue from the Mastodon logo
'Pleroma' => '#E46F0F' // Orange from the text that is used on Pleroma instances
'Pleroma' => '#E46F0F', // Orange from the text that is used on Pleroma instances
'socialhome' => '#52056b' // lilac from the Django Image used at the Socialhome homepage
);
$counts = array();
$total = 0;

View file

@ -13,6 +13,7 @@ use Friendica\Network\Probe;
require_once 'include/contact_selectors.php';
require_once 'mod/proxy.php';
require_once 'include/follow.php';
function contacts_init(App $a) {
if (! local_user()) {
@ -34,8 +35,9 @@ function contacts_init(App $a) {
require_once 'include/contact_widgets.php';
if ($_GET['nets'] == "all") {
$_GET['nets'] = "";
$nets = defaults($_GET, 'nets', '');
if ($nets == "all") {
$nets = "";
}
if (! x($a->page,'aside')) {
@ -62,22 +64,22 @@ function contacts_init(App $a) {
'$account_type' => Contact::getAccountType($a->data['contact'])
));
$finpeople_widget = '';
$findpeople_widget = '';
$follow_widget = '';
$networks_widget = '';
} else {
$vcard_widget = '';
$networks_widget .= networks_widget('contacts',$_GET['nets']);
$networks_widget = networks_widget('contacts', $nets);
if (isset($_GET['add'])) {
$follow_widget = follow_widget($_GET['add']);
} else {
$follow_widget = follow_widget();
}
$findpeople_widget .= findpeople_widget();
$findpeople_widget = findpeople_widget();
}
$groups_widget .= Group::sidebarWidget('contacts','group','full',0,$contact_id);
$groups_widget = Group::sidebarWidget('contacts','group','full',0,$contact_id);
$a->page['aside'] .= replace_macros(get_markup_template("contacts-widget-sidebar.tpl"),array(
'$vcard_widget' => $vcard_widget,
@ -514,8 +516,6 @@ function contacts_content(App $a) {
require_once 'include/contact_selectors.php';
$tpl = get_markup_template("contact_edit.tpl");
switch($contact['rel']) {
case CONTACT_IS_FRIEND:
$dir_icon = 'images/lrarrow.gif';
@ -576,6 +576,7 @@ function contacts_content(App $a) {
$lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : '');
$fetch_further_information = null;
if ($contact['network'] == NETWORK_FEED) {
$fetch_further_information = array('fetch_further_information',
t('Fetch further information for feeds'),
@ -586,12 +587,19 @@ function contacts_content(App $a) {
'3' => t('Fetch keywords'),
'2' => t('Fetch information and keywords')));
}
if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL)))
$poll_interval = null;
if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL))) {
$poll_interval = contact_poll_interval($contact['priority'],(! $poll_enabled));
}
if ($contact['network'] == NETWORK_DFRN)
$profile_select = null;
if ($contact['network'] == NETWORK_DFRN) {
$profile_select = contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false));
}
$follow = '';
$follow_text = '';
if (in_array($contact['network'], array(NETWORK_DIASPORA, NETWORK_OSTATUS))) {
if ($contact['rel'] == CONTACT_IS_FOLLOWER) {
$follow = System::baseUrl(true)."/follow?url=".urlencode($contact["url"]);
@ -605,7 +613,7 @@ function contacts_content(App $a) {
// Load contactact related actions like hide, suggest, delete and others
$contact_actions = contact_actions($contact);
$tpl = get_markup_template("contact_edit.tpl");
$o .= replace_macros($tpl, array(
//'$header' => t('Contact Editor'),
'$header' => t("Contact"),
@ -617,9 +625,7 @@ function contacts_content(App $a) {
'$lbl_info2' => t('Their personal note'),
'$reason' => trim(notags($contact['reason'])),
'$infedit' => t('Edit contact notes'),
'$common_text' => $common_text,
'$common_link' => 'common/loc/' . local_user() . '/' . $contact['id'],
'$all_friends' => $all_friends,
'$relation_text' => $relation_text,
'$visit' => sprintf( t('Visit %s\'s profile [%s]'),$contact['name'],$contact['url']),
'$blockunblock' => t('Block/Unblock contact'),
@ -657,7 +663,6 @@ function contacts_content(App $a) {
'$photo' => $contact['photo'],
'$name' => htmlentities($contact['name']),
'$dir_icon' => $dir_icon,
'$alt_text' => $alt_text,
'$sparkle' => $sparkle,
'$url' => $url,
'$profileurllabel' => t('Profile URL'),
@ -690,33 +695,30 @@ function contacts_content(App $a) {
$blocked = false;
$hidden = false;
$ignored = false;
$archived = false;
$all = false;
if(($a->argc == 2) && ($a->argv[1] === 'all')) {
$sql_extra = '';
$all = true;
}
elseif(($a->argc == 2) && ($a->argv[1] === 'blocked')) {
} elseif(($a->argc == 2) && ($a->argv[1] === 'blocked')) {
$sql_extra = " AND `blocked` = 1 ";
$blocked = true;
}
elseif(($a->argc == 2) && ($a->argv[1] === 'hidden')) {
} elseif(($a->argc == 2) && ($a->argv[1] === 'hidden')) {
$sql_extra = " AND `hidden` = 1 ";
$hidden = true;
}
elseif(($a->argc == 2) && ($a->argv[1] === 'ignored')) {
} elseif(($a->argc == 2) && ($a->argv[1] === 'ignored')) {
$sql_extra = " AND `readonly` = 1 ";
$ignored = true;
}
elseif(($a->argc == 2) && ($a->argv[1] === 'archived')) {
} elseif(($a->argc == 2) && ($a->argv[1] === 'archived')) {
$sql_extra = " AND `archive` = 1 ";
$archived = true;
}
else
} else {
$sql_extra = " AND `blocked` = 0 ";
}
$search = ((x($_GET,'search')) ? notags(trim($_GET['search'])) : '');
$nets = ((x($_GET,'nets')) ? notags(trim($_GET['nets'])) : '');
$search = x($_GET, 'search') ? notags(trim($_GET['search'])) : '';
$nets = x($_GET, 'nets') ? notags(trim($_GET['nets'])) : '';
$tabs = array(
array(
@ -785,9 +787,8 @@ function contacts_content(App $a) {
$tab_tpl = get_markup_template('common_tabs.tpl');
$t = replace_macros($tab_tpl, array('$tabs'=>$tabs));
$searching = false;
$search_hdr = null;
if ($search) {
$search_hdr = $search;
$search_txt = dbesc(protect_sprintf(preg_quote($search)));
@ -795,15 +796,16 @@ function contacts_content(App $a) {
}
$sql_extra .= (($searching) ? " AND (name REGEXP '$search_txt' OR url REGEXP '$search_txt' OR nick REGEXP '$search_txt') " : "");
if($nets)
if ($nets) {
$sql_extra .= sprintf(" AND network = '%s' ", dbesc($nets));
}
$sql_extra2 = ((($sort_type > 0) && ($sort_type <= CONTACT_IS_FRIEND)) ? sprintf(" AND `rel` = %d ",intval($sort_type)) : '');
$r = q("SELECT COUNT(*) AS `total` FROM `contact`
WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 ",
intval($_SESSION['uid']));
intval($_SESSION['uid'])
);
if (DBM::is_result($r)) {
$a->set_pager_total($r[0]['total']);
$total = $r[0]['total'];
@ -833,7 +835,7 @@ function contacts_content(App $a) {
'$total' => $total,
'$search' => $search_hdr,
'$desc' => t('Search your contacts'),
'$finding' => (($searching) ? sprintf(t('Results for: %s'),$search) : ""),
'$finding' => $searching ? t('Results for: %s', $search) : "",
'$submit' => t('Find'),
'$cmd' => $a->cmd,
'$contacts' => $contacts,
@ -848,7 +850,6 @@ function contacts_content(App $a) {
),
'$h_batch_actions' => t('Batch Actions'),
'$paginate' => paginate($a),
));
return $o;
@ -926,12 +927,11 @@ function contact_posts($a, $contact_id) {
$contact = $r[0];
$a->page['aside'] = "";
profile_load($a, "", 0, Contact::getDetailsByURL($contact["url"]));
} else
$profile = "";
}
$tab_str = contacts_tab($a, $contact_id, 1);
$o .= $tab_str;
$o = $tab_str;
$o .= Contact::getPostsFromUrl($contact["url"]);

View file

@ -1,4 +1,5 @@
<?php
/**
* @file mod/crepair.php
*/
@ -10,7 +11,8 @@ use Friendica\Model\Contact;
require_once 'include/contact_selectors.php';
require_once 'mod/contacts.php';
function crepair_init(App $a) {
function crepair_init(App $a)
{
if (!local_user()) {
return;
}
@ -28,8 +30,9 @@ function crepair_init(App $a) {
}
}
if(! x($a->page,'aside'))
if (!x($a->page, 'aside')) {
$a->page['aside'] = '';
}
if ($contact_id) {
$a->data['contact'] = $r[0];
@ -38,7 +41,8 @@ function crepair_init(App $a) {
}
}
function crepair_post(App $a) {
function crepair_post(App $a)
{
if (!local_user()) {
return;
}
@ -58,16 +62,16 @@ function crepair_post(App $a) {
$contact = $r[0];
$name = ((x($_POST,'name')) ? $_POST['name'] : $contact['name']);
$nick = ((x($_POST,'nick')) ? $_POST['nick'] : '');
$url = ((x($_POST,'url')) ? $_POST['url'] : '');
$request = ((x($_POST,'request')) ? $_POST['request'] : '');
$confirm = ((x($_POST,'confirm')) ? $_POST['confirm'] : '');
$notify = ((x($_POST,'notify')) ? $_POST['notify'] : '');
$poll = ((x($_POST,'poll')) ? $_POST['poll'] : '');
$attag = ((x($_POST,'attag')) ? $_POST['attag'] : '');
$photo = ((x($_POST,'photo')) ? $_POST['photo'] : '');
$remote_self = ((x($_POST,'remote_self')) ? $_POST['remote_self'] : false);
$name = defaults($_POST, 'name' , $contact['name']);
$nick = defaults($_POST, 'nick' , '');
$url = defaults($_POST, 'url' , '');
$request = defaults($_POST, 'request' , '');
$confirm = defaults($_POST, 'confirm' , '');
$notify = defaults($_POST, 'notify' , '');
$poll = defaults($_POST, 'poll' , '');
$attag = defaults($_POST, 'attag' , '');
$photo = defaults($_POST, 'photo' , '');
$remote_self = defaults($_POST, 'remote_self', false);
$nurl = normalise_link($url);
$r = q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `url` = '%s', `nurl` = '%s', `request` = '%s', `confirm` = '%s', `notify` = '%s', `poll` = '%s', `attag` = '%s' , `remote_self` = %d
@ -101,10 +105,8 @@ function crepair_post(App $a) {
return;
}
function crepair_content(App $a) {
function crepair_content(App $a)
{
if (!local_user()) {
notice(t('Permission denied.') . EOL);
return;
@ -136,32 +138,31 @@ function crepair_content(App $a) {
// Disable remote self for everything except feeds.
// There is an issue when you repeat an item from maybe twitter and you got comments from friendica and twitter
// Problem is, you couldn't reply to both networks.
if (!in_array($contact['network'], array(NETWORK_FEED, NETWORK_DFRN, NETWORK_DIASPORA)))
if (!in_array($contact['network'], array(NETWORK_FEED, NETWORK_DFRN, NETWORK_DIASPORA))) {
$allow_remote_self = false;
}
if ($contact['network'] == NETWORK_FEED)
if ($contact['network'] == NETWORK_FEED) {
$remote_self_options = array('0' => t('No mirroring'), '1' => t('Mirror as forwarded posting'), '2' => t('Mirror as my own posting'));
else
} else {
$remote_self_options = array('0' => t('No mirroring'), '2' => t('Mirror as my own posting'));
}
$update_profile = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DSPR, NETWORK_OSTATUS));
$update_profile = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS));
$tab_str = contacts_tab($a, $contact['id'], 5);
$tpl = get_markup_template('crepair.tpl');
$o .= replace_macros($tpl, array(
//'$title' => t('Repair Contact Settings'),
$o = replace_macros($tpl, array(
'$tab_str' => $tab_str,
'$warning' => $warning,
'$info' => $info,
'$returnaddr' => $returnaddr,
'$return' => t('Return to contact editor'),
'$update_profile' => update_profile,
'$update_profile' => $update_profile,
'$udprofilenow' => t('Refetch contact data'),
'$contact_id' => $contact['id'],
'$lbl_submit' => t('Submit'),
'$label_remote_self' => t('Remote Self'),
'$allow_remote_self' => $allow_remote_self,
'$remote_self' => array('remote_self',
@ -183,5 +184,4 @@ function crepair_content(App $a) {
));
return $o;
}

View file

@ -29,6 +29,7 @@ use Friendica\Model\Group;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Protocol\Diaspora;
use Friendica\Util\Crypto;
require_once 'include/enotify.php';
@ -162,9 +163,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
* worried about key leakage than anybody cracking it.
*
*/
require_once 'include/crypto.php';
$res = new_keypair(4096);
$res = Crypto::newKeypair(4096);
$private_key = $res['prvkey'];

View file

@ -1,4 +1,5 @@
<?php
/**
* @file mod/dfrn_poll.php
*/
@ -12,27 +13,27 @@ use Friendica\Protocol\OStatus;
require_once 'include/items.php';
require_once 'include/auth.php';
function dfrn_poll_init(App $a) {
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
$type = ((x($_GET,'type')) ? $_GET['type'] : 'data');
$last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : '');
$destination_url = ((x($_GET,'destination_url')) ? $_GET['destination_url'] : '');
$challenge = ((x($_GET,'challenge')) ? $_GET['challenge'] : '');
$sec = ((x($_GET,'sec')) ? $_GET['sec'] : '');
$dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0);
$perm = ((x($_GET,'perm')) ? $_GET['perm'] : 'r');
$quiet = ((x($_GET,'quiet')) ? true : false);
function dfrn_poll_init(App $a)
{
$dfrn_id = x($_GET,'dfrn_id') ? $_GET['dfrn_id'] : '';
$type = x($_GET,'type') ? $_GET['type'] : 'data';
$last_update = x($_GET,'last_update') ? $_GET['last_update'] : '';
$destination_url = x($_GET,'destination_url') ? $_GET['destination_url'] : '';
$challenge = x($_GET,'challenge') ? $_GET['challenge'] : '';
$sec = x($_GET,'sec') ? $_GET['sec'] : '';
$dfrn_version = x($_GET,'dfrn_version') ? (float) $_GET['dfrn_version'] : 2.0;
$perm = x($_GET,'perm') ? $_GET['perm'] : 'r';
$quiet = x($_GET,'quiet') ? true : false;
// Possibly it is an OStatus compatible server that requests a user feed
if (($a->argc > 1) && ($dfrn_id == '') && !strstr($_SERVER["HTTP_USER_AGENT"], 'Friendica')) {
$nickname = $a->argv[1];
header("Content-type: application/atom+xml");
echo OStatus::feed($a, $nickname, $last_update, 10);
echo OStatus::feed($nickname, $last_update, 10);
killme();
}
$direction = (-1);
$direction = -1;
if (strpos($dfrn_id, ':') == 1) {
$direction = intval(substr($dfrn_id, 0, 1));
@ -42,7 +43,7 @@ function dfrn_poll_init(App $a) {
$hidewall = false;
if (($dfrn_id === '') && (!x($_POST, 'dfrn_id'))) {
if((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) {
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
http_status_exit(403);
}
@ -51,8 +52,9 @@ function dfrn_poll_init(App $a) {
$r = q("SELECT `hidewall`,`nickname` FROM `user` WHERE `user`.`nickname` = '%s' LIMIT 1",
dbesc($a->argv[1])
);
if (!$r)
if (!$r) {
http_status_exit(404);
}
$hidewall = ($r[0]['hidewall'] && !local_user());
@ -66,10 +68,9 @@ function dfrn_poll_init(App $a) {
}
if (($type === 'profile') && (!strlen($sec))) {
$sql_extra = '';
switch ($direction) {
case (-1):
case -1:
$sql_extra = sprintf(" AND ( `dfrn-id` = '%s' OR `issued-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
$my_id = $dfrn_id;
break;
@ -94,19 +95,18 @@ function dfrn_poll_init(App $a) {
);
if (DBM::is_result($r)) {
$s = fetch_url($r[0]['poll'] . '?dfrn_id=' . $my_id . '&type=profile-check');
logger("dfrn_poll: old profile returns " . $s, LOGGER_DATA);
if (strlen($s)) {
$xml = parse_xml_string($s);
if((int) $xml->status == 1) {
if ((int) $xml->status === 1) {
$_SESSION['authenticated'] = 1;
if(! x($_SESSION,'remote'))
if (!x($_SESSION, 'remote')) {
$_SESSION['remote'] = array();
}
$_SESSION['remote'][] = array('cid' => $r[0]['id'], 'uid' => $r[0]['uid'], 'url' => $r[0]['url']);
@ -114,8 +114,10 @@ function dfrn_poll_init(App $a) {
$_SESSION['visitor_home'] = $r[0]['url'];
$_SESSION['visitor_handle'] = $r[0]['addr'];
$_SESSION['visitor_visiting'] = $r[0]['uid'];
if(!$quiet)
if (!$quiet) {
info(sprintf(t('%1$s welcomes %2$s'), $r[0]['username'], $r[0]['name']) . EOL);
}
// Visitors get 1 day session.
$session_id = session_id();
$expire = time() + 86400;
@ -129,13 +131,10 @@ function dfrn_poll_init(App $a) {
goaway((strlen($destination_url)) ? $destination_url : System::baseUrl() . '/profile/' . $profile);
}
goaway(System::baseUrl());
}
if ($type === 'profile-check' && $dfrn_version < 2.2) {
if ((strlen($challenge)) && (strlen($sec))) {
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
$r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1",
dbesc($sec)
@ -144,9 +143,11 @@ function dfrn_poll_init(App $a) {
xml_status(3, 'No ticket');
// NOTREACHED
}
$orig_id = $r[0]['dfrn_id'];
if(strpos($orig_id, ':'))
if (strpos($orig_id, ':')) {
$orig_id = substr($orig_id, 2);
}
$c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($r[0]['cid'])
@ -154,6 +155,7 @@ function dfrn_poll_init(App $a) {
if (!DBM::is_result($c)) {
xml_status(3, 'No profile');
}
$contact = $c[0];
$sent_dfrn_id = hex2bin($dfrn_id);
@ -164,16 +166,16 @@ function dfrn_poll_init(App $a) {
if (($contact['duplex']) && strlen($contact['prvkey'])) {
openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
openssl_private_decrypt($challenge, $decoded_challenge, $contact['prvkey']);
}
else {
} else {
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
openssl_public_decrypt($challenge, $decoded_challenge, $contact['pubkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if(strpos($final_dfrn_id,':') == 1)
if (strpos($final_dfrn_id, ':') == 1) {
$final_dfrn_id = substr($final_dfrn_id, 2);
}
if ($final_dfrn_id != $orig_id) {
logger('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, LOGGER_DEBUG);
@ -185,10 +187,8 @@ function dfrn_poll_init(App $a) {
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>$decoded_challenge</challenge><sec>$sec</sec></dfrn_poll>";
killme();
// NOTREACHED
}
else {
} else {
// old protocol
switch ($direction) {
case 1:
$dfrn_id = '0:' . $dfrn_id;
@ -200,7 +200,6 @@ function dfrn_poll_init(App $a) {
break;
}
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
$r = q("SELECT * FROM `profile_check` WHERE `dfrn_id` = '%s' ORDER BY `expire` DESC",
dbesc($dfrn_id));
@ -212,25 +211,20 @@ function dfrn_poll_init(App $a) {
return; // NOTREACHED
}
}
}
function dfrn_poll_post(App $a) {
$dfrn_id = ((x($_POST,'dfrn_id')) ? $_POST['dfrn_id'] : '');
$challenge = ((x($_POST,'challenge')) ? $_POST['challenge'] : '');
$url = ((x($_POST,'url')) ? $_POST['url'] : '');
$sec = ((x($_POST,'sec')) ? $_POST['sec'] : '');
$ptype = ((x($_POST,'type')) ? $_POST['type'] : '');
$dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
$perm = ((x($_POST,'perm')) ? $_POST['perm'] : 'r');
function dfrn_poll_post(App $a)
{
$dfrn_id = x($_POST,'dfrn_id') ? $_POST['dfrn_id'] : '';
$challenge = x($_POST,'challenge') ? $_POST['challenge'] : '';
$url = x($_POST,'url') ? $_POST['url'] : '';
$sec = x($_POST,'sec') ? $_POST['sec'] : '';
$ptype = x($_POST,'type') ? $_POST['type'] : '';
$dfrn_version = x($_POST,'dfrn_version') ? (float) $_POST['dfrn_version'] : 2.0;
$perm = x($_POST,'perm') ? $_POST['perm'] : 'r';
if ($ptype === 'profile-check') {
if((strlen($challenge)) && (strlen($sec))) {
if (strlen($challenge) && strlen($sec)) {
logger('dfrn_poll: POST: profile-check');
q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
@ -241,9 +235,11 @@ function dfrn_poll_post(App $a) {
xml_status(3, 'No ticket');
// NOTREACHED
}
$orig_id = $r[0]['dfrn_id'];
if(strpos($orig_id, ':'))
if (strpos($orig_id, ':')) {
$orig_id = substr($orig_id, 2);
}
$c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($r[0]['cid'])
@ -251,6 +247,7 @@ function dfrn_poll_post(App $a) {
if (!DBM::is_result($c)) {
xml_status(3, 'No profile');
}
$contact = $c[0];
$sent_dfrn_id = hex2bin($dfrn_id);
@ -258,19 +255,19 @@ function dfrn_poll_post(App $a) {
$final_dfrn_id = '';
if(($contact['duplex']) && strlen($contact['prvkey'])) {
if ($contact['duplex'] && strlen($contact['prvkey'])) {
openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
openssl_private_decrypt($challenge, $decoded_challenge, $contact['prvkey']);
}
else {
} else {
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
openssl_public_decrypt($challenge, $decoded_challenge, $contact['pubkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if(strpos($final_dfrn_id,':') == 1)
if (strpos($final_dfrn_id, ':') == 1) {
$final_dfrn_id = substr($final_dfrn_id, 2);
}
if ($final_dfrn_id != $orig_id) {
logger('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, LOGGER_DEBUG);
@ -283,16 +280,14 @@ function dfrn_poll_post(App $a) {
killme();
// NOTREACHED
}
}
$direction = (-1);
$direction = -1;
if (strpos($dfrn_id, ':') == 1) {
$direction = intval(substr($dfrn_id, 0, 1));
$dfrn_id = substr($dfrn_id, 2);
}
$r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
dbesc($dfrn_id),
dbesc($challenge)
@ -313,7 +308,7 @@ function dfrn_poll_post(App $a) {
$sql_extra = '';
switch ($direction) {
case (-1):
case -1:
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
$my_id = $dfrn_id;
break;
@ -330,10 +325,7 @@ function dfrn_poll_post(App $a) {
break; // NOTREACHED
}
$r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1");
if (!DBM::is_result($r)) {
killme();
}
@ -342,7 +334,6 @@ function dfrn_poll_post(App $a) {
$owner_uid = $r[0]['uid'];
$contact_id = $r[0]['id'];
if ($type === 'reputation' && strlen($url)) {
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
dbesc($url),
@ -370,16 +361,15 @@ function dfrn_poll_post(App $a) {
";
killme();
// NOTREACHED
}
else {
} else {
// Update the writable flag if it changed
logger('dfrn_poll: post request feed: ' . print_r($_POST, true), LOGGER_DATA);
if ($dfrn_version >= 2.21) {
if($perm === 'rw')
if ($perm === 'rw') {
$writable = 1;
else
} else {
$writable = 0;
}
if ($writable != $contact['writable']) {
q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d",
@ -393,28 +383,26 @@ function dfrn_poll_post(App $a) {
$o = DFRN::feed($dfrn_id, $a->argv[1], $last_update, $direction);
echo $o;
killme();
}
}
function dfrn_poll_content(App $a) {
function dfrn_poll_content(App $a)
{
$dfrn_id = x($_GET,'dfrn_id') ? $_GET['dfrn_id'] : '';
$type = x($_GET,'type') ? $_GET['type'] : 'data';
$last_update = x($_GET,'last_update') ? $_GET['last_update'] : '';
$destination_url = x($_GET,'destination_url') ? $_GET['destination_url'] : '';
$sec = x($_GET,'sec') ? $_GET['sec'] : '';
$dfrn_version = x($_GET,'dfrn_version') ? (float) $_GET['dfrn_version'] : 2.0;
$perm = x($_GET,'perm') ? $_GET['perm'] : 'r';
$quiet = x($_GET,'quiet') ? true : false;
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
$type = ((x($_GET,'type')) ? $_GET['type'] : 'data');
$last_update = ((x($_GET,'last_update')) ? $_GET['last_update'] : '');
$destination_url = ((x($_GET,'destination_url')) ? $_GET['destination_url'] : '');
$sec = ((x($_GET,'sec')) ? $_GET['sec'] : '');
$dfrn_version = ((x($_GET,'dfrn_version')) ? (float) $_GET['dfrn_version'] : 2.0);
$perm = ((x($_GET,'perm')) ? $_GET['perm'] : 'r');
$quiet = ((x($_GET,'quiet')) ? true : false);
$direction = (-1);
$direction = -1;
if (strpos($dfrn_id, ':') == 1) {
$direction = intval(substr($dfrn_id, 0, 1));
$dfrn_id = substr($dfrn_id, 2);
}
if ($dfrn_id != '') {
// initial communication from external contact
$hash = random_string();
@ -433,13 +421,16 @@ function dfrn_poll_content(App $a) {
dbesc($last_update)
);
}
$sql_extra = '';
switch ($direction) {
case (-1):
if($type === 'profile')
case -1:
if ($type === 'profile') {
$sql_extra = sprintf(" AND ( `dfrn-id` = '%s' OR `issued-id` = '%s' ) ", dbesc($dfrn_id), dbesc($dfrn_id));
else
} else {
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
}
$my_id = $dfrn_id;
break;
case 0:
@ -463,35 +454,29 @@ function dfrn_poll_content(App $a) {
AND `user`.`nickname` = '%s' $sql_extra LIMIT 1",
dbesc($nickname)
);
if (DBM::is_result($r)) {
$challenge = '';
$encrypted_id = '';
$id_str = $my_id . '.' . mt_rand(1000, 9999);
if(($r[0]['duplex'] && strlen($r[0]['pubkey'])) || (! strlen($r[0]['prvkey']))) {
if (($r[0]['duplex'] && strlen($r[0]['pubkey'])) || !strlen($r[0]['prvkey'])) {
openssl_public_encrypt($hash, $challenge, $r[0]['pubkey']);
openssl_public_encrypt($id_str, $encrypted_id, $r[0]['pubkey']);
}
else {
} else {
openssl_private_encrypt($hash, $challenge, $r[0]['prvkey']);
openssl_private_encrypt($id_str, $encrypted_id, $r[0]['prvkey']);
}
$challenge = bin2hex($challenge);
$encrypted_id = bin2hex($encrypted_id);
}
else {
} else {
$status = 1;
$challenge = '';
$encrypted_id = '';
}
if (($type === 'profile') && (strlen($sec))) {
// URL reply
if ($dfrn_version < 2.2) {
$s = fetch_url($r[0]['poll']
. '?dfrn_id=' . $encrypted_id
@ -500,8 +485,7 @@ function dfrn_poll_content(App $a) {
. '&challenge=' . $challenge
. '&sec=' . $sec
);
}
else {
} else {
$s = post_url($r[0]['poll'], array(
'dfrn_id' => $encrypted_id,
'type' => 'profile-check',
@ -533,7 +517,6 @@ function dfrn_poll_content(App $a) {
logger("dfrn_poll: sec profile: " . $s, LOGGER_DATA);
if (strlen($s) && strstr($s, '<?xml')) {
$xml = parse_xml_string($s);
logger('dfrn_poll: profile: parsed xml: ' . print_r($xml, true), LOGGER_DATA);
@ -541,17 +524,20 @@ function dfrn_poll_content(App $a) {
logger('dfrn_poll: secure profile: challenge: ' . $xml->challenge . ' expecting ' . $hash);
logger('dfrn_poll: secure profile: sec: ' . $xml->sec . ' expecting ' . $sec);
if (((int) $xml->status == 0) && ($xml->challenge == $hash) && ($xml->sec == $sec)) {
$_SESSION['authenticated'] = 1;
if(! x($_SESSION,'remote'))
if (!x($_SESSION, 'remote')) {
$_SESSION['remote'] = array();
}
$_SESSION['remote'][] = array('cid' => $r[0]['id'], 'uid' => $r[0]['uid'], 'url' => $r[0]['url']);
$_SESSION['visitor_id'] = $r[0]['id'];
$_SESSION['visitor_home'] = $r[0]['url'];
$_SESSION['visitor_visiting'] = $r[0]['uid'];
if(!$quiet)
if (!$quiet) {
info(sprintf(t('%1$s welcomes %2$s'), $r[0]['username'], $r[0]['name']) . EOL);
}
// Visitors get 1 day session.
$session_id = session_id();
$expire = time() + 86400;
@ -565,9 +551,7 @@ function dfrn_poll_content(App $a) {
}
goaway($dest);
// NOTREACHED
}
else {
} else {
// XML reply
header("Content-type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n"

View file

@ -201,8 +201,9 @@ function display_content(App $a, $update = false, $update_uid = 0) {
if ($update) {
$item_id = $_REQUEST['item_id'];
$item = dba::select('item', ['uid'], ['id' => $item_id], ['limit' => 1]);
$item = dba::select('item', ['uid', 'parent'], ['id' => $item_id], ['limit' => 1]);
$a->profile = array('uid' => intval($item['uid']), 'profile_uid' => intval($item['uid']));
$item_parent = $item['parent'];
} else {
$item_id = (($a->argc > 2) ? $a->argv[2] : 0);
@ -260,7 +261,7 @@ function display_content(App $a, $update = false, $update_uid = 0) {
$contact_id = 0;
if (is_array($_SESSION['remote'])) {
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) {
if ($v['uid'] == $a->profile['uid']) {
$contact_id = $v['cid'];
@ -294,7 +295,7 @@ function display_content(App $a, $update = false, $update_uid = 0) {
}
$is_owner = (local_user() && (in_array($a->profile['profile_uid'], [local_user(), 0])) ? true : false);
if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
if (x($a->profile, 'hidewall') && !$is_owner && !$remote_contact) {
notice(t('Access to this profile has been restricted.') . EOL);
return;
}

View file

@ -20,7 +20,7 @@ function events_init(App $a) {
return;
}
if ($a->argc == 1) {
if ($a->argc > 1) {
// If it's a json request abort here because we don't
// need the widget data
if ($a->argv[1] === 'json') {
@ -234,6 +234,7 @@ function events_content(App $a) {
));
$o = '';
$tabs = '';
// tabs
if ($a->theme_events_in_profile) {
$tabs = profile_tabs($a, true);
@ -309,10 +310,13 @@ function events_content(App $a) {
$start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0);
$finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59);
if ($a->argv[1] === 'json') {
if (x($_GET, 'start')) {$start = $_GET['start'];}
if (x($_GET, 'end')) {$finish = $_GET['end'];}
if ($a->argc > 1 && $a->argv[1] === 'json') {
if (x($_GET, 'start')) {
$start = $_GET['start'];
}
if (x($_GET, 'end')) {
$finish = $_GET['end'];
}
}
$start = datetime_convert('UTC', 'UTC', $start);
@ -358,7 +362,7 @@ function events_content(App $a) {
$events = process_events($r);
}
if ($a->argv[1] === 'json'){
if ($a->argc > 1 && $a->argv[1] === 'json'){
echo json_encode($events);
killme();
}

View file

@ -8,8 +8,6 @@ use Friendica\Core\System;
use Friendica\Protocol\Diaspora;
use Friendica\Util\XML;
require_once "include/crypto.php";
function fetch_init(App $a)
{

View file

@ -176,7 +176,8 @@ function follow_content(App $a) {
));
$a->page['aside'] = "";
profile_load($a, "", 0, Contact::getDetailsByURL($ret["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($ret["url"]), false);
if ($gcontact_id <> 0) {
$o .= replace_macros(get_markup_template('section_title.tpl'),

View file

@ -4,6 +4,8 @@ use Friendica\App;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
require_once 'include/follow.php';
function fsuggest_post(App $a) {
if (! local_user()) {

View file

@ -1,18 +1,21 @@
<?php
/**
* @file mod/hostxrd.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Protocol\Salmon;
use Friendica\Util\Crypto;
require_once('include/crypto.php');
function hostxrd_init(App $a) {
function hostxrd_init(App $a)
{
header('Access-Control-Allow-Origin: *');
header("Content-type: text/xml");
$pubkey = Config::get('system', 'site_pubkey');
if (! $pubkey) {
$res = new_keypair(1024);
$res = Crypto::newKeypair(1024);
Config::set('system','site_prvkey', $res['prvkey']);
Config::set('system','site_pubkey', $res['pubkey']);
@ -23,8 +26,8 @@ function hostxrd_init(App $a) {
'$zhost' => $a->get_hostname(),
'$zroot' => System::baseUrl(),
'$domain' => System::baseUrl(),
'$bigkey' => salmon_key(Config::get('system','site_pubkey')),
));
exit();
'$bigkey' => Salmon::salmonKey(Config::get('system', 'site_pubkey')))
);
exit();
}

View file

@ -7,90 +7,87 @@
* Author: Rabuzarus <https://github.com/rabuzarus>
* License: GNU AFFERO GENERAL PUBLIC LICENSE (Version 3)
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
function hovercard_init(App $a) {
function hovercard_init(App $a)
{
// Just for testing purposes
$_GET["mode"] = "minimal";
$_GET['mode'] = 'minimal';
}
function hovercard_content() {
$profileurl = (x($_REQUEST,'profileurl') ? $_REQUEST['profileurl'] : "");
$datatype = (x($_REQUEST,'datatype') ?$_REQUEST['datatype'] : "json");
function hovercard_content()
{
$profileurl = defaults($_REQUEST, 'profileurl', '');
$datatype = defaults($_REQUEST, 'datatype' , 'json');
// Get out if the system doesn't have public access allowed
if(intval(Config::get('system','block_public')))
if (intval(Config::get('system', 'block_public'))) {
http_status_exit(401);
}
// Return the raw content of the template. We use this to make templates usable for js functions.
// Look at hovercard.js (function getHoverCardTemplate()).
// This part should be moved in it's own module. Maybe we could make more templates accessabel.
// (We need to discuss possible security lacks before doing this)
if ($datatype == "tpl") {
$templatecontent = get_template_content("hovercard.tpl");
// This part should be moved in its own module. Maybe we could make more templates accessible.
// (We need to discuss possible security leaks before doing this)
if ($datatype == 'tpl') {
$templatecontent = get_template_content('hovercard.tpl');
echo $templatecontent;
killme();
}
// If a contact is connected the url is internally changed to "redir/CID". We need the pure url to search for
// If a contact is connected the url is internally changed to 'redir/CID'. We need the pure url to search for
// the contact. So we strip out the contact id from the internal url and look in the contact table for
// the real url (nurl)
if (local_user() && strpos($profileurl, "redir/") === 0) {
$cid = 0;
if (local_user() && strpos($profileurl, 'redir/') === 0) {
$cid = intval(substr($profileurl, 6));
$r = dba::select('contact', array('nurl', 'self'), array('id' => $cid), array('limit' => 1));
$profileurl = ($r["nurl"] ? $r["nurl"] : "");
$self = ($r["self"] ? $r["self"] : "");
$r = dba::select('contact', array('nurl'), array('id' => $cid), array('limit' => 1));
$profileurl = defaults($r, 'nurl', '');
}
$contact = [];
// if it's the url containing https it should be converted to http
$nurl = normalise_link(GContact::cleanContactUrl($profileurl));
if ($nurl) {
// Search for contact data
$contact = Contact::getDetailsByURL($nurl);
}
if(!is_array($contact))
if (!count($contact)) {
return;
}
// Get the photo_menu - the menu if possible contact actions
if(local_user())
if (local_user()) {
$actions = Contact::photoMenu($contact);
}
// Move the contact data to the profile array so we can deliver it to
//
$profile = array(
'name' => $contact["name"],
'nick' => $contact["nick"],
'addr' => (($contact["addr"] != "") ? $contact["addr"] : $contact["url"]),
'thumb' => proxy_url($contact["thumb"], false, PROXY_SIZE_THUMB),
'url' => ($cid ? ("redir/".$cid) : zrl($contact["url"])),
'nurl' => $contact["nurl"], // We additionally store the nurl as identifier
// 'alias' => $contact["alias"],
'location' => $contact["location"],
'gender' => $contact["gender"],
'about' => $contact["about"],
'network' => format_network_name($contact["network"], $contact["url"]),
'tags' => $contact["keywords"],
// 'nsfw' => intval($contact["nsfw"]),
// 'server_url' => $contact["server_url"],
'bd' => (($contact["birthday"] <= '0001-01-01') ? "" : $contact["birthday"]),
// 'generation' => $contact["generation"],
'name' => $contact['name'],
'nick' => $contact['nick'],
'addr' => defaults($contact, 'addr', $contact['url']),
'thumb' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
'url' => $cid ? ('redir/' . $cid) : zrl($contact['url']),
'nurl' => $contact['nurl'], // We additionally store the nurl as identifier
'location' => $contact['location'],
'gender' => $contact['gender'],
'about' => $contact['about'],
'network' => format_network_name($contact['network'], $contact['url']),
'tags' => $contact['keywords'],
'bd' => $contact['birthday'] <= '0001-01-01' ? '' : $contact['birthday'],
'account_type' => Contact::getAccountType($contact),
'actions' => $actions,
);
if($datatype == "html") {
$t = get_markup_template("hovercard.tpl");
$o = replace_macros($t, array(
if ($datatype == 'html') {
$tpl = get_markup_template('hovercard.tpl');
$o = replace_macros($tpl, array(
'$profile' => $profile,
));
return $o;
} else {
json_return_and_die($profile);
}
@ -104,8 +101,8 @@ function hovercard_content() {
*
* @return string|bool Output the raw content if existent, otherwise false
*/
function get_template_content($template, $root = "") {
function get_template_content($template, $root = '')
{
// We load the whole template system to get the filename.
// Maybe we can do it a little bit smarter if I get time.
$t = get_markup_template($template, $root);

View file

@ -29,7 +29,6 @@ use Friendica\Protocol\Diaspora;
use Friendica\Protocol\Email;
use Friendica\Util\Emailer;
require_once 'include/crypto.php';
require_once 'include/enotify.php';
require_once 'include/tags.php';
require_once 'include/files.php';

View file

@ -3,10 +3,10 @@
use Friendica\App;
use Friendica\Core\System;
require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
require_once('include/like.php');
require_once 'include/security.php';
require_once 'include/bbcode.php';
require_once 'include/items.php';
require_once 'include/like.php';
function like_content(App $a) {
if (!local_user() && !remote_user()) {
@ -16,20 +16,22 @@ function like_content(App $a) {
$verb = notags(trim($_GET['verb']));
if(! $verb)
if (!$verb) {
$verb = 'like';
}
$item_id = (($a->argc > 1) ? notags(trim($a->argv[1])) : 0);
$r = do_like($item_id, $verb);
if (!$r) return;
if (!$r) {
return;
}
// See if we've been passed a return path to redirect to
$return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : '');
like_content_return(System::baseUrl(), $return_path);
killme(); // NOTREACHED
// return; // NOTREACHED
}
@ -37,15 +39,16 @@ function like_content(App $a) {
// then redirect back to the calling page. If not, just quietly end
function like_content_return($baseurl, $return_path) {
if ($return_path) {
$rand = '_=' . time();
if(strpos($return_path, '?')) $rand = "&$rand";
else $rand = "?$rand";
if (strpos($return_path, '?')) {
$rand = "&$rand";
} else {
$rand = "?$rand";
}
goaway($baseurl . "/" . $return_path . $rand);
}
killme();
}

View file

@ -10,8 +10,8 @@ require_once 'include/acl_selectors.php';
require_once 'include/message.php';
require_once 'include/conversation.php';
function message_init(App $a) {
function message_init(App $a)
{
$tabs = '';
if ($a->argc > 1 && is_numeric($a->argv[1])) {
@ -21,7 +21,7 @@ function message_init(App $a) {
$new = array(
'label' => t('New Message'),
'url' => 'message/new',
'sel'=> ($a->argv[1] == 'new'),
'sel' => $a->argc > 1 && $a->argv[1] == 'new',
'accesskey' => 'm',
);
@ -43,20 +43,19 @@ function message_init(App $a) {
'$baseurl' => System::baseUrl(true),
'$base' => $base
));
}
function message_post(App $a) {
function message_post(App $a)
{
if (!local_user()) {
notice(t('Permission denied.') . EOL);
return;
}
$replyto = ((x($_REQUEST,'replyto')) ? notags(trim($_REQUEST['replyto'])) : '');
$subject = ((x($_REQUEST,'subject')) ? notags(trim($_REQUEST['subject'])) : '');
$body = ((x($_REQUEST,'body')) ? escape_tags(trim($_REQUEST['body'])) : '');
$recipient = ((x($_REQUEST,'messageto')) ? intval($_REQUEST['messageto']) : 0 );
$replyto = x($_REQUEST, 'replyto') ? notags(trim($_REQUEST['replyto'])) : '';
$subject = x($_REQUEST, 'subject') ? notags(trim($_REQUEST['subject'])) : '';
$body = x($_REQUEST, 'body') ? escape_tags(trim($_REQUEST['body'])) : '';
$recipient = x($_REQUEST, 'messageto') ? intval($_REQUEST['messageto']) : 0;
$ret = send_message($recipient, $body, $subject, $replyto);
$norecip = false;
@ -80,17 +79,16 @@ function message_post(App $a) {
}
// fake it to go back to the input form if no recipient listed
if ($norecip) {
$a->argc = 2;
$a->argv[1] = 'new';
} else
} else {
goaway($_SESSION['return_url']);
}
}
function message_content(App $a) {
function message_content(App $a)
{
$o = '';
nav_set_selected('messages');
@ -104,13 +102,12 @@ function message_content(App $a) {
$tpl = get_markup_template('mail_head.tpl');
$header = replace_macros($tpl, array(
'$messages' => t('Messages'),
'$tab_content' => $tab_content
));
if (($a->argc == 3) && ($a->argv[1] === 'drop' || $a->argv[1] === 'dropconv')) {
if (! intval($a->argv[2]))
if (!intval($a->argv[2])) {
return;
}
// Check if we should do HTML-based delete confirmation
if ($_REQUEST['confirm']) {
@ -170,24 +167,22 @@ function message_content(App $a) {
// Actually if we do this, we can never receive another reply to that conversation,
// as we will never again have the info we need to re-create it.
// We'll just have to orphan it.
//if ($convid) {
// q("delete from conv where id = %d limit 1",
// intval($convid)
// );
//}
if ($r)
if ($r) {
info(t('Conversation removed.') . EOL);
}
}
//goaway(System::baseUrl(true) . '/message' );
goaway($_SESSION['return_url']);
}
}
if (($a->argc > 1) && ($a->argv[1] === 'new')) {
$o .= $header;
$tpl = get_markup_template('msg-header.tpl');
@ -204,8 +199,7 @@ function message_content(App $a) {
'$linkurl' => t('Please enter a link URL:')
));
$preselect = (isset($a->argv[2])?array($a->argv[2]):false);
$preselect = isset($a->argv[2]) ? array($a->argv[2]) : false;
$prename = $preurl = $preid = '';
@ -233,14 +227,14 @@ function message_content(App $a) {
$preurl = $r[0]['url'];
$preid = $r[0]['id'];
$preselect = array($preid);
} else
} else {
$preselect = false;
}
}
$prefill = (($preselect) ? $prename : '');
$prefill = $preselect ? $prename : '';
// the ugly select box
$select = contact_select('messageto', 'message-to-select', $preselect, 4, true, false, false, 10);
$tpl = get_markup_template('prv_message.tpl');
@ -252,8 +246,8 @@ function message_content(App $a) {
'$autocomp' => $autocomp,
'$preid' => $preid,
'$subject' => t('Subject:'),
'$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''),
'$text' => ((x($_REQUEST,'body')) ? escape_tags(htmlspecialchars($_REQUEST['body'])) : ''),
'$subjtxt' => x($_REQUEST, 'subject') ? strip_tags($_REQUEST['subject']) : '',
'$text' => x($_REQUEST, 'body') ? escape_tags(htmlspecialchars($_REQUEST['body'])) : '',
'$readonly' => '',
'$yourmessage' => t('Your message:'),
'$select' => $select,
@ -369,10 +363,10 @@ function message_content(App $a) {
$sparkle = ' sparkle';
}
$extracted = item_extract_images($message['body']);
if ($extracted['images'])
if ($extracted['images']) {
$message['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $message['contact-id']);
}
$from_name_e = $message['from-name'];
$subject_e = $message['title'];
@ -380,10 +374,11 @@ function message_content(App $a) {
$to_name_e = $message['name'];
$contact = Contact::getDetailsByURL($message['from-url']);
if (isset($contact["thumb"]))
if (isset($contact["thumb"])) {
$from_photo = $contact["thumb"];
else
} else {
$from_photo = $message['from-photo'];
}
$mails[] = array(
'id' => $message['id'],
@ -403,14 +398,10 @@ function message_content(App $a) {
$seen = $message['seen'];
}
$select = $message['name'] . '<input type="hidden" name="messageto" value="' . $contact_id . '" />';
$parent = '<input type="hidden" name="replyto" value="' . $message['parent-uri'] . '" />';
$tpl = get_markup_template('mail_display.tpl');
$subjtxt_e = $message['title'];
$o = replace_macros($tpl, array(
'$thread_id' => $a->argv[1],
'$thread_subject' => $message['title'],
@ -425,7 +416,7 @@ function message_content(App $a) {
'$to' => t('To:'),
'$showinputs' => '',
'$subject' => t('Subject:'),
'$subjtxt' => $subjtxt_e,
'$subjtxt' => $message['title'],
'$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ',
'$yourmessage' => t('Your message:'),
'$text' => '',
@ -435,14 +426,14 @@ function message_content(App $a) {
'$insert' => t('Insert web link'),
'$submit' => t('Submit'),
'$wait' => t('Please wait')
));
return $o;
}
}
function get_messages($user, $lstart, $lend) {
function get_messages($user, $lstart, $lend)
{
//TODO: rewritte with a sub-query to get the first message of each private thread with certainty
return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`,
ANY_VALUE(`mail`.`id`) AS `id`, ANY_VALUE(`mail`.`uid`) AS `uid`, ANY_VALUE(`mail`.`guid`) AS `guid`,
@ -461,8 +452,8 @@ function get_messages($user, $lstart, $lend) {
);
}
function render_messages(array $msg, $t) {
function render_messages(array $msg, $t)
{
$a = get_app();
$tpl = get_markup_template($t);
@ -471,23 +462,24 @@ function render_messages(array $msg, $t) {
$myprofile = System::baseUrl() . '/profile/' . $a->user['nickname'];
foreach ($msg as $rr) {
if ($rr['unknown'])
$participants = sprintf( t("Unknown sender - %s"),$rr['from-name']);
elseif (link_compare($rr['from-url'], $myprofile))
$participants = sprintf( t("You and %s"), $rr['name']);
else
$participants = sprintf(t("%s and You"), $rr['from-name']);
if ($rr['unknown']) {
$participants = t("Unknown sender - %s", $rr['from-name']);
} elseif (link_compare($rr['from-url'], $myprofile)) {
$participants = t("You and %s", $rr['name']);
} else {
$participants = t("%s and You", $rr['from-name']);
}
$subject_e = (($rr['mailseen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>');
$body_e = $rr['body'];
$to_name_e = $rr['name'];
$contact = Contact::getDetailsByURL($rr['url']);
if (isset($contact["thumb"]))
if (isset($contact["thumb"])) {
$from_photo = $contact["thumb"];
else
} else {
$from_photo = (($rr['thumb']) ? $rr['thumb'] : $rr['from-photo']);
}
$rslt .= replace_macros($tpl, array(
'$id' => $rr['id'],
@ -503,7 +495,7 @@ function render_messages(array $msg, $t) {
'$date' => datetime_convert('UTC', date_default_timezone_get(), $rr['mailcreated'], t('D, d M Y - g:i A')),
'$ago' => relative_date($rr['mailcreated']),
'$seen' => $rr['mailseen'],
'$count' => sprintf( tt('%d message', '%d messages', $rr['count']), $rr['count']),
'$count' => tt('%d message', '%d messages', $rr['count']),
));
}

View file

@ -365,7 +365,7 @@ function networkConversation($a, $items, $mode, $update) {
// Set this so that the conversation function can find out contact info for our wall-wall items
$a->page_contact = $a->contact;
$o .= conversation($a, $items, $mode, $update);
$o = conversation($a, $items, $mode, $update);
if (!$update) {
if (PConfig::get(local_user(), 'system', 'infinite_scroll')) {
@ -568,9 +568,9 @@ function networkThreadedView(App $a, $update = 0) {
if ($group) {
if (($t = Contact::getOStatusCountByGroupId($group)) && !PConfig::get(local_user(), 'system', 'nowarn_insecure')) {
notice(sprintf(tt("Warning: This group contains %s member from a network that doesn't allow non public messages.",
notice(tt("Warning: This group contains %s member from a network that doesn't allow non public messages.",
"Warning: This group contains %s members from a network that doesn't allow non public messages.",
$t), $t).EOL);
$t) . EOL);
notice(t("Messages in this group won't be send to these receivers.").EOL);
}
}
@ -664,7 +664,7 @@ function networkThreadedView(App $a, $update = 0) {
}
$o = replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => sprintf(t('Group: %s'), $r['name'])
'$title' => t('Group: %s', $r['name'])
)) . $o;
} elseif ($cid) {
@ -716,13 +716,6 @@ function networkThreadedView(App $a, $update = 0) {
$sql_order = "";
$order_mode = "received";
if (strlen($file)) {
$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` ",
dbesc(protect_sprintf($file)), intval(TERM_OBJ_POST), intval(TERM_FILE), intval(local_user()));
$sql_order = "`item`.`id`";
$order_mode = "id";
}
if ($conv) {
$sql_extra3 .= " AND $sql_table.`mention`";
}
@ -744,7 +737,7 @@ function networkThreadedView(App $a, $update = 0) {
$sql_order = "$sql_table.$ordering";
}
if (($_GET["offset"] != "")) {
if (x($_GET, 'offset')) {
$sql_extra3 .= sprintf(" AND $sql_order <= '%s'", dbesc($_GET["offset"]));
}
@ -816,6 +809,7 @@ function networkThreadedView(App $a, $update = 0) {
$parents_str = '';
$date_offset = "";
$items = array();
if (DBM::is_result($r)) {
foreach ($r as $rr) {
if (!in_array($rr['item_id'], $parents_arr)) {
@ -833,8 +827,6 @@ function networkThreadedView(App $a, $update = 0) {
$max_comments = 100;
}
$items = array();
foreach ($parents_arr AS $parents) {
$thread_items = dba::p(item_query() . " AND `item`.`uid` = ?
AND `item`.`parent` = ?
@ -848,14 +840,14 @@ function networkThreadedView(App $a, $update = 0) {
}
}
$items = conv_sort($items, $ordering);
} else {
$items = array();
}
if ($_GET["offset"] == "") {
if (x($_GET, 'offset')) {
$date_offset = $_GET["offset"];
} elseif(count($items)) {
$date_offset = $items[0][$order_mode];
} else {
$date_offset = $_GET["offset"];
$date_offset = '';
}
$a->page_offset = $date_offset;

View file

@ -41,28 +41,25 @@ function nogroup_content(App $a)
$contact_details = Contact::getDetailsByURL($rr['url'], local_user(), $rr);
$contacts[] = array(
'img_hover' => sprintf(t('Visit %s\'s profile [%s]'), $contact_details['name'], $rr['url']),
'img_hover' => t('Visit %s\'s profile [%s]', $contact_details['name'], $rr['url']),
'edit_hover' => t('Edit contact'),
'photo_menu' => Contact::photoMenu($rr),
'id' => $rr['id'],
'alt_text' => $alt_text,
'dir_icon' => $dir_icon,
'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
'name' => $contact_details['name'],
'username' => $contact_details['name'],
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'sparkle' => $sparkle,
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
'url' => $rr['url'],
'network' => network_to_name($rr['network'], $url),
'network' => network_to_name($rr['network'], $rr['url']),
);
}
}
$tpl = get_markup_template("nogroup-template.tpl");
$o .= replace_macros(
$o = replace_macros(
$tpl,
array(
'$header' => t('Contacts who are not members of a group'),

View file

@ -1,38 +0,0 @@
<?php
use Friendica\App;
require_once("include/oembed.php");
function oembed_content(App $a) {
// logger('mod_oembed ' . $a->query_string, LOGGER_ALL);
if ($a->argv[1]=='b2h'){
$url = array( "", trim(hex2bin($_REQUEST['url'])));
echo oembed_replacecb($url);
killme();
}
if ($a->argv[1]=='h2b'){
$text = trim(hex2bin($_REQUEST['text']));
echo oembed_html2bbcode($text);
killme();
}
if ($a->argc == 2){
echo "<html><body>";
$url = base64url_decode($a->argv[1]);
$j = oembed_fetch_url($url);
// workaround for media.ccc.de (and any other endpoint that return size 0)
if (substr($j->html, 0, 7) == "<iframe" && strstr($j->html, 'width="0"')) {
$j->html = '<style>html,body{margin:0;padding:0;} iframe{width:100%;height:100%;}</style>'. $j->html;
$j->html = str_replace('width="0"', '', $j->html);
$j->html = str_replace('height="0"', '', $j->html);
}
echo $j->html;
// logger('mod-oembed ' . $j->html, LOGGER_ALL);
echo "</body></html>";
}
killme();
}

View file

@ -1,4 +1,5 @@
<?php
/**
* @file mod/photo.php
*/
@ -8,7 +9,8 @@ use Friendica\Object\Image;
require_once 'include/security.php';
function photo_init(App $a) {
function photo_init(App $a)
{
global $_SERVER;
$prvcachecontrol = false;
@ -49,15 +51,11 @@ function photo_init(App $a) {
}
$default = 'images/person-175.jpg';
$public = true;
if (isset($type)) {
/**
* Profile photos
*/
// Profile photos
switch ($type) {
case 'profile':
case 'custom':
$resolution = 4;
@ -92,11 +90,7 @@ function photo_init(App $a) {
$mimetype = 'image/jpeg';
}
} else {
/**
* Other photos
*/
// Other photos
$resolution = 0;
$photo = str_replace(array('.jpg', '.png', '.gif'), array('', '', ''), $photo);
@ -115,22 +109,18 @@ function photo_init(App $a) {
intval($resolution)
);
if (DBM::is_result($r)) {
$sql_extra = permissions_sql($r[0]['uid']);
// Now we'll see if we can access the photo
$r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `scale` <= %d $sql_extra ORDER BY scale DESC LIMIT 1",
dbesc($photo),
intval($resolution)
);
$public = (DBM::is_result($r)) && ($r[0]['allow_cid'] == '') && ($r[0]['allow_gid'] == '') && ($r[0]['deny_cid'] == '') && ($r[0]['deny_gid'] == '');
if (DBM::is_result($r)) {
$resolution = $r[0]['scale'];
$data = $r[0]['data'];
$mimetype = $r[0]['type'];
$public = $r[0]['allow_cid'] == '' && $r[0]['allow_gid'] == '' && $r[0]['deny_cid'] == '' && $r[0]['deny_gid'] == '';
} else {
// The picure exists. We already checked with the first query.
// obviously, this is not an authorized viev!
@ -145,7 +135,6 @@ function photo_init(App $a) {
if (empty($data)) {
if (isset($resolution)) {
switch ($resolution) {
case 4:
$data = file_get_contents('images/person-175.jpg');
$mimetype = 'image/jpeg';
@ -167,7 +156,7 @@ function photo_init(App $a) {
}
// Resize only if its not a GIF and it is supported by the library
if (($mimetype != "image/gif") && in_array($mimetype, Image::supportedTypes())) {
if ($mimetype != "image/gif" && in_array($mimetype, Image::supportedTypes())) {
$Image = new Image($data, $mimetype);
if ($Image->isValid()) {
if (isset($customres) && $customres > 0 && $customres < 500) {
@ -186,13 +175,10 @@ function photo_init(App $a) {
header("Content-type: " . $mimetype);
if ($prvcachecontrol) {
// it is a private photo that they have no permission to view.
// tell the browser not to cache it, in case they authenticate
// and subsequently have permission to see it
header("Cache-Control: no-store, no-cache, must-revalidate");
} else {
header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT");
header('Etag: "' . md5($data) . '"');
@ -202,7 +188,7 @@ function photo_init(App $a) {
echo $data;
// If the photo is public and there is an existing photo directory store the photo there
if ($public and ($file != "")) {
if ($public and $file != '') {
// If the photo path isn't there, try to create it
$basepath = $a->get_basepath();
if (!is_dir($basepath . "/photo")) {

View file

@ -28,7 +28,7 @@ function photos_init(App $a) {
auto_redir($a, $a->argv[1]);
}
if ((Config::get('system', 'block_public')) && (! local_user()) && (! remote_user())) {
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
return;
}
@ -54,17 +54,17 @@ function photos_init(App $a) {
$tpl = get_markup_template("vcard-widget.tpl");
$vcard_widget .= replace_macros($tpl, array(
$vcard_widget = replace_macros($tpl, array(
'$name' => $profile['name'],
'$photo' => $profile['photo'],
'$addr' => (($profile['addr'] != "") ? $profile['addr'] : ""),
'$addr' => defaults($profile, 'addr', ''),
'$account_type' => $account_type,
'$pdesc' => (($profile['pdesc'] != "") ? $profile['pdesc'] : ""),
'$pdesc' => defaults($profile, 'pdesc', ''),
));
$albums = photo_albums($a->data['user']['uid']);
$albums_visible = ((intval($a->data['user']['hidewall']) && (! local_user()) && (! remote_user())) ? false : true);
$albums_visible = ((intval($a->data['user']['hidewall']) && !local_user() && !remote_user()) ? false : true);
// add various encodings to the array so we can just loop through and pick them out in a template
$ret = array('success' => false);
@ -78,7 +78,7 @@ function photos_init(App $a) {
$ret['albums'] = array();
foreach ($albums as $k => $album) {
//hide profile photos to others
if ((! $is_owner) && (! remote_user()) && ($album['album'] == t('Profile Photos')))
if (!$is_owner && !remote_user() && ($album['album'] == t('Profile Photos')))
continue;
$entry = array(
'text' => $album['album'],
@ -91,18 +91,16 @@ function photos_init(App $a) {
}
}
$albums = $ret;
if (local_user() && $a->data['user']['uid'] == local_user()) {
$can_post = true;
}
if ($albums['success']) {
if ($ret['success']) {
$photo_albums_widget = replace_macros(get_markup_template('photo_albums.tpl'), array(
'$nick' => $a->data['user']['nickname'],
'$title' => t('Photo Albums'),
'$recent' => t('Recent Photos'),
'$albums' => $albums['albums'],
'$albums' => $ret['albums'],
'$baseurl' => System::baseUrl(),
'$upload' => array(t('Upload New Photos'), 'photos/' . $a->data['user']['nickname'] . '/upload'),
'$can_post' => $can_post
@ -116,24 +114,18 @@ function photos_init(App $a) {
$a->page['aside'] .= $vcard_widget;
$a->page['aside'] .= $photo_albums_widget;
$tpl = get_markup_template("photos_head.tpl");
$a->page['htmlhead'] .= replace_macros($tpl,array(
'$ispublic' => t('everybody')
));
}
return;
}
function photos_post(App $a) {
function photos_post(App $a)
{
logger('mod-photos: photos_post: begin' , LOGGER_DEBUG);
logger('mod_photos: REQUEST ' . print_r($_REQUEST, true), LOGGER_DATA);
logger('mod_photos: FILES ' . print_r($_FILES, true), LOGGER_DATA);
@ -143,14 +135,14 @@ function photos_post(App $a) {
$visitor = 0;
$page_owner_uid = $a->data['user']['uid'];
$community_page = (($a->data['user']['page-flags'] == PAGE_COMMUNITY) ? true : false);
$community_page = $a->data['user']['page-flags'] == PAGE_COMMUNITY;
if ((local_user()) && (local_user() == $page_owner_uid)) {
if (local_user() && (local_user() == $page_owner_uid)) {
$can_post = true;
} else {
if ($community_page && remote_user()) {
$contact_id = 0;
if (is_array($_SESSION['remote'])) {
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) {
if ($v['uid'] == $page_owner_uid) {
$contact_id = $v['cid'];
@ -159,7 +151,6 @@ function photos_post(App $a) {
}
}
if ($contact_id) {
$r = q("SELECT `uid` FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 AND `id` = %d AND `uid` = %d LIMIT 1",
intval($contact_id),
intval($page_owner_uid)
@ -190,8 +181,7 @@ function photos_post(App $a) {
$owner_record = $r[0];
if (($a->argc > 3) && ($a->argv[2] === 'album')) {
if ($a->argc > 3 && $a->argv[2] === 'album') {
$album = hex2bin($a->argv[3]);
if ($album === t('Profile Photos') || $album === 'Contact Photos' || $album === t('Contact Photos')) {
@ -214,10 +204,7 @@ function photos_post(App $a) {
goaway($_SESSION['photo_return']);
}
/*
* RENAME photo album
*/
// RENAME photo album
$newalbum = notags(trim($_POST['albumname']));
if ($newalbum != $album) {
q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d",
@ -238,9 +225,8 @@ function photos_post(App $a) {
*/
if ($_POST['dropalbum'] == t('Delete Album')) {
// Check if we should do HTML-based delete confirmation
if ($_REQUEST['confirm']) {
if (x($_REQUEST, 'confirm')) {
$drop_url = $a->query_string;
$extra_inputs = array(
array('name' => 'albumname', 'value' => $_POST['albumname']),
@ -286,14 +272,12 @@ function photos_post(App $a) {
$str_res = implode(',', $res);
// remove the associated photos
q("DELETE FROM `photo` WHERE `resource-id` IN ( $str_res ) AND `uid` = %d",
intval($page_owner_uid)
);
// find and delete the corresponding item with all the comments and likes/dislikes
$r = q("SELECT `parent-uri` FROM `item` WHERE `resource-id` IN ( $str_res ) AND `uid` = %d",
$r = q("SELECT `id`, `parent-uri`, `visible` FROM `item` WHERE `resource-id` IN ( $str_res ) AND `uid` = %d",
intval($page_owner_uid)
);
if (DBM::is_result($r)) {
@ -309,7 +293,6 @@ function photos_post(App $a) {
$drop_id = intval($rr['id']);
// send the notification upstream/downstream as the case may be
if ($rr['visible']) {
Worker::add(PRIORITY_HIGH, "Notifier", "drop", $drop_id);
}
@ -326,16 +309,16 @@ function photos_post(App $a) {
// Check if the user has responded to a delete confirmation query for a single photo
if (($a->argc > 2) && $_REQUEST['canceled']) {
if ($a->argc > 2 && x($_REQUEST, 'canceled')) {
goaway($_SESSION['photo_return']);
}
if (($a->argc > 2) && (x($_POST,'delete')) && ($_POST['delete'] == t('Delete Photo'))) {
if ($a->argc > 2 && defaults($_POST, 'delete', '') === t('Delete Photo')) {
// same as above but remove single photo
// Check if we should do HTML-based delete confirmation
if ($_REQUEST['confirm']) {
if (x($_REQUEST, 'confirm')) {
$drop_url = $a->query_string;
$a->page['content'] = replace_macros(get_markup_template('confirm.tpl'), array(
'$method' => 'post',
@ -367,7 +350,7 @@ function photos_post(App $a) {
intval($page_owner_uid),
dbesc($r[0]['resource-id'])
);
$i = q("SELECT * FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1",
$i = q("SELECT `id`, `uri`, `visible` FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1",
dbesc($r[0]['resource-id']),
intval($page_owner_uid)
);
@ -397,13 +380,12 @@ function photos_post(App $a) {
return; // NOTREACHED
}
if (($a->argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false)) || (x($_POST,'albname') !== false)) {
$desc = ((x($_POST,'desc')) ? notags(trim($_POST['desc'])) : '');
$rawtags = ((x($_POST,'newtag')) ? notags(trim($_POST['newtag'])) : '');
$item_id = ((x($_POST,'item_id')) ? intval($_POST['item_id']) : 0);
$albname = ((x($_POST,'albname')) ? notags(trim($_POST['albname'])) : '');
$origaname = ((x($_POST,'origaname')) ? notags(trim($_POST['origaname'])) : '');
if ($a->argc > 2 && (x($_POST, 'desc') !== false || x($_POST, 'newtag') !== false || x($_POST, 'albname') !== false)) {
$desc = x($_POST, 'desc') ? notags(trim($_POST['desc'])) : '';
$rawtags = x($_POST, 'newtag') ? notags(trim($_POST['newtag'])) : '';
$item_id = x($_POST, 'item_id') ? intval($_POST['item_id']) : 0;
$albname = x($_POST, 'albname') ? notags(trim($_POST['albname'])) : '';
$origaname = x($_POST, 'origaname') ? notags(trim($_POST['origaname'])) : '';
$str_group_allow = perms2str($_POST['group_allow']);
$str_contact_allow = perms2str($_POST['contact_allow']);
$str_group_deny = perms2str($_POST['group_deny']);
@ -415,9 +397,8 @@ function photos_post(App $a) {
$albname = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y');
}
if ((x($_POST,'rotate') !== false) &&
( (intval($_POST['rotate']) == 1) || (intval($_POST['rotate']) == 2) )) {
if (x($_POST,'rotate') !== false &&
(intval($_POST['rotate']) == 1 || intval($_POST['rotate']) == 2)) {
logger('rotate');
$r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `scale` = 0 LIMIT 1",
@ -503,9 +484,7 @@ function photos_post(App $a) {
}
if (!$item_id) {
// Create item container
$title = '';
$uri = item_new_uri($a->get_hostname(),$page_owner_uid);
@ -538,7 +517,6 @@ function photos_post(App $a) {
. '[/url]';
$item_id = item_store($arr);
}
if ($item_id) {
@ -553,12 +531,10 @@ function photos_post(App $a) {
}
if (strlen($rawtags)) {
$str_tags = '';
$inform = '';
// if the new tag doesn't have a namespace specifier (@foo or #foo) give it a hashtag
$x = substr($rawtags, 0, 1);
if ($x !== '@' && $x !== '#') {
$rawtags = '#' . $rawtags;
@ -569,10 +545,8 @@ function photos_post(App $a) {
if (count($tags)) {
foreach ($tags as $tag) {
if (isset($profile)) {
unset($profile);
}
if (strpos($tag, '@') === 0) {
$profile = '';
$name = substr($tag,1);
if ((strpos($name, '@')) || (strpos($name, 'http://'))) {
$newname = $name;
@ -690,7 +664,6 @@ function photos_post(App $a) {
if (count($taginfo)) {
foreach ($taginfo as $tagged) {
$uri = item_new_uri($a->get_hostname(), $page_owner_uid);
$arr = array();
@ -746,18 +719,12 @@ function photos_post(App $a) {
}
/**
* default post action - upload a photo
*/
// default post action - upload a photo
call_hooks('photo_post_init', $_POST);
/**
* Determine the album to use
*/
$album = notags(trim($_REQUEST['album']));
$newalbum = notags(trim($_REQUEST['newalbum']));
// Determine the album to use
$album = x($_REQUEST, 'album') ? notags(trim($_REQUEST['album'])) : '';
$newalbum = x($_REQUEST, 'newalbum') ? notags(trim($_REQUEST['newalbum'])) : '';
logger('mod/photos.php: photos_post(): album= ' . $album . ' newalbum= ' . $newalbum , LOGGER_DEBUG);
@ -781,20 +748,25 @@ function photos_post(App $a) {
dbesc($album),
intval($page_owner_uid)
);
if ((! DBM::is_result($r)) || ($album == t('Profile Photos'))) {
if (!DBM::is_result($r) || ($album == t('Profile Photos'))) {
$visible = 1;
} else {
$visible = 0;
}
if (intval($_REQUEST['not_visible']) || $_REQUEST['not_visible'] === 'true') {
if (x($_REQUEST, 'not_visible') && $_REQUEST['not_visible'] !== 'false') {
$visible = 0;
}
$str_group_allow = perms2str(((is_array($_REQUEST['group_allow'])) ? $_REQUEST['group_allow'] : explode(',', $_REQUEST['group_allow'])));
$str_contact_allow = perms2str(((is_array($_REQUEST['contact_allow'])) ? $_REQUEST['contact_allow'] : explode(',', $_REQUEST['contact_allow'])));
$str_group_deny = perms2str(((is_array($_REQUEST['group_deny'])) ? $_REQUEST['group_deny'] : explode(',', $_REQUEST['group_deny'])));
$str_contact_deny = perms2str(((is_array($_REQUEST['contact_deny'])) ? $_REQUEST['contact_deny'] : explode(',', $_REQUEST['contact_deny'])));
$group_allow = defaults($_REQUEST, 'group_allow' , []);
$contact_allow = defaults($_REQUEST, 'contact_allow', []);
$group_deny = defaults($_REQUEST, 'group_deny' , []);
$contact_deny = defaults($_REQUEST, 'contact_deny' , []);
$str_group_allow = perms2str(is_array($group_allow) ? $group_allow : explode(',', $group_allow));
$str_contact_allow = perms2str(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
$str_group_deny = perms2str(is_array($group_deny) ? $group_deny : explode(',', $group_deny));
$str_contact_deny = perms2str(is_array($contact_deny) ? $contact_deny : explode(',', $contact_deny));
$ret = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
@ -805,12 +777,41 @@ function photos_post(App $a) {
$filename = $ret['filename'];
$filesize = $ret['filesize'];
$type = $ret['type'];
$error = UPLOAD_ERR_OK;
} else {
$src = $_FILES['userfile']['tmp_name'];
$filename = basename($_FILES['userfile']['name']);
$filesize = intval($_FILES['userfile']['size']);
$type = $_FILES['userfile']['type'];
$error = $_FILES['userfile']['error'];
}
if ($error !== UPLOAD_ERR_OK) {
switch ($error) {
case UPLOAD_ERR_INI_SIZE:
notice(t('Image exceeds size limit of %s', ini_get('upload_max_filesize')) . EOL);
break;
case UPLOAD_ERR_FORM_SIZE:
notice(t('Image exceeds size limit of %s', formatBytes(defaults($_REQUEST, 'MAX_FILE_SIZE', 0))) . EOL);
break;
case UPLOAD_ERR_PARTIAL:
notice(t('Image upload didn\'t complete, please try again') . EOL);
break;
case UPLOAD_ERR_NO_FILE:
notice(t('Image file is missing') . EOL);
break;
case UPLOAD_ERR_NO_TMP_DIR:
case UPLOAD_ERR_CANT_WRITE:
case UPLOAD_ERR_EXTENSION:
notice(t('Server can\'t accept new file upload at this time, please contact your administrator') . EOL);
break;
}
@unlink($src);
$foo = 0;
call_hooks('photo_post_end', $foo);
return;
}
if ($type == "") {
$type = Image::guessType($filename);
}
@ -819,8 +820,8 @@ function photos_post(App $a) {
$maximagesize = Config::get('system', 'maximagesize');
if (($maximagesize) && ($filesize > $maximagesize)) {
notice( sprintf(t('Image exceeds size limit of %s'), formatBytes($maximagesize)) . EOL);
if ($maximagesize && ($filesize > $maximagesize)) {
notice(t('Image exceeds size limit of %s', formatBytes($maximagesize)) . EOL);
@unlink($src);
$foo = 0;
call_hooks('photo_post_end', $foo);
@ -888,23 +889,16 @@ function photos_post(App $a) {
$smallest = 2;
}
$basename = basename($filename);
$uri = item_new_uri($a->get_hostname(), $page_owner_uid);
// Create item container
$lat = $lon = null;
/// @TODO merge these 2 if() into one?
if ($exif && $exif['GPS']) {
if (Feature::isEnabled($channel_id,'photo_location')) {
if ($exif && $exif['GPS'] && Feature::isEnabled($channel_id, 'photo_location')) {
$lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
$lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
}
}
$arr = array();
if ($lat && $lon) {
$arr['coord'] = $lat . ' ' . $lon;
}
@ -946,17 +940,15 @@ function photos_post(App $a) {
call_hooks('photo_post_end',intval($item_id));
/*
* addon uploaders should call "killme()" [e.g. exit] within the photo_post_end hook
* if they do not wish to be redirected
*/
// addon uploaders should call "killme()" [e.g. exit] within the photo_post_end hook
// if they do not wish to be redirected
goaway($_SESSION['photo_return']);
// NOTREACHED
}
function photos_content(App $a) {
function photos_content(App $a)
{
// URLs:
// photos/name
// photos/name/upload
@ -966,8 +958,7 @@ function photos_content(App $a) {
// photos/name/image/xxxxx
// photos/name/image/xxxxx/edit
if ((Config::get('system', 'block_public')) && (! local_user()) && (! remote_user())) {
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
notice( t('Public access denied.') . EOL);
return;
}
@ -985,10 +976,8 @@ function photos_content(App $a) {
$_SESSION['photo_return'] = $a->cmd;
//
// Parse arguments
//
$datum = null;
if ($a->argc > 3) {
$datatype = $a->argv[2];
$datum = $a->argv[3];
@ -1004,10 +993,7 @@ function photos_content(App $a) {
$cmd = 'view';
}
//
// Setup permissions structures
//
$can_post = false;
$visitor = 0;
$contact = null;
@ -1018,7 +1004,7 @@ function photos_content(App $a) {
$community_page = (($a->data['user']['page-flags'] == PAGE_COMMUNITY) ? true : false);
if ((local_user()) && (local_user() == $owner_uid)) {
if (local_user() && (local_user() == $owner_uid)) {
$can_post = true;
} else {
if ($community_page && remote_user()) {
@ -1046,9 +1032,10 @@ function photos_content(App $a) {
}
}
// perhaps they're visiting - but not a community page, so they wouldn't have write access
$groups = [];
if (remote_user() && (! $visitor)) {
// perhaps they're visiting - but not a community page, so they wouldn't have write access
if (remote_user() && !$visitor) {
$contact_id = 0;
if (is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) {
@ -1071,15 +1058,12 @@ function photos_content(App $a) {
}
}
/// @TODO merge these 2 if() into one?
if (! $remote_contact) {
if (local_user()) {
if (!$remote_contact && local_user()) {
$contact_id = $_SESSION['cid'];
$contact = $a->contact;
}
}
if ($a->data['user']['hidewall'] && (local_user() != $owner_uid) && (! $remote_contact)) {
if ($a->data['user']['hidewall'] && (local_user() != $owner_uid) && !$remote_contact) {
notice( t('Access to this item is restricted.') . EOL);
return;
}
@ -1092,24 +1076,18 @@ function photos_content(App $a) {
$is_owner = (local_user() && (local_user() == $owner_uid));
$o .= profile_tabs($a, $is_owner, $a->data['user']['nickname']);
/**
* Display upload form
*/
// Display upload form
if ($datatype === 'upload') {
if (! ($can_post)) {
if (!$can_post) {
notice(t('Permission denied.'));
return;
}
$selname = (($datum) ? hex2bin($datum) : '');
$selname = $datum ? hex2bin($datum) : '';
$albumselect = '';
$albumselect .= '<option value="" ' . ((! $selname) ? ' selected="selected" ' : '') . '>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
$albumselect .= '<option value="" ' . (!$selname ? ' selected="selected" ' : '') . '>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
if (count($a->data['albums'])) {
foreach ($a->data['albums'] as $album) {
if (($album['album'] === '') || ($album['album'] === 'Contact Photos') || ($album['album'] === t('Contact Photos'))) {
@ -1135,32 +1113,9 @@ function photos_content(App $a) {
$usage_message = '';
// Private/public post links for the non-JS ACL form
$private_post = 1;
if ($_REQUEST['public']) {
$private_post = 0;
}
$query_str = $a->query_string;
if (strpos($query_str, 'public=1') !== false) {
$query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str);
}
/*
* I think $a->query_string may never have ? in it, but I could be wrong
* It looks like it's from the index.php?q=[etc] rewrite that the web
* server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
*/
if (strpos($query_str, '?') === false) {
$public_post_link = '?public=1';
} else {
$public_post_link = '&public=1';
}
$tpl = get_markup_template('photos_upload.tpl');
$albumselect_e = $albumselect;
$aclselect_e = (($visitor) ? '' : populate_acl($a->user));
$aclselect_e = ($visitor ? '' : populate_acl($a->user));
$o .= replace_macros($tpl,array(
'$pagename' => t('Upload Photos'),
@ -1170,35 +1125,26 @@ function photos_content(App $a) {
'$newalbum' => t('New album name: '),
'$existalbumtext' => t('or existing album name: '),
'$nosharetext' => t('Do not show a status post for this upload'),
'$albumselect' => $albumselect_e,
'$albumselect' => $albumselect,
'$permissions' => t('Permissions'),
'$aclselect' => $aclselect_e,
'$alt_uploader' => $ret['addon_text'],
'$default_upload_box' => (($ret['default_upload']) ? $default_upload_box : ''),
'$default_upload_submit' => (($ret['default_upload']) ? $default_upload_submit : ''),
'$default_upload_box' => ($ret['default_upload'] ? $default_upload_box : ''),
'$default_upload_submit' => ($ret['default_upload'] ? $default_upload_submit : ''),
'$uploadurl' => $ret['post_url'],
// ACL permissions box
'$acl_data' => construct_acl_data($a, $a->user), // For non-Javascript ACL selector
'$group_perms' => t('Show to Groups'),
'$contact_perms' => t('Show to Contacts'),
'$private' => t('Private Photo'),
'$public' => t('Public Photo'),
'$is_private' => $private_post,
'$return_path' => $query_str,
'$public_link' => $public_post_link,
'$return_path' => $a->query_string,
));
return $o;
}
/*
* Display a single photo album
*/
// Display a single photo album
if ($datatype === 'album') {
$album = hex2bin($datum);
$r = q("SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = %d AND `album` = '%s'
@ -1212,7 +1158,8 @@ function photos_content(App $a) {
}
/// @TODO I have seen this many times, maybe generalize it script-wide and encapsulate it?
if ($_GET['order'] === 'posted') {
$order_field = defaults($_GET, 'order', '');
if ($order_field === 'posted') {
$order = 'ASC';
} else {
$order = 'DESC';
@ -1253,7 +1200,7 @@ function photos_content(App $a) {
}
}
if ($_GET['order'] === 'posted') {
if ($order_field === 'posted') {
$order = array(t('Show Newest First'), 'photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album));
} else {
$order = array(t('Show Oldest First'), 'photos/' . $a->data['user']['nickname'] . '/album/' . bin2hex($album) . '?f=&order=posted');
@ -1261,14 +1208,11 @@ function photos_content(App $a) {
$photos = array();
if (DBM::is_result($r))
$twist = 'rotright';
if (DBM::is_result($r)) {
// "Twist" is only used for the duepunto theme with style "slackr"
$twist = false;
foreach ($r as $rr) {
if ($twist == 'rotright') {
$twist = 'rotleft';
} else {
$twist = 'rotright';
}
$twist = !$twist;
$ext = $phototypes[$rr['type']];
@ -1277,17 +1221,18 @@ function photos_content(App $a) {
$photos[] = array(
'id' => $rr['id'],
'twist' => ' ' . $twist . rand(2,4),
'twist' => ' ' . ($twist ? 'rotleft' : 'rotright') . rand(2,4),
'link' => 'photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id']
. (($_GET['order'] === 'posted') ? '?f=&order=posted' : ''),
. ($order_field === 'posted' ? '?f=&order=posted' : ''),
'title' => t('View Photo'),
'src' => 'photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.' .$ext,
'alt' => $imgalt_e,
'desc'=> $desc_e,
'ext' => $ext,
'hash'=> $rr['resource_id'],
'hash'=> $rr['resource-id'],
);
}
}
$tpl = get_markup_template('photo_album.tpl');
$o .= replace_macros($tpl, array(
@ -1304,14 +1249,9 @@ function photos_content(App $a) {
}
/*
* Display one photo
*/
// Display one photo
if ($datatype === 'image') {
//$o = '';
// fetch image, item containing image, then comments
$ph = q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'
$sql_extra ORDER BY `scale` ASC ",
intval($owner_uid),
@ -1339,10 +1279,12 @@ function photos_content(App $a) {
// The query leads to a really intense used index.
// By now we hide it if someone wants to.
if (!Config::get('system', 'no_count', false)) {
if ($_GET['order'] === 'posted')
$order_field = defaults($_GET, 'order', '');
if ($order_field === 'posted') {
$order = 'ASC';
else
} else {
$order = 'DESC';
}
$prvnxt = q("SELECT `resource-id` FROM `photo` WHERE `album` = '%s' AND `uid` = %d AND `scale` = 0
$sql_extra ORDER BY `created` $order ",
@ -1364,9 +1306,9 @@ function photos_content(App $a) {
break;
}
}
$edit_suffix = ((($cmd === 'edit') && ($can_post)) ? '/edit' : '');
$prevlink = 'photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
$nextlink = 'photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix . (($_GET['order'] === 'posted') ? '?f=&order=posted' : '');
$edit_suffix = ((($cmd === 'edit') && $can_post) ? '/edit' : '');
$prevlink = 'photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$prv]['resource-id'] . $edit_suffix . ($order_field === 'posted' ? '?f=&order=posted' : '');
$nextlink = 'photos/' . $a->data['user']['nickname'] . '/image/' . $prvnxt[$nxt]['resource-id'] . $edit_suffix . ($order_field === 'posted' ? '?f=&order=posted' : '');
}
}
@ -1440,6 +1382,7 @@ function photos_content(App $a) {
);
$map = null;
$link_item = [];
if (DBM::is_result($linked_items)) {
$link_item = $linked_items[0];
@ -1479,7 +1422,7 @@ function photos_content(App $a) {
);
if ((local_user()) && (local_user() == $link_item['uid'])) {
if (local_user() && (local_user() == $link_item['uid'])) {
q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d",
intval($link_item['parent']),
intval(local_user())
@ -1513,31 +1456,9 @@ function photos_content(App $a) {
$edit = Null;
if (($cmd === 'edit') && ($can_post)) {
if ($cmd === 'edit' && $can_post) {
$edit_tpl = get_markup_template('photo_edit.tpl');
// Private/public post links for the non-JS ACL form
$private_post = 1;
if ($_REQUEST['public']) {
$private_post = 0;
}
$query_str = $a->query_string;
if (strpos($query_str, 'public=1') !== false) {
$query_str = str_replace(array('?public=1', '&public=1'), array('', ''), $query_str);
}
/*
* I think $a->query_string may never have ? in it, but I could be wrong
* It looks like it's from the index.php?q=[etc] rewrite that the web
* server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
*/
if (strpos($query_str, '?') === false) {
$public_post_link = '?public=1';
} else {
$public_post_link = '&public=1';
}
$album_e = $ph[0]['album'];
$caption_e = $ph[0]['desc'];
$aclselect_e = populate_acl($ph[0]);
@ -1556,7 +1477,7 @@ function photos_content(App $a) {
'$permissions' => t('Permissions'),
'$aclselect' => $aclselect_e,
'$item_id' => ((count($linked_items)) ? $link_item['id'] : 0),
'$item_id' => defaults($link_item, 'id', 0),
'$submit' => t('Submit'),
'$delete' => t('Delete Photo'),
@ -1564,25 +1485,24 @@ function photos_content(App $a) {
'$acl_data' => construct_acl_data($a, $ph[0]), // For non-Javascript ACL selector
'$group_perms' => t('Show to Groups'),
'$contact_perms' => t('Show to Contacts'),
'$private' => t('Private photo'),
'$public' => t('Public photo'),
'$is_private' => $private_post,
'$return_path' => $query_str,
'$public_link' => $public_post_link,
'$return_path' => $a->query_string,
));
}
if (count($linked_items)) {
$like = '';
$dislike = '';
$likebuttons = '';
$comments = '';
$paginate = '';
$responses = '';
if (count($linked_items)) {
$cmnt_tpl = get_markup_template('comment_item.tpl');
$tpl = get_markup_template('photo_item.tpl');
$return_url = $a->cmd;
$like_tpl = get_markup_template('like_noshare.tpl');
$likebuttons = '';
if ($can_post || can_write_wall($a, $owner_uid)) {
$like_tpl = get_markup_template('like_noshare.tpl');
$likebuttons = replace_macros($like_tpl, array(
'$id' => $link_item['id'],
'$likethis' => t("I like this \x28toggle\x29"),
@ -1592,7 +1512,6 @@ function photos_content(App $a) {
));
}
$comments = '';
if (!DBM::is_result($r)) {
if (($can_post || can_write_wall($a, $owner_uid)) && $link_item['last-child']) {
$comments .= replace_macros($cmnt_tpl, array(
@ -1615,12 +1534,6 @@ function photos_content(App $a) {
}
}
$alike = array();
$dlike = array();
$like = '';
$dislike = '';
$conv_responses = array(
'like' => array('title' => t('Likes','title')),'dislike' => array('title' => t('Dislikes','title')),
'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title'))
@ -1628,13 +1541,16 @@ function photos_content(App $a) {
// display comments
if (DBM::is_result($r)) {
foreach ($r as $item) {
builtin_activity_puller($item, $conv_responses);
}
$like = ((x($conv_responses['like'], $link_item['uri'])) ? format_like($conv_responses['like'][$link_item['uri']], $conv_responses['like'][$link_item['uri'] . '-l'], 'like',$link_item['id']) : '');
$dislike = ((x($conv_responses['dislike'], $link_item['uri'])) ? format_like($conv_responses['dislike'][$link_item['uri']], $conv_responses['dislike'][$link_item['uri'] . '-l'], 'dislike',$link_item['id']) : '');
if (x($conv_responses['like'], $link_item['uri'])) {
$like = format_like($conv_responses['like'][$link_item['uri']], $conv_responses['like'][$link_item['uri'] . '-l'], 'like', $link_item['id']);
}
if (x($conv_responses['dislike'], $link_item['uri'])) {
$dislike = format_like($conv_responses['dislike'][$link_item['uri']], $conv_responses['dislike'][$link_item['uri'] . '-l'], 'dislike', $link_item['id']);
}
if (($can_post || can_write_wall($a, $owner_uid)) && $link_item['last-child']) {
$comments .= replace_macros($cmnt_tpl,array(
@ -1656,20 +1572,19 @@ function photos_content(App $a) {
));
}
foreach ($r as $item) {
$comment = '';
$template = $tpl;
$sparkle = '';
if (((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE))) && ($item['id'] != $item['parent']))
if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && ($item['id'] != $item['parent'])) {
continue;
}
$redirect_url = 'redir/' . $item['cid'];
if (local_user() && ($item['contact-uid'] == local_user())
&& ($item['network'] == NETWORK_DFRN) && (! $item['self'] )) {
&& ($item['network'] == NETWORK_DFRN) && !$item['self']) {
$profile_url = $redirect_url;
$sparkle = ' sparkle';
} else {
@ -1679,8 +1594,8 @@ function photos_content(App $a) {
$diff_author = (($item['url'] !== $item['author-link']) ? true : false);
$profile_name = (((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']);
$profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $item['thumb']);
$profile_name = ((strlen($item['author-name']) && $diff_author) ? $item['author-name'] : $item['name']);
$profile_avatar = ((strlen($item['author-avatar']) && $diff_author) ? $item['author-avatar'] : $item['thumb']);
$profile_link = $profile_url;
@ -1731,40 +1646,32 @@ function photos_content(App $a) {
}
}
}
$paginate = paginate($a);
}
$response_verbs = array('like');
if (Feature::isEnabled($owner_uid, 'dislike')) {
$response_verbs[] = 'dislike';
}
$responses = get_responses($conv_responses, $response_verbs, '', $link_item);
$paginate = paginate($a);
}
$photo_tpl = get_markup_template('photo_view.tpl');
$album_e = array($album_link, $ph[0]['album']);
$tags_e = $tags;
$like_e = $like;
$dislike_e = $dislike;
$o .= replace_macros($photo_tpl, array(
'$id' => $ph[0]['id'],
'$album' => $album_e,
'$album' => [$album_link, $ph[0]['album']],
'$tools' => $tools,
'$lock' => $lock,
'$photo' => $photo,
'$prevlink' => $prevlink,
'$nextlink' => $nextlink,
'$desc' => $ph[0]['desc'],
'$tags' => $tags_e,
'$tags' => $tags,
'$edit' => $edit,
'$map' => $map,
'$map_text' => t('Map'),
'$likebuttons' => $likebuttons,
'$like' => $like_e,
'$dislike' => $dikslike_e,
'$like' => $like,
'$dislike' => $dislike,
'responses' => $responses,
'$comments' => $comments,
'$paginate' => $paginate,
@ -1807,16 +1714,14 @@ function photos_content(App $a) {
$photos = array();
if (DBM::is_result($r)) {
$twist = 'rotright';
// "Twist" is only used for the duepunto theme with style "slackr"
$twist = false;
foreach ($r as $rr) {
//hide profile photos to others
if ((! $is_owner) && (! remote_user()) && ($rr['album'] == t('Profile Photos')))
if (!$is_owner && !remote_user() && ($rr['album'] == t('Profile Photos')))
continue;
if ($twist == 'rotright')
$twist = 'rotleft';
else
$twist = 'rotright';
$twist = !$twist;
$ext = $phototypes[$rr['type']];
@ -1825,7 +1730,7 @@ function photos_content(App $a) {
$photos[] = array(
'id' => $rr['id'],
'twist' => ' ' . $twist . rand(2,4),
'twist' => ' ' . ($twist ? 'rotleft' : 'rotright') . rand(2,4),
'link' => 'photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'],
'title' => t('View Photo'),
'src' => 'photo/' . $rr['resource-id'] . '-' . ((($rr['scale']) == 6) ? 4 : $rr['scale']) . '.' . $ext,

View file

@ -164,8 +164,8 @@ function ping_init(App $a)
if (intval(Feature::isEnabled(local_user(), 'forumlist_widget'))) {
$forum_counts = ForumManager::countUnseenItems();
if (DBM::is_result($forums_counts)) {
foreach ($forums_counts as $forum_count) {
if (DBM::is_result($forum_counts)) {
foreach ($forum_counts as $forum_count) {
if ($forum_count['count'] > 0) {
$forums_unseen[] = $forum_count;
}
@ -490,8 +490,10 @@ function ping_get_notifications($uid)
$notification["href"] = System::baseUrl() . "/notify/view/" . $notification["id"];
if ($notification["visible"] && !$notification["spam"]
&& !$notification["deleted"] && !is_array($result[$notification["parent"]])
if ($notification["visible"]
&& !$notification["spam"]
&& !$notification["deleted"]
&& !(x($result, $notification["parent"]) && is_array($result[$notification["parent"]]))
) {
// Should we condense the notifications or show them all?
if (PConfig::get(local_user(), 'system', 'detailed_notif')) {

View file

@ -6,22 +6,22 @@ use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Database\DBM;
require_once('include/contact_widgets.php');
require_once('include/redir.php');
require_once 'include/contact_widgets.php';
require_once 'include/redir.php';
function profile_init(App $a) {
if(! x($a->page,'aside'))
function profile_init(App $a)
{
if (!x($a->page, 'aside')) {
$a->page['aside'] = '';
}
if($a->argc > 1)
if ($a->argc > 1) {
$which = htmlspecialchars($a->argv[1]);
else {
$r = q("select nickname from user where blocked = 0 and account_expired = 0 and account_removed = 0 and verified = 1 order by rand() limit 1");
} else {
$r = q("SELECT `nickname` FROM `user` WHERE `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 ORDER BY RAND() LIMIT 1");
if (DBM::is_result($r)) {
goaway(System::baseUrl() . '/profile/' . $r[0]['nickname']);
}
else {
} else {
logger('profile error: mod_profile ' . $a->query_string, LOGGER_DEBUG);
notice(t('Requested profile is not available.') . EOL);
$a->error = 404;
@ -30,40 +30,44 @@ function profile_init(App $a) {
}
$profile = 0;
if((local_user()) && ($a->argc > 2) && ($a->argv[2] === 'view')) {
if (local_user() && $a->argc > 2 && $a->argv[2] === 'view') {
$which = $a->user['nickname'];
$profile = htmlspecialchars($a->argv[1]);
}
else {
} else {
auto_redir($a, $which);
}
profile_load($a, $which, $profile);
$blocked = (((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false);
$userblock = (($a->profile['hidewall'] && (! local_user()) && (! remote_user())) ? true : false);
$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'] == PAGE_COMMUNITY)) {
if (x($a->profile, 'page-flags') && $a->profile['page-flags'] == PAGE_COMMUNITY) {
$a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />';
}
if (x($a->profile, 'openidserver')) {
$a->page['htmlhead'] .= '<link rel="openid.server" href="' . $a->profile['openidserver'] . '" />' . "\r\n";
}
if (x($a->profile, 'openid')) {
$delegate = ((strstr($a->profile['openid'],'://')) ? $a->profile['openid'] : 'https://' . $a->profile['openid']);
$delegate = strstr($a->profile['openid'], '://') ? $a->profile['openid'] : 'https://' . $a->profile['openid'];
$a->page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\r\n";
}
// site block
if ((! $blocked) && (! $userblock)) {
$keywords = ((x($a->profile,'pub_keywords')) ? $a->profile['pub_keywords'] : '');
$keywords = str_replace(array('#',',',' ',',,'),array('',' ',',',','),$keywords);
if(strlen($keywords))
if (!$blocked && !$userblock) {
$keywords = str_replace(array('#', ',', ' ', ',,'), array('', ' ', ',', ','), defaults($a->profile, 'pub_keywords', ''));
if (strlen($keywords)) {
$a->page['htmlhead'] .= '<meta name="keywords" content="' . $keywords . '" />' . "\r\n";
}
}
$a->page['htmlhead'] .= '<meta name="dfrn-global-visibility" content="' . (($a->profile['net-publish']) ? 'true' : 'false') . '" />' . "\r\n" ;
$a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . System::baseUrl() . '/dfrn_poll/' . $which .'" />' . "\r\n" ;
$uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : ''));
$a->page['htmlhead'] .= '<meta name="dfrn-global-visibility" content="' . ($a->profile['net-publish'] ? 'true' : 'false') . '" />' . "\r\n";
$a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . System::baseUrl() . '/feed/' . $which . '/" title="' . t('%s\'s posts', $a->profile['username']) . '"/>' . "\r\n";
$a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . System::baseUrl() . '/feed/' . $which . '/comments" title="' . t('%s\'s comments', $a->profile['username']) . '"/>' . "\r\n";
$a->page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . System::baseUrl() . '/feed/' . $which . '/activity" title="' . t('%s\'s timeline', $a->profile['username']) . '"/>' . "\r\n";
$uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . ($a->path ? '/' . $a->path : ''));
$a->page['htmlhead'] .= '<link rel="lrdd" type="application/xrd+xml" href="' . System::baseUrl() . '/xrd/?uri=' . $uri . '" />' . "\r\n";
header('Link: <' . System::baseUrl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false);
@ -71,13 +75,11 @@ function profile_init(App $a) {
foreach ($dfrn_pages as $dfrn) {
$a->page['htmlhead'] .= "<link rel=\"dfrn-{$dfrn}\" href=\"" . System::baseUrl() . "/dfrn_{$dfrn}/{$which}\" />\r\n";
}
$a->page['htmlhead'] .= "<link rel=\"dfrn-poco\" href=\"".System::baseUrl()."/poco/{$which}\" />\r\n";
$a->page['htmlhead'] .= '<link rel="dfrn-poco" href="' . System::baseUrl() . "/poco/{$which}\" />\r\n";
}
function profile_content(App $a, $update = 0) {
function profile_content(App $a, $update = 0)
{
$category = $datequery = $datequery2 = '';
if ($a->argc > 2) {
@ -95,20 +97,20 @@ function profile_content(App $a, $update = 0) {
}
if (!x($category)) {
$category = ((x($_GET,'category')) ? $_GET['category'] : '');
$category = defaults($_GET, 'category', '');
}
$hashtags = (x($_GET, 'tag') ? $_GET['tag'] : '');
$hashtags = defaults($_GET, 'tag', '');
if (Config::get('system','block_public') && (! local_user()) && (! remote_user())) {
if (Config::get('system', 'block_public') && !local_user() && !remote_user()) {
return login();
}
require_once("include/bbcode.php");
require_once('include/security.php');
require_once('include/conversation.php');
require_once('include/acl_selectors.php');
require_once('include/items.php');
require_once 'include/bbcode.php';
require_once 'include/security.php';
require_once 'include/conversation.php';
require_once 'include/acl_selectors.php';
require_once 'include/items.php';
$groups = array();
@ -127,7 +129,7 @@ function profile_content(App $a, $update = 0) {
$contact_id = 0;
if (is_array($_SESSION['remote'])) {
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $v) {
if ($v['uid'] == $a->profile['profile_uid']) {
$contact_id = $v['cid'];
@ -155,15 +157,16 @@ function profile_content(App $a, $update = 0) {
}
}
$is_owner = ((local_user()) && (local_user() == $a->profile['profile_uid']) ? true : false);
$is_owner = local_user() == $a->profile['profile_uid'];
$last_updated_key = "profile:" . $a->profile['profile_uid'] . ":" . local_user() . ":" . remote_user();
if ($a->profile['hidewall'] && (! $is_owner) && (! $remote_contact)) {
if (x($a->profile, 'hidewall') && !$is_owner && !$remote_contact) {
notice(t('Access to this profile has been restricted.') . EOL);
return;
}
if (!$update) {
$tab = false;
if (x($_GET, 'tab')) {
$tab = notags(trim($_GET['tab']));
}
@ -178,32 +181,34 @@ function profile_content(App $a, $update = 0) {
$o .= common_friends_visitor_widget($a->profile['profile_uid']);
if (x($_SESSION,'new_member') && $_SESSION['new_member'] && $is_owner) {
if (x($_SESSION, 'new_member') && $is_owner) {
$o .= '<a href="newmember" id="newmember-tips" style="font-size: 1.2em;"><b>' . t('Tips for New Members') . '</b></a>' . EOL;
}
$commpage = (($a->profile['page-flags'] == PAGE_COMMUNITY) ? true : false);
$commvisitor = (($commpage && $remote_contact == true) ? true : false);
$commpage = $a->profile['page-flags'] == PAGE_COMMUNITY;
$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'] .= categories_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (x($category) ? xmlify($category) : ''));
$a->page['aside'] .= tagcloud_wall_widget();
if (can_write_wall($a, $a->profile['profile_uid'])) {
$x = array(
'is_owner' => $is_owner,
'allow_location' => ((($is_owner || $commvisitor) && $a->profile['allow_location']) ? true : false),
'default_location' => (($is_owner) ? $a->user['default-location'] : ''),
'allow_location' => ($is_owner || $commvisitor) && $a->profile['allow_location'],
'default_location' => $is_owner ? $a->user['default-location'] : '',
'nickname' => $a->profile['nickname'],
'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'),
'acl' => (($is_owner) ? populate_acl($a->user, true) : ''),
'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',
'acl' => $is_owner ? populate_acl($a->user, true) : '',
'bang' => '',
'visitor' => (($is_owner || $commvisitor) ? 'block' : 'none'),
'visitor' => $is_owner || $commvisitor ? 'block' : 'none',
'profile_uid' => $a->profile['profile_uid'],
'acl_data' => ( $is_owner ? construct_acl_data($a, $a->user) : '' ), // For non-Javascript ACL selector
'acl_data' => $is_owner ? construct_acl_data($a, $a->user) : '', // For non-Javascript ACL selector
);
$o .= status_editor($a, $x);
@ -211,11 +216,9 @@ function profile_content(App $a, $update = 0) {
}
/**
* Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
*/
// Get permissions SQL - if $remote_contact is true, our remote user has been pre-verified and we already have fetched his/her groups
$sql_extra = item_permissions_sql($a->profile['profile_uid'], $remote_contact, $groups);
$sql_extra2 = '';
if ($update) {
$last_updated = (x($_SESSION['last_updated'], $last_updated_key) ? $_SESSION['last_updated'][$last_updated_key] : 0);
@ -247,14 +250,12 @@ function profile_content(App $a, $update = 0) {
if (!DBM::is_result($r)) {
return '';
}
} else {
$sql_post_table = "";
if (x($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` ",
dbesc(protect_sprintf($category)), intval(TERM_OBJ_POST), intval(TERM_CATEGORY), intval($a->profile['profile_uid']));
//$sql_extra .= protect_sprintf(file_tag_file_query('item',$category,'category'));
}
if (x($hashtags)) {
@ -274,7 +275,8 @@ function profile_content(App $a, $update = 0) {
$r = q("SELECT `uid` FROM `user` WHERE `uid` = %d AND `page-flags` IN (%d, %d)",
intval($a->profile['profile_uid']),
intval(PAGE_COMMUNITY),
intval(PAGE_PRVGROUP));
intval(PAGE_PRVGROUP)
);
if (!DBM::is_result($r)) {
$sql_extra3 = sprintf(" AND `thread`.`contact-id` = %d ", intval(intval($a->profile['contact_id'])));
@ -283,16 +285,16 @@ function profile_content(App $a, $update = 0) {
// check if we serve a mobile device and get the user settings
// accordingly
if ($a->is_mobile) {
$itemspage_network = PConfig::get(local_user(),'system','itemspage_mobile_network');
$itemspage_network = ((intval($itemspage_network)) ? $itemspage_network : 10);
$itemspage_network = PConfig::get(local_user(), 'system', 'itemspage_mobile_network', 10);
} else {
$itemspage_network = PConfig::get(local_user(),'system','itemspage_network');
$itemspage_network = ((intval($itemspage_network)) ? $itemspage_network : 20);
$itemspage_network = PConfig::get(local_user(), 'system', 'itemspage_network', 20);
}
// now that we have the user settings, see if the theme forces
// a maximum item number which is lower then the user choice
if(($a->force_max_items > 0) && ($a->force_max_items < $itemspage_network))
if (($a->force_max_items > 0) && ($a->force_max_items < $itemspage_network)) {
$itemspage_network = $a->force_max_items;
}
$a->set_pager_itemspage($itemspage_network);
@ -312,7 +314,6 @@ function profile_content(App $a, $update = 0) {
ORDER BY `thread`.`created` DESC $pager_sql",
intval($a->profile['profile_uid'])
);
}
$parents_arr = array();
@ -323,8 +324,10 @@ function profile_content(App $a, $update = 0) {
$_SESSION['last_updated'][$last_updated_key] = time();
if (DBM::is_result($r)) {
foreach($r as $rr)
foreach ($r as $rr) {
$parents_arr[] = $rr['item_id'];
}
$parents_str = implode(', ', $parents_arr);
$items = q(item_query() . " AND `item`.`uid` = %d
@ -339,7 +342,7 @@ function profile_content(App $a, $update = 0) {
$items = array();
}
if($is_owner && (! $update) && (! Config::get('theme','hide_eventlist'))) {
if ($is_owner && !$update && !Config::get('theme', 'hide_eventlist')) {
$o .= get_birthdays();
$o .= get_events();
}

View file

@ -9,8 +9,6 @@ use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Protocol\Diaspora;
require_once 'include/crypto.php';
/**
* @param object $a App
* @return void

View file

@ -7,8 +7,8 @@ use Friendica\Core\PConfig;
use Friendica\Database\DBM;
use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon;
use Friendica\Util\Crypto;
require_once 'include/crypto.php';
require_once 'include/items.php';
require_once 'include/follow.php';
@ -117,23 +117,23 @@ function salmon_post(App $a) {
logger('mod-salmon: key details: ' . print_r($key_info,true), LOGGER_DEBUG);
$pubkey = metopem($m,$e);
$pubkey = Crypto::meToPem($m, $e);
// We should have everything we need now. Let's see if it verifies.
// Try GNU Social format
$verify = rsa_verify($signed_data, $signature, $pubkey);
$verify = Crypto::rsaVerify($signed_data, $signature, $pubkey);
$mode = 1;
if (! $verify) {
logger('mod-salmon: message did not verify using protocol. Trying compliant format.');
$verify = rsa_verify($compliant_format, $signature, $pubkey);
$verify = Crypto::rsaVerify($compliant_format, $signature, $pubkey);
$mode = 2;
}
if (! $verify) {
logger('mod-salmon: message did not verify using padding. Trying old statusnet format.');
$verify = rsa_verify($stnet_signed_data, $signature, $pubkey);
$verify = Crypto::rsaVerify($stnet_signed_data, $signature, $pubkey);
$mode = 3;
}

View file

@ -7,11 +7,11 @@ use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Model\Contact;
require_once('include/items.php');
require_once('include/acl_selectors.php');
require_once('include/bbcode.php');
require_once('include/security.php');
require_once('include/redir.php');
require_once 'include/items.php';
require_once 'include/acl_selectors.php';
require_once 'include/bbcode.php';
require_once 'include/security.php';
require_once 'include/redir.php';
function videos_init(App $a) {
@ -44,12 +44,12 @@ function videos_init(App $a) {
$tpl = get_markup_template("vcard-widget.tpl");
$vcard_widget .= replace_macros($tpl, array(
$vcard_widget = replace_macros($tpl, array(
'$name' => $profile['name'],
'$photo' => $profile['photo'],
'$addr' => (($profile['addr'] != "") ? $profile['addr'] : ""),
'$addr' => defaults($profile, 'addr', ''),
'$account_type' => $account_type,
'$pdesc' => (($profile['pdesc'] != "") ? $profile['pdesc'] : ""),
'$pdesc' => defaults($profile, 'pdesc', ''),
));
@ -280,8 +280,9 @@ function videos_content(App $a) {
}
}
// perhaps they're visiting - but not a community page, so they wouldn't have write access
$groups = [];
// perhaps they're visiting - but not a community page, so they wouldn't have write access
if(remote_user() && (! $visitor)) {
$contact_id = 0;
if(is_array($_SESSION['remote'])) {

View file

@ -1,12 +1,14 @@
<?php
/**
* @file mod/xrd.php
*/
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Protocol\Salmon;
require_once('include/crypto.php');
function xrd_init(App $a) {
function xrd_init(App $a)
{
if ($a->argv[0] == 'xrd') {
$uri = urldecode(notags(trim($_GET['uri'])));
if ($_SERVER['HTTP_ACCEPT'] == 'application/jrd+json') {
@ -54,8 +56,9 @@ function xrd_init(App $a) {
}
}
function xrd_json($a, $uri, $alias, $profile_url, $r) {
$salmon_key = salmon_key($r['spubkey']);
function xrd_json($a, $uri, $alias, $profile_url, $r)
{
$salmon_key = Salmon::salmonKey($r['spubkey']);
header('Access-Control-Allow-Origin: *');
header("Content-type: application/json; charset=utf-8");
@ -79,8 +82,9 @@ function xrd_json($a, $uri, $alias, $profile_url, $r) {
killme();
}
function xrd_xml($a, $uri, $alias, $profile_url, $r) {
$salmon_key = salmon_key($r['spubkey']);
function xrd_xml($a, $uri, $alias, $profile_url, $r)
{
$salmon_key = Salmon::salmonKey($r['spubkey']);
header('Access-Control-Allow-Origin: *');
header("Content-type: text/xml");
@ -100,8 +104,8 @@ function xrd_xml($a, $uri, $alias, $profile_url, $r) {
'$salmon' => System::baseUrl() . '/salmon/' . $r['nickname'],
'$salmen' => System::baseUrl() . '/salmon/' . $r['nickname'] . '/mention',
'$subscribe' => System::baseUrl() . '/follow?url={uri}',
'$modexp' => 'data:application/magic-public-key,' . $salmon_key,
));
'$modexp' => 'data:application/magic-public-key,' . $salmon_key)
);
$arr = array('user' => $r, 'xml' => $o);
call_hooks('personal_xrd', $arr);

View file

@ -37,6 +37,7 @@ class App {
public $query_string;
public $config;
public $page;
public $page_offset;
public $profile;
public $profile_uid;
public $user;

355
src/Content/OEmbed.php Normal file
View file

@ -0,0 +1,355 @@
<?php
/**
* @file src/Content/OEmbed.php
*/
namespace Friendica\Content;
use Friendica\Core\Cache;
use Friendica\Core\System;
use Friendica\ParseUrl;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use dba;
use DOMDocument;
use DOMXPath;
use DOMNode;
require_once 'include/dba.php';
require_once 'mod/proxy.php';
/**
* Handles all OEmbed content fetching and replacement
*
* OEmbed is a standard used to allow an embedded representation of a URL on
* third party sites
*
* @see https://oembed.com
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class OEmbed
{
public static function replaceCallback($matches)
{
$embedurl = $matches[1];
$j = self::fetchURL($embedurl);
$s = self::formatObject($j);
return $s;
}
/**
* @brief Get data from an URL to embed its content.
*
* @param string $embedurl The URL from which the data should be fetched.
* @param bool $no_rich_type If set to true rich type content won't be fetched.
*
* @return bool|object Returns object with embed content or false if no embedable
* content exists
*/
public static function fetchURL($embedurl, $no_rich_type = false)
{
$embedurl = trim($embedurl, "'");
$embedurl = trim($embedurl, '"');
$a = get_app();
$condition = array('url' => normalise_link($embedurl));
$r = dba::select('oembed', array('content'), $condition, array('limit' => 1));
if (DBM::is_result($r)) {
$txt = $r["content"];
} else {
$txt = Cache::get($a->videowidth . $embedurl);
}
// These media files should now be caught in bbcode.php
// left here as a fallback in case this is called from another source
$noexts = array("mp3", "mp4", "ogg", "ogv", "oga", "ogm", "webm");
$ext = pathinfo(strtolower($embedurl), PATHINFO_EXTENSION);
if (is_null($txt)) {
$txt = "";
if (!in_array($ext, $noexts)) {
// try oembed autodiscovery
$redirects = 0;
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*");
if ($html_text) {
$dom = @DOMDocument::loadHTML($html_text);
if ($dom) {
$xpath = new DOMXPath($dom);
$entries = $xpath->query("//link[@type='application/json+oembed']");
foreach ($entries as $e) {
$href = $e->getAttributeNode("href")->nodeValue;
$txt = fetch_url($href . '&maxwidth=' . $a->videowidth);
break;
}
$entries = $xpath->query("//link[@type='text/json+oembed']");
foreach ($entries as $e) {
$href = $e->getAttributeNode("href")->nodeValue;
$txt = fetch_url($href . '&maxwidth=' . $a->videowidth);
break;
}
}
}
}
$txt = trim($txt);
if (!$txt || $txt[0] != "{") {
$txt = '{"type":"error"}';
} else { //save in cache
$j = json_decode($txt);
if ($j->type != "error") {
dba::insert('oembed', array('url' => normalise_link($embedurl),
'content' => $txt, 'created' => datetime_convert()), true);
}
Cache::set($a->videowidth . $embedurl, $txt, CACHE_DAY);
}
}
$j = json_decode($txt);
if (!is_object($j)) {
return false;
}
// Always embed the SSL version
if (isset($j->html)) {
$j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"), array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html);
}
$j->embedurl = $embedurl;
// If fetching information doesn't work, then improve via internal functions
if (($j->type == "error") || ($no_rich_type && ($j->type == "rich"))) {
$data = ParseUrl::getSiteinfoCached($embedurl, true, false);
$j->type = $data["type"];
if ($j->type == "photo") {
$j->url = $data["url"];
//$j->width = $data["images"][0]["width"];
//$j->height = $data["images"][0]["height"];
}
if (isset($data["title"])) {
$j->title = $data["title"];
}
if (isset($data["text"])) {
$j->description = $data["text"];
}
if (is_array($data["images"])) {
$j->thumbnail_url = $data["images"][0]["src"];
$j->thumbnail_width = $data["images"][0]["width"];
$j->thumbnail_height = $data["images"][0]["height"];
}
}
call_hooks('oembed_fetch_url', $embedurl, $j);
return $j;
}
public static function formatObject($j)
{
$embedurl = $j->embedurl;
$jhtml = self::iframe($j->embedurl, (isset($j->width) ? $j->width : null), (isset($j->height) ? $j->height : null));
$ret = "<span class='oembed " . $j->type . "'>";
switch ($j->type) {
case "video":
if (isset($j->thumbnail_url)) {
$tw = (isset($j->thumbnail_width) && intval($j->thumbnail_width)) ? $j->thumbnail_width : 200;
$th = (isset($j->thumbnail_height) && intval($j->thumbnail_height)) ? $j->thumbnail_height : 180;
// make sure we don't attempt divide by zero, fallback is a 1:1 ratio
$tr = (($th) ? $tw / $th : 1);
$th = 120;
$tw = $th * $tr;
$tpl = get_markup_template('oembed_video.tpl');
$ret.=replace_macros($tpl, array(
'$baseurl' => System::baseUrl(),
'$embedurl' => $embedurl,
'$escapedhtml' => base64_encode($jhtml),
'$tw' => $tw,
'$th' => $th,
'$turl' => $j->thumbnail_url,
));
} else {
$ret = $jhtml;
}
//$ret.="<br>";
break;
case "photo":
$ret.= "<img width='" . $j->width . "' src='" . proxy_url($j->url) . "'>";
break;
case "link":
break;
case "rich":
// not so safe..
if (!Config::get("system", "no_oembed_rich_content")) {
$ret.= proxy_parse_html($jhtml);
}
break;
}
// add link to source if not present in "rich" type
if ($j->type != 'rich' || !strpos($j->html, $embedurl)) {
$ret .= "<h4>";
if (isset($j->title)) {
if (isset($j->provider_name)) {
$ret .= $j->provider_name . ": ";
}
$embedlink = (isset($j->title)) ? $j->title : $embedurl;
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
if (isset($j->author_name)) {
$ret.=" (" . $j->author_name . ")";
}
} elseif (isset($j->provider_name) || isset($j->author_name)) {
$embedlink = "";
if (isset($j->provider_name)) {
$embedlink .= $j->provider_name;
}
if (isset($j->author_name)) {
if ($embedlink != "") {
$embedlink .= ": ";
}
$embedlink .= $j->author_name;
}
if (trim($embedlink) == "") {
$embedlink = $embedurl;
}
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
}
//if (isset($j->author_name)) $ret.=" by ".$j->author_name;
//if (isset($j->provider_name)) $ret.=" on ".$j->provider_name;
$ret .= "</h4>";
} else {
// add <a> for html2bbcode conversion
$ret .= "<a href='$embedurl' rel='oembed'>$embedurl</a>";
}
$ret.="</span>";
$ret = str_replace("\n", "", $ret);
return mb_convert_encoding($ret, 'HTML-ENTITIES', mb_detect_encoding($ret));
}
public static function BBCode2HTML($text)
{
$stopoembed = Config::get("system", "no_oembed");
if ($stopoembed == true) {
return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "<!-- oembed $1 --><i>" . t('Embedding disabled') . " : $1</i><!-- /oembed $1 -->", $text);
}
return preg_replace_callback("/\[embed\](.+?)\[\/embed\]/is", ['self', 'replaceCallback'], $text);
}
/**
* Find <span class='oembed'>..<a href='url' rel='oembed'>..</a></span>
* and replace it with [embed]url[/embed]
*/
public static function HTML2BBCode($text)
{
// start parser only if 'oembed' is in text
if (strpos($text, "oembed")) {
// convert non ascii chars to html entities
$html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
// If it doesn't parse at all, just return the text.
$dom = @DOMDocument::loadHTML($html_text);
if (!$dom) {
return $text;
}
$xpath = new DOMXPath($dom);
$xattr = self::buildXPath("class", "oembed");
$entries = $xpath->query("//span[$xattr]");
$xattr = "@rel='oembed'"; //oe_build_xpath("rel","oembed");
foreach ($entries as $e) {
$href = $xpath->evaluate("a[$xattr]/@href", $e)->item(0)->nodeValue;
if (!is_null($href)) {
$e->parentNode->replaceChild(new DOMText("[embed]" . $href . "[/embed]"), $e);
}
}
return self::getInnerHTML($dom->getElementsByTagName("body")->item(0));
} else {
return $text;
}
}
/**
* @brief Generates the iframe HTML for an oembed attachment.
*
* Width and height are given by the remote, and are regularly too small for
* the generated iframe.
*
* The width is entirely discarded for the actual width of the post, while fixed
* height is used as a starting point before the inevitable resizing.
*
* Since the iframe is automatically resized on load, there are no need for ugly
* and impractical scrollbars.
*
* @param string $src Original remote URL to embed
* @param string $width
* @param string $height
* @return string formatted HTML
*
* @see oembed_format_object()
*/
private static function iframe($src, $width, $height)
{
$a = get_app();
if (!$height || strstr($height, '%')) {
$height = '200';
}
$width = '100%';
$s = System::baseUrl() . '/oembed/' . base64url_encode($src);
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $s . '" allowfullscreen scrolling="no" frameborder="no">' . t('Embedded content') . '</iframe>';
}
/**
* Generates an XPath query to select elements whose provided attribute contains
* the provided value in a space-separated list.
*
* @brief Generates attribute search XPath string
*
* @param string $attr Name of the attribute to seach
* @param string $value Value to search in a space-separated list
* @return string
*/
private static function buildXPath($attr, $value)
{
// https://www.westhoffswelt.de/blog/2009/6/9/select-html-elements-with-more-than-one-css-class-using-xpath
return "contains(normalize-space(@$attr), ' $value ') or substring(normalize-space(@$attr), 1, string-length('$value') + 1) = '$value ' or substring(normalize-space(@$attr), string-length(@$attr) - string-length('$value')) = ' $value' or @$attr = '$value'";
}
/**
* Returns the inner XML string of a provided DOMNode
*
* @brief Returns the inner XML string of a provided DOMNode
*
* @param DOMNode $node
* @return string
*/
private static function getInnerHTML(DOMNode $node)
{
$innerHTML = '';
$children = $node->childNodes;
foreach ($children as $child) {
$innerHTML .= $child->ownerDocument->saveXML($child);
}
return $innerHTML;
}
}

View file

@ -606,6 +606,7 @@ class Worker
$exponent = 3;
$slope = $maxworkers / pow($maxsysload, $exponent);
$queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent));
$processlist = '';
if (Config::get('system', 'worker_debug')) {
// Create a list of queue entries grouped by their priority

View file

@ -662,7 +662,7 @@ class Contact extends BaseObject
if (!DBM::is_result($contact)) {
// The link could be provided as http although we stored it as https
$ssl_url = str_replace('http://', 'https://', $url);
$r = dba::select('contact', array('id', 'avatar-date'), array('`alias` IN (?, ?, ?) AND `uid` = ?', $url, normalise_link($url), $ssl_url, $uid), array('limit' => 1));
$r = dba::select('contact', array('id', 'avatar', 'avatar-date'), array('`alias` IN (?, ?, ?) AND `uid` = ?', $url, normalise_link($url), $ssl_url, $uid), array('limit' => 1));
$contact = dba::fetch($r);
dba::close($r);
}
@ -674,7 +674,7 @@ class Contact extends BaseObject
$update_contact = ($contact['avatar-date'] < datetime_convert('', '', 'now -7 days'));
// We force the update if the avatar is empty
if ($contact['avatar'] == '') {
if (!x($contact, 'avatar')) {
$update_contact = true;
}

View file

@ -16,11 +16,11 @@ use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Model\Photo;
use Friendica\Object\Image;
use Friendica\Util\Crypto;
use dba;
use Exception;
require_once 'boot.php';
require_once 'include/crypto.php';
require_once 'include/dba.php';
require_once 'include/enotify.php';
require_once 'include/network.php';
@ -299,7 +299,7 @@ class User
$return['password'] = $new_password;
$keys = new_keypair(4096);
$keys = Crypto::newKeypair(4096);
if ($keys === false) {
throw new Exception(t('SERIOUS ERROR: Generation of security keys failed.'));
}
@ -308,7 +308,7 @@ class User
$pubkey = $keys['pubkey'];
// Create another keypair for signing/verifying salmon protocol messages.
$sres = new_keypair(512);
$sres = Crypto::newKeypair(512);
$sprvkey = $sres['prvkey'];
$spubkey = $sres['pubkey'];

59
src/Module/Feed.php Normal file
View file

@ -0,0 +1,59 @@
<?php
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Protocol\OStatus;
/**
* Provides public Atom feeds
*
* Currently supported:
* - /feed/[nickname]/ => posts
* - /feed/[nickname]/posts => posts
* - /feed/[nickname]/comments => comments
* - /feed/[nickname]/replies => comments
* - /feed/[nickname]/activity => activity
*
* The nocache GET parameter is provided mainly for debug purposes, requires auth
*
* @brief Provides public Atom feeds
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Feed extends BaseModule
{
public static function content()
{
$a = self::getApp();
$last_update = x($_GET, 'last_update') ? $_GET['last_update'] : '';
$nocache = x($_GET, 'nocache') && local_user();
if ($a->argc < 2) {
http_status_exit(400);
}
$type = null;
if ($a->argc > 2) {
$type = $a->argv[2];
}
switch ($type) {
case 'posts':
case 'comments':
case 'activity':
break;
case 'replies':
$type = 'comments';
break;
default:
$type = 'posts';
}
$nickname = $a->argv[1];
header("Content-type: application/atom+xml");
echo OStatus::feed($nickname, $last_update, 10, $type, $nocache);
killme();
}
}

53
src/Module/Oembed.php Normal file
View file

@ -0,0 +1,53 @@
<?php
namespace Friendica\Module;
use Friendica\BaseModule;
use Friendica\Content;
/**
* Oembed module
*
* Displays stored embed content based on a base64 hash of a remote URL
*
* Example: /oembed/aHR0cHM6Ly9...
*
* @author Hypolite Petovan <mrpetovan@gmail.com>
*/
class Oembed extends BaseModule
{
public static function content()
{
$a = self::getApp();
// Unused form: /oembed/b2h?url=...
if ($a->argv[1] == 'b2h') {
$url = array("", trim(hex2bin($_REQUEST['url'])));
echo Content\OEmbed::replaceCallback($url);
killme();
}
// Unused form: /oembed/h2b?text=...
if ($a->argv[1] == 'h2b') {
$text = trim(hex2bin($_REQUEST['text']));
echo Content\OEmbed::HTML2BBCode($text);
killme();
}
if ($a->argc == 2) {
echo '<html><body>';
$url = base64url_decode($a->argv[1]);
$j = Content\OEmbed::fetchURL($url);
// workaround for media.ccc.de (and any other endpoint that return size 0)
if (substr($j->html, 0, 7) == "<iframe" && strstr($j->html, 'width="0"')) {
$j->html = '<style>html,body{margin:0;padding:0;} iframe{width:100%;height:100%;}</style>' . $j->html;
$j->html = str_replace('width="0"', '', $j->html);
$j->html = str_replace('height="0"', '', $j->html);
}
echo $j->html;
echo '</body></html>';
}
killme();
}
}

View file

@ -17,6 +17,7 @@ use Friendica\Database\DBM;
use Friendica\Model\Profile;
use Friendica\Protocol\Email;
use Friendica\Protocol\Feed;
use Friendica\Util\Crypto;
use Friendica\Util\XML;
use dba;
@ -25,7 +26,6 @@ use DOMDocument;
require_once 'include/dba.php';
require_once 'include/network.php';
require_once "include/crypto.php";
/**
* @brief This class contain functions for probing URL
@ -330,7 +330,7 @@ class Probe
$data["url"] = $uri;
}
if ($data["photo"] != "") {
if (x($data, "photo")) {
$data["baseurl"] = matching_url(normalise_link($data["baseurl"]), normalise_link($data["photo"]));
} else {
$data["photo"] = System::baseUrl().'/images/person-175.jpg';
@ -341,7 +341,7 @@ class Probe
$data["name"] = $data["nick"];
}
if ($data["name"] == "") {
if (!x($data, "name")) {
$data["name"] = $data["url"];
}
}
@ -944,7 +944,7 @@ class Probe
//if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
if (strstr($data["pubkey"], 'RSA ')) {
$data["pubkey"] = rsatopem($data["pubkey"]);
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
}
}
}
@ -1043,7 +1043,7 @@ class Probe
if ($search->length > 0) {
$data["pubkey"] = $search->item(0)->nodeValue;
if (strstr($data["pubkey"], 'RSA ')) {
$data["pubkey"] = rsatopem($data["pubkey"]);
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
}
}
@ -1133,7 +1133,7 @@ class Probe
//if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
if (strstr($data["pubkey"], 'RSA ')) {
$data["pubkey"] = rsatopem($data["pubkey"]);
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
}
}
}
@ -1244,7 +1244,7 @@ class Probe
if (sizeof($key) >= 3) {
$m = base64url_decode($key[1]);
$e = base64url_decode($key[2]);
$data["pubkey"] = metopem($m, $e);
$data["pubkey"] = Crypto::meToPem($m, $e);
}
}
}

View file

@ -1,7 +1,9 @@
<?php
/**
* @file src/Object/Post.php
*/
namespace Friendica\Object;
use Friendica\BaseObject;
@ -52,9 +54,9 @@ class Post extends BaseObject
$this->data = $data;
$this->setTemplate('wall');
$this->toplevel = ($this->getId() == $this->getDataValue('parent'));
$this->toplevel = $this->getId() == $this->getDataValue('parent');
if (is_array($_SESSION['remote'])) {
if (x($_SESSION, 'remote') && is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['cid'] == $this->getDataValue('contact-id')) {
$this->visiting = true;
@ -63,9 +65,7 @@ class Post extends BaseObject
}
}
$this->writable = ($this->getDataValue('writable') || $this->getDataValue('self'));
$ssl_state = ((local_user()) ? true : false);
$this->writable = $this->getDataValue('writable') || $this->getDataValue('self');
$this->redirect_url = 'redir/' . $this->getDataValue('cid');
if (!$this->isToplevel()) {
@ -75,9 +75,7 @@ class Post extends BaseObject
// Prepare the children
if (count($data['children'])) {
foreach ($data['children'] as $item) {
/*
* Only add will be displayed
*/
// Only add will be displayed
if ($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
continue;
} elseif (!visible_activity($item)) {
@ -145,7 +143,7 @@ class Post extends BaseObject
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
: false);
$shareable = ((in_array($conv->getProfileOwner(), [0, local_user()]) && ($item['private'] != 1)) ? true : false);
$shareable = in_array($conv->getProfileOwner(), [0, local_user()]) && $item['private'] != 1;
if (local_user() && link_compare($a->contact['url'], $item['author-link'])) {
if ($item["event-id"] != 0) {
@ -170,7 +168,7 @@ class Post extends BaseObject
$filer = (($conv->getProfileOwner() == local_user()) ? t("save to folder") : false);
$diff_author = ((link_compare($item['url'], $item['author-link'])) ? false : true);
$diff_author = !link_compare($item['url'], $item['author-link']);
$profile_name = htmlentities(((strlen($item['author-name'])) && $diff_author) ? $item['author-name'] : $item['name']);
if ($item['author-link'] && (!$item['author-name'])) {
$profile_name = $item['author-link'];
@ -210,25 +208,11 @@ class Post extends BaseObject
call_hooks('render_location', $locate);
$location = ((strlen($locate['html'])) ? $locate['html'] : render_location_dummy($locate));
$tags=array();
$hashtags = array();
$mentions = array();
/*foreach(explode(',',$item['tag']) as $tag){
$tag = trim($tag);
if ($tag!="") {
$t = bbcode($tag);
$tags[] = $t;
if($t[0] == '#')
$hashtags[] = $t;
elseif($t[0] == '@')
$mentions[] = $t;
}
}*/
// process action responses - e.g. like/dislike/attend/agree/whatever
$response_verbs = array('like', 'dislike');
$isevent = false;
$attend = [];
if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
$response_verbs[] = 'attendyes';
$response_verbs[] = 'attendno';
@ -242,7 +226,7 @@ class Post extends BaseObject
$responses = get_responses($conv_responses, $response_verbs, $this, $item);
foreach ($response_verbs as $value => $verbs) {
$responses[$verbs]['output'] = ((x($conv_responses[$verbs], $item['uri'])) ? format_like($conv_responses[$verbs][$item['uri']], $conv_responses[$verbs][$item['uri'] . '-l'], $verbs, $item['uri']) : '');
$responses[$verbs]['output'] = x($conv_responses[$verbs], $item['uri']) ? format_like($conv_responses[$verbs][$item['uri']], $conv_responses[$verbs][$item['uri'] . '-l'], $verbs, $item['uri']) : '';
}
/*
@ -256,6 +240,8 @@ class Post extends BaseObject
$osparkle = ' sparkle';
}
$tagger = '';
if ($this->isToplevel()) {
if ($conv->getProfileOwner() == local_user()) {
$isstarred = (($item['starred']) ? "starred" : "unstarred");
@ -264,8 +250,8 @@ class Post extends BaseObject
'do' => t("add star"),
'undo' => t("remove star"),
'toggle' => t("toggle star status"),
'classdo' => (($item['starred']) ? "hidden" : ""),
'classundo' => (($item['starred']) ? "" : "hidden"),
'classdo' => $item['starred'] ? "hidden" : "",
'classundo' => $item['starred'] ? "" : "hidden",
'starred' => t('starred'),
);
$r = dba::select('thread', array('ignored'), array('uid' => $item['uid'], 'iid' => $item['id']), array('limit' => 1));
@ -274,13 +260,12 @@ class Post extends BaseObject
'do' => t("ignore thread"),
'undo' => t("unignore thread"),
'toggle' => t("toggle ignore status"),
'classdo' => (($r['ignored']) ? "hidden" : ""),
'classundo' => (($r['ignored']) ? "" : "hidden"),
'classdo' => $r['ignored'] ? "hidden" : "",
'classundo' => $r['ignored'] ? "" : "hidden",
'ignored' => t('ignored'),
);
}
$tagger = '';
if (Feature::isEnabled($conv->getProfileOwner(), 'commtag')) {
$tagger = array(
'add' => t("add tag"),
@ -295,7 +280,7 @@ class Post extends BaseObject
if ($conv->isWritable()) {
$buttons = array(
'like' => array(t("I like this \x28toggle\x29"), t("like")),
'dislike' => ((Feature::isEnabled($conv->getProfileOwner(), 'dislike')) ? array( t("I don't like this \x28toggle\x29"), t("dislike")) : ''),
'dislike' => Feature::isEnabled($conv->getProfileOwner(), 'dislike') ? array(t("I don't like this \x28toggle\x29"), t("dislike")) : '',
);
if ($shareable) {
$buttons['share'] = array(t('Share this'), t('share'));
@ -322,10 +307,10 @@ class Post extends BaseObject
$owner_name_e = $this->getOwnerName();
// Disable features that aren't available in several networks
/// @todo Add NETWORK_DIASPORA when it will pass this information
if (!in_array($item["item_network"], array(NETWORK_DFRN)) && isset($buttons["dislike"])) {
unset($buttons["dislike"], $isevent);
unset($buttons["dislike"]);
$isevent = false;
$tagger = '';
}
@ -355,8 +340,8 @@ class Post extends BaseObject
'guid' => urlencode($item['guid']),
'isevent' => $isevent,
'attend' => $attend,
'linktitle' => sprintf(t('View %s\'s profile @ %s'), $profile_name, ((strlen($item['author-link'])) ? $item['author-link'] : $item['url'])),
'olinktitle' => sprintf(t('View %s\'s profile @ %s'), htmlentities($this->getOwnerName()), ((strlen($item['owner-link'])) ? $item['owner-link'] : $item['url'])),
'linktitle' => t('View %s\'s profile @ %s', $profile_name, defaults($item, 'author-link', $item['url'])),
'olinktitle' => t('View %s\'s profile @ %s', htmlentities($this->getOwnerName()), defaults($item, 'owner-link', $item['url'])),
'to' => t('to'),
'via' => t('via'),
'wall' => t('Wall-to-Wall'),
@ -369,7 +354,7 @@ class Post extends BaseObject
'sparkle' => $sparkle,
'title' => $title_e,
'localtime' => datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'r'),
'ago' => (($item['app']) ? sprintf(t('%s from %s'), relative_date($item['created']), $item['app']) : relative_date($item['created'])),
'ago' => $item['app'] ? t('%s from %s', relative_date($item['created']), $item['app']) : relative_date($item['created']),
'app' => $item['app'],
'created' => relative_date($item['created']),
'lock' => $lock,
@ -380,12 +365,12 @@ class Post extends BaseObject
'owner_photo' => $a->remove_baseurl(proxy_url($item['owner-thumb'], false, PROXY_SIZE_THUMB)),
'owner_name' => htmlentities($owner_name_e),
'plink' => get_plink($item),
'edpost' => ((Feature::isEnabled($conv->getProfileOwner(), 'edit_posts')) ? $edpost : ''),
'edpost' => Feature::isEnabled($conv->getProfileOwner(), 'edit_posts') ? $edpost : '',
'isstarred' => $isstarred,
'star' => ((Feature::isEnabled($conv->getProfileOwner(), 'star_posts')) ? $star : ''),
'ignore' => ((Feature::isEnabled($conv->getProfileOwner(), 'ignore_posts')) ? $ignore : ''),
'star' => Feature::isEnabled($conv->getProfileOwner(), 'star_posts') ? $star : '',
'ignore' => Feature::isEnabled($conv->getProfileOwner(), 'ignore_posts') ? $ignore : '',
'tagger' => $tagger,
'filer' => ((Feature::isEnabled($conv->getProfileOwner(), 'filing')) ? $filer : ''),
'filer' => Feature::isEnabled($conv->getProfileOwner(), 'filing') ? $filer : '',
'drop' => $drop,
'vote' => $buttons,
'like' => $responses['like']['output'],
@ -393,7 +378,7 @@ class Post extends BaseObject
'responses' => $responses,
'switchcomment' => t('Comment'),
'comment' => $comment,
'previewing' => ($conv->isPreview() ? ' preview ' : ''),
'previewing' => $conv->isPreview() ? ' preview ' : '',
'wait' => t('Please wait'),
'thread_level' => $thread_level,
'edited' => $edited,
@ -419,7 +404,7 @@ class Post extends BaseObject
// Collapse
if (($nb_children > 2) || ($thread_level > 1)) {
$result['children'][0]['comment_firstcollapsed'] = true;
$result['children'][0]['num_comments'] = sprintf(tt('%d comment', '%d comments', $total_children), $total_children);
$result['children'][0]['num_comments'] = tt('%d comment', '%d comments', $total_children);
$result['children'][0]['hidden_comments_num'] = $total_children;
$result['children'][0]['hidden_comments_text'] = tt('comment', 'comments', $total_children);
$result['children'][0]['hide_text'] = t('show more');
@ -696,7 +681,6 @@ class Post extends BaseObject
if ($conv) {
// This will allow us to comment on wall-to-wall items owned by our friends
// and community forums even if somebody else wrote the post.
// bug #517 - this fixes for conversation owner
if ($conv->getMode() == 'profile' && $conv->getProfileOwner() == local_user()) {
return true;
@ -750,7 +734,6 @@ class Post extends BaseObject
$comment_box = '';
$conv = $this->getThread();
$template = get_markup_template($this->getCommentBoxTemplate());
$ww = '';
if (($conv->getMode() === 'network') && $this->isWallToWall()) {
$ww = 'ww';
@ -768,14 +751,12 @@ class Post extends BaseObject
$qcomment = (($qc) ? explode("\n", $qc) : null);
}
$comment_box = replace_macros(
$template,
array(
$template = get_markup_template($this->getCommentBoxTemplate());
$comment_box = replace_macros($template, array(
'$return_path' => $a->query_string,
'$threaded' => $this->isThreaded(),
// '$jsreload' => (($conv->getMode() === 'display') ? $_SESSION['return_url'] : ''),
'$jsreload' => '',
'$type' => (($conv->getMode() === 'profile') ? 'wall-comment' : 'net-comment'),
'$type' => $conv->getMode() === 'profile' ? 'wall-comment' : 'net-comment',
'$id' => $this->getId(),
'$parent' => $this->getId(),
'$qcomment' => $qcomment,
@ -796,9 +777,9 @@ class Post extends BaseObject
'$preview' => ((Feature::isEnabled($conv->getProfileOwner(), 'preview')) ? t('Preview') : ''),
'$indent' => $indent,
'$sourceapp' => t($a->sourcename),
'$ww' => (($conv->getMode() === 'network') ? $ww : ''),
'$rand_num' => random_digits(12))
);
'$ww' => $conv->getMode() === 'network' ? $ww : '',
'$rand_num' => random_digits(12)
));
}
return $comment_box;
@ -846,7 +827,6 @@ class Post extends BaseObject
// all over the park. It can be tricked, but this prevents you from
// seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
// well that it's the same Bob Smith.
// But it could be somebody else with the same name. It just isn't highly likely.
@ -854,8 +834,8 @@ class Post extends BaseObject
$this->owner_name = $this->getDataValue('owner-name');
$this->wall_to_wall = true;
// If it is our contact, use a friendly redirect link
if ((link_compare($this->getDataValue('owner-link'), $this->getDataValue('url')))
&& ($this->getDataValue('network') === NETWORK_DFRN)
if ($this->getDataValue('network') === NETWORK_DFRN
&& link_compare($this->getDataValue('owner-link'), $this->getDataValue('url'))
) {
$this->owner_url = $this->getRedirectUrl();
} else {

View file

@ -5,7 +5,7 @@
*/
namespace Friendica;
use Friendica\Core\Config;
use Friendica\Content\OEmbed;
use Friendica\Object\Image;
use Friendica\Util\XML;
@ -15,7 +15,6 @@ use DOMDocument;
require_once 'include/dba.php';
require_once "include/network.php";
require_once "include/oembed.php";
/**
* @brief Class with methods for extracting certain content from an url
@ -164,7 +163,7 @@ class ParseUrl
$body = $data["body"];
if ($do_oembed) {
$oembed_data = oembed_fetch_url($url);
$oembed_data = OEmbed::fetchURL($url);
if (!in_array($oembed_data->type, array("error", "rich", ""))) {
$siteinfo["type"] = $oembed_data->type;

View file

@ -8,6 +8,7 @@
*/
namespace Friendica\Protocol;
use Friendica\Content\OEmbed;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Core\Worker;
@ -33,7 +34,6 @@ require_once "include/tags.php";
require_once "include/files.php";
require_once "include/event.php";
require_once "include/text.php";
require_once "include/oembed.php";
require_once "include/html2bbcode.php";
require_once "include/bbcode.php";
@ -463,7 +463,7 @@ class DFRN
/* get site pubkey. this could be a new installation with no site keys*/
$pubkey = Config::get('system', 'site_pubkey');
if (! $pubkey) {
$res = new_keypair(1024);
$res = Crypto::newKeypair(1024);
Config::set('system', 'site_prvkey', $res['prvkey']);
Config::set('system', 'site_pubkey', $res['pubkey']);
}
@ -2502,7 +2502,7 @@ class DFRN
$item['body'] = html2bb_video($item['body']);
$item['body'] = oembed_html2bbcode($item['body']);
$item['body'] = OEmbed::HTML2BBCode($item['body']);
$config = \HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);

View file

@ -22,6 +22,7 @@ use Friendica\Model\Group;
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Util\Crypto;
use Friendica\Util\XML;
use dba;
@ -173,7 +174,7 @@ class Diaspora
$key = self::key($handle);
$verify = rsa_verify($signable_data, $sig, $key);
$verify = Crypto::rsaVerify($signable_data, $sig, $key);
if (!$verify) {
logger('Message did not verify. Discarding.');
return false;
@ -273,7 +274,7 @@ class Diaspora
$author_addr = base64_decode($key_id);
$key = self::key($author_addr);
$verify = rsa_verify($signed_data, $signature, $key);
$verify = Crypto::rsaVerify($signed_data, $signature, $key);
if (!$verify) {
logger('Message did not verify. Discarding.');
http_status_exit(400);
@ -406,7 +407,7 @@ class Diaspora
http_status_exit(400);
}
$verify = rsa_verify($signed_data, $signature, $key);
$verify = Crypto::rsaVerify($signed_data, $signature, $key);
if (!$verify) {
logger('Message did not verify. Discarding.');
@ -699,7 +700,7 @@ class Diaspora
$key = self::key($msg["author"]);
if (!rsa_verify($signed_data, $parent_author_signature, $key, "sha256")) {
if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) {
logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG);
return false;
}
@ -709,7 +710,7 @@ class Diaspora
$key = self::key($fields->author);
if (!rsa_verify($signed_data, $author_signature, $key, "sha256")) {
if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) {
logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG);
return false;
} else {
@ -1432,7 +1433,7 @@ class Diaspora
// Check signature
$signed_text = 'AccountMigration:'.$old_handle.':'.$new_handle;
$key = self::key($old_handle);
if (!rsa_verify($signed_text, $signature, $key, "sha256")) {
if (!Crypto::rsaVerify($signed_text, $signature, $key, "sha256")) {
logger('No valid signature for migration.');
return false;
}
@ -2688,6 +2689,8 @@ class Diaspora
self::fetchGuid($datarray);
$message_id = item_store($datarray);
self::sendParticipation($contact, $datarray);
if ($message_id) {
logger("Stored reshare ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
return true;
@ -2926,6 +2929,8 @@ class Diaspora
self::fetchGuid($datarray);
$message_id = item_store($datarray);
self::sendParticipation($contact, $datarray);
if ($message_id) {
logger("Stored item ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
return true;
@ -3028,7 +3033,7 @@ class Diaspora
$user['uprvkey'] = $user['prvkey'];
}
$signature = rsa_sign($signable_data, $user["uprvkey"]);
$signature = Crypto::rsaSign($signable_data, $user["uprvkey"]);
$sig = base64url_encode($signature);
$xmldata = array("me:env" => array("me:data" => $data,
@ -3084,7 +3089,7 @@ class Diaspora
$signed_text = implode(";", $sigmsg);
return base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256"));
return base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256"));
}
/**
@ -3215,6 +3220,54 @@ class Diaspora
return $return_code;
}
/**
* @brief sends a participation (Used to get all further updates)
*
* @param array $contact Target of the communication
* @param array $item Item array
*
* @return int The result of the transmission
*/
private static function sendParticipation($contact, $item)
{
// Don't send notifications for private postings
if ($item['private']) {
return;
}
$cachekey = "diaspora:sendParticipation:".$item['guid'];
$result = Cache::get($cachekey);
if (!is_null($result)) {
return;
}
// Fetch some user id to have a valid handle to transmit the participation.
// In fact it doesn't matter which user sends this - but it is needed by the protocol.
// If the item belongs to a user, we take this user id.
if ($item['uid'] == 0) {
$condition = ['verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false];
$first_user = dba::select('user', ['uid'], $condition, ['limit' => 1]);
$owner = User::getOwnerDataById($first_user['uid']);
} else {
$owner = User::getOwnerDataById($item['uid']);
}
$author = self::myHandle($owner);
$message = array("author" => $author,
"guid" => get_guid(32),
"parent_type" => "Post",
"parent_guid" => $item["guid"]);
logger("Send participation for ".$item["guid"]." by ".$author, LOGGER_DEBUG);
// It doesn't matter what we store, we only want to avoid sending repeated notifications for the same item
Cache::set($cachekey, $item["guid"], CACHE_QUARTER_HOUR);
return self::buildAndTransmit($owner, $contact, "participation", $message);
}
/**
* @brief sends an account migration
*
@ -3230,7 +3283,7 @@ class Diaspora
$profile = self::createProfileData($uid);
$signed_text = 'AccountMigration:'.$old_handle.':'.$profile['author'];
$signature = base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256"));
$signature = base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256"));
$message = array("author" => $old_handle,
"profile" => $profile,

View file

@ -1237,10 +1237,11 @@ class OStatus
*
* @param object $doc XML document
* @param array $owner Contact data of the poster
* @param string $filter The related feed filter (activity, posts or comments)
*
* @return object header root element
*/
private static function addHeader($doc, $owner)
private static function addHeader($doc, $owner, $filter)
{
$a = get_app();
@ -1256,10 +1257,16 @@ class OStatus
$root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
$root->setAttribute("xmlns:mastodon", NAMESPACE_MASTODON);
switch ($filter) {
case 'activity': $title = t('%s\'s timeline', $owner['name']); break;
case 'posts' : $title = t('%s\'s posts' , $owner['name']); break;
case 'comments': $title = t('%s\'s comments', $owner['name']); break;
}
$attributes = array("uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION . "-" . DB_UPDATE_VERSION);
XML::addElement($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
XML::addElement($doc, $root, "id", System::baseUrl() . "/profile/" . $owner["nick"]);
XML::addElement($doc, $root, "title", sprintf("%s timeline", $owner["name"]));
XML::addElement($doc, $root, "title", $title);
XML::addElement($doc, $root, "subtitle", sprintf("Updates from %s on %s", $owner["name"], $a->config["sitename"]));
XML::addElement($doc, $root, "logo", $owner["photo"]);
XML::addElement($doc, $root, "updated", datetime_convert("UTC", "UTC", "now", ATOM_TIME));
@ -2067,42 +2074,51 @@ class OStatus
}
/**
* Creates the XML feed for a given nickname
*
* Supported filters:
* - activity (default): all the public posts
* - posts: all the public top-level posts
* - comments: all the public replies
*
* Updates the provided last_update parameter if the result comes from the
* cache or it is empty
*
* @brief Creates the XML feed for a given nickname
*
* @param object $a The application class
* @param string $owner_nick Nickname of the feed owner
* @param string $last_update Date of the last update
* @param integer $max_items Number of maximum items to fetch
* @param string $filter Feed items filter (activity, posts or comments)
* @param boolean $nocache Wether to bypass caching
*
* @return string XML feed
*/
public static function feed(App $a, $owner_nick, &$last_update, $max_items = 300)
public static function feed($owner_nick, &$last_update, $max_items = 300, $filter = 'activity', $nocache = false)
{
$stamp = microtime(true);
$cachekey = "ostatus:feed:".$owner_nick.":".$last_update;
$cachekey = "ostatus:feed:" . $owner_nick . ":" . $filter . ":" . $last_update;
$previous_created = $last_update;
$result = Cache::get($cachekey);
if (!is_null($result)) {
logger('Feed duration: '.number_format(microtime(true) - $stamp, 3).' - '.$owner_nick.' - '.$previous_created.' (cached)', LOGGER_DEBUG);
if (!$nocache && !is_null($result)) {
logger('Feed duration: ' . number_format(microtime(true) - $stamp, 3) . ' - ' . $owner_nick . ' - ' . $filter . ' - ' . $previous_created . ' (cached)', LOGGER_DEBUG);
$last_update = $result['last_update'];
return $result['feed'];
}
$r = q(
$owner = dba::fetch_first(
"SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`self` AND `user`.`nickname` = '%s' LIMIT 1",
dbesc($owner_nick)
WHERE `contact`.`self` AND `user`.`nickname` = ? LIMIT 1",
$owner_nick
);
if (!DBM::is_result($r)) {
if (!DBM::is_result($owner)) {
return;
}
$owner = $r[0];
if (!strlen($last_update)) {
$last_update = 'now -30 days';
}
@ -2110,23 +2126,40 @@ class OStatus
$check_date = datetime_convert('UTC', 'UTC', $last_update, 'Y-m-d H:i:s');
$authorid = Contact::getIdForURL($owner["url"], 0);
$sql_extra = '';
if ($filter === 'posts') {
$sql_extra .= ' AND `item`.`id` = `item`.`parent` ';
}
if ($filter === 'comments') {
$sql_extra .= sprintf(" AND `item`.`object-type` = '%s' ", dbesc(ACTIVITY_OBJ_COMMENT));
}
$items = q(
"SELECT `item`.*, `item`.`id` AS `item_id` FROM `item` USE INDEX (`uid_contactid_created`)
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `item`.`parent`
WHERE `item`.`uid` = %d AND `item`.`contact-id` = %d AND
`item`.`author-id` = %d AND `item`.`created` > '%s' AND
NOT `item`.`deleted` AND NOT `item`.`private` AND
`thread`.`network` IN ('%s', '%s')
WHERE `item`.`uid` = %d
AND `item`.`contact-id` = %d
AND `item`.`author-id` = %d
AND `item`.`created` > '%s'
AND NOT `item`.`deleted`
AND NOT `item`.`private`
AND `thread`.`network` IN ('%s', '%s')
$sql_extra
ORDER BY `item`.`created` DESC LIMIT %d",
intval($owner["uid"]), intval($owner["id"]),
intval($authorid), dbesc($check_date),
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DFRN), intval($max_items)
intval($owner["uid"]),
intval($owner["id"]),
intval($authorid),
dbesc($check_date),
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_DFRN),
intval($max_items)
);
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$root = self::addHeader($doc, $owner);
$root = self::addHeader($doc, $owner, $filter);
foreach ($items as $item) {
if (Config::get('system', 'ostatus_debug')) {
@ -2145,7 +2178,7 @@ class OStatus
$msg = array('feed' => $feeddata, 'last_update' => $last_update);
Cache::set($cachekey, $msg, CACHE_QUARTER_HOUR);
logger('Feed duration: '.number_format(microtime(true) - $stamp, 3).' - '.$owner_nick.' - '.$previous_created, LOGGER_DEBUG);
logger('Feed duration: ' . number_format(microtime(true) - $stamp, 3) . ' - ' . $owner_nick . ' - ' . $filter . ' - ' . $previous_created, LOGGER_DEBUG);
return $feeddata;
}

View file

@ -5,10 +5,9 @@
namespace Friendica\Protocol;
use Friendica\Network\Probe;
use Friendica\Util\Crypto;
use Friendica\Util\XML;
require_once 'include/crypto.php';
/**
* @brief Salmon Protocol class
* The Salmon Protocol is a message exchange protocol running over HTTP designed to decentralize commentary
@ -107,18 +106,18 @@ class Salmon
$data_type = 'application/atom+xml';
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$keyhash = base64url_encode(hash('sha256', salmon_key($owner['spubkey'])), true);
$keyhash = base64url_encode(hash('sha256', self::salmonKey($owner['spubkey'])), true);
$precomputed = '.' . base64url_encode($data_type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($algorithm);
// GNU Social format
$signature = base64url_encode(rsa_sign($data . $precomputed, $owner['sprvkey']));
$signature = base64url_encode(Crypto::rsaSign($data . $precomputed, $owner['sprvkey']));
// Compliant format
$signature2 = base64url_encode(rsa_sign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
$signature2 = base64url_encode(Crypto::rsaSign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
// Old Status.net format
$signature3 = base64url_encode(rsa_sign($data, $owner['sprvkey']));
$signature3 = base64url_encode(Crypto::rsaSign($data, $owner['sprvkey']));
// At first try the non compliant method that works for GNU Social
$xmldata = array("me:env" => array("me:data" => $data,
@ -201,4 +200,14 @@ class Salmon
return (($return_code >= 200) && ($return_code < 300)) ? 0 : 1;
}
/**
* @param string $pubkey public key
* @return string
*/
public static function salmonKey($pubkey)
{
Crypto::pemToMe($pubkey, $m, $e);
return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true);
}
}

252
src/Util/Crypto.php Normal file
View file

@ -0,0 +1,252 @@
<?php
/**
* @file src/Util/Crypto.php
*/
namespace Friendica\Util;
use Friendica\Core\Config;
use ASN_BASE;
use ASNValue;
require_once 'library/ASNValue.class.php';
require_once 'library/asn1.php';
/**
* @brief Crypto class
*/
class Crypto
{
// supported algorithms are 'sha256', 'sha1'
/**
* @param string $data data
* @param string $key key
* @param string $alg algorithm
* @return string
*/
public static function rsaSign($data, $key, $alg = 'sha256')
{
openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
return $sig;
}
/**
* @param string $data data
* @param string $sig signature
* @param string $key key
* @param string $alg algorithm
* @return boolean
*/
public static function rsaVerify($data, $sig, $key, $alg = 'sha256')
{
return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
}
/**
* @param string $Der der formatted string
* @param string $Private key type optional, default false
* @return string
*/
private static function DerToPem($Der, $Private = false)
{
//Encode:
$Der = base64_encode($Der);
//Split lines:
$lines = str_split($Der, 65);
$body = implode("\n", $lines);
//Get title:
$title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
//Add wrapping:
$result = "-----BEGIN {$title}-----\n";
$result .= $body . "\n";
$result .= "-----END {$title}-----\n";
return $result;
}
/**
* @param string $Der der formatted string
* @return string
*/
private static function DerToRsa($Der)
{
//Encode:
$Der = base64_encode($Der);
//Split lines:
$lines = str_split($Der, 64);
$body = implode("\n", $lines);
//Get title:
$title = 'RSA PUBLIC KEY';
//Add wrapping:
$result = "-----BEGIN {$title}-----\n";
$result .= $body . "\n";
$result .= "-----END {$title}-----\n";
return $result;
}
/**
* @param string $Modulus modulo
* @param string $PublicExponent exponent
* @return string
*/
private static function pkcs8Encode($Modulus, $PublicExponent)
{
//Encode key sequence
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
$modulus->SetIntBuffer($Modulus);
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
$publicExponent->SetIntBuffer($PublicExponent);
$keySequenceItems = array($modulus, $publicExponent);
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
$keySequence->SetSequence($keySequenceItems);
//Encode bit string
$bitStringValue = $keySequence->Encode();
$bitStringValue = chr(0x00) . $bitStringValue; //Add unused bits byte
$bitString = new ASNValue(ASNValue::TAG_BITSTRING);
$bitString->Value = $bitStringValue;
//Encode body
$bodyValue = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" . $bitString->Encode();
$body = new ASNValue(ASNValue::TAG_SEQUENCE);
$body->Value = $bodyValue;
//Get DER encoded public key:
$PublicDER = $body->Encode();
return $PublicDER;
}
/**
* @param string $Modulus modulo
* @param string $PublicExponent exponent
* @return string
*/
private static function pkcs1Encode($Modulus, $PublicExponent)
{
//Encode key sequence
$modulus = new ASNValue(ASNValue::TAG_INTEGER);
$modulus->SetIntBuffer($Modulus);
$publicExponent = new ASNValue(ASNValue::TAG_INTEGER);
$publicExponent->SetIntBuffer($PublicExponent);
$keySequenceItems = array($modulus, $publicExponent);
$keySequence = new ASNValue(ASNValue::TAG_SEQUENCE);
$keySequence->SetSequence($keySequenceItems);
//Encode bit string
$bitStringValue = $keySequence->Encode();
return $bitStringValue;
}
/**
* @param string $m modulo
* @param string $e exponent
* @return string
*/
public static function meToPem($m, $e)
{
$der = self::pkcs8Encode($m, $e);
$key = self::DerToPem($der, false);
return $key;
}
/**
* @param string $key key
* @param string $m modulo reference
* @param object $e exponent reference
* @return void
*/
private static function pubRsaToMe($key, &$m, &$e)
{
$lines = explode("\n", $key);
unset($lines[0]);
unset($lines[count($lines)]);
$x = base64_decode(implode('', $lines));
$r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData);
}
/**
* @param string $key key
* @return string
*/
public static function rsaToPem($key)
{
self::pubRsaToMe($key, $m, $e);
return self::meToPem($m, $e);
}
/**
* @param string $key key
* @return string
*/
private static function pemToRsa($key)
{
self::pemToMe($key, $m, $e);
return self::meToRsa($m, $e);
}
/**
* @param string $key key
* @param string $m modulo reference
* @param string $e exponent reference
* @return void
*/
public static function pemToMe($key, &$m, &$e)
{
$lines = explode("\n", $key);
unset($lines[0]);
unset($lines[count($lines)]);
$x = base64_decode(implode('', $lines));
$r = ASN_BASE::parseASNString($x);
$m = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[0]->asnData);
$e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
}
/**
* @param string $m modulo
* @param string $e exponent
* @return string
*/
private static function meToRsa($m, $e)
{
$der = self::pkcs1Encode($m, $e);
$key = self::DerToRsa($der);
return $key;
}
/**
* @param integer $bits number of bits
* @return mixed
*/
public static function newKeypair($bits)
{
$openssl_options = array(
'digest_alg' => 'sha1',
'private_key_bits' => $bits,
'encrypt_key' => false
);
$conf = Config::get('system', 'openssl_conf_file');
if ($conf) {
$openssl_options['config'] = $conf;
}
$result = openssl_pkey_new($openssl_options);
if (empty($result)) {
logger('new_keypair: failed');
return false;
}
// Get private key
$response = array('prvkey' => '', 'pubkey' => '');
openssl_pkey_export($result, $response['prvkey']);
// Get public key
$pkey = openssl_pkey_get_details($result);
$response['pubkey'] = $pkey["key"];
return $response;
}
}

View file

@ -310,6 +310,7 @@ class ExAuth
$lockpath = Config::get('jabber', 'lockpath');
if (is_null($lockpath)) {
$this->writeLog(LOG_INFO, 'No lockpath defined.');
return;
}
@ -325,6 +326,9 @@ class ExAuth
// Now it is safe to create the pid file
PidFile::create($file);
if (!file_exists($file)) {
$this->writeLog(LOG_WARNING, 'Logfile ' . $file . " couldn't be created.");
}
}
/**

View file

@ -280,7 +280,6 @@ class Notifier {
}
}
if ($relay_to_owner) {
logger('notifier: followup '.$target_item["guid"], LOGGER_DEBUG);
// local followup to remote post
$followup = true;
$public_message = false; // not public
@ -288,6 +287,8 @@ class Notifier {
$recipients = array($parent['contact-id']);
$recipients_followup = array($parent['contact-id']);
logger('notifier: followup '.$target_item["guid"].' to '.$conversant_str, LOGGER_DEBUG);
//if (!$target_item['private'] && $target_item['wall'] &&
if (!$target_item['private'] &&
(strlen($target_item['allow_cid'].$target_item['allow_gid'].

View file

@ -52,7 +52,7 @@ class PubSubPublish {
logger("Generate feed of user ".$rr['nickname']." to ".$rr['callback_url']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
$last_update = $rr['last_update'];
$params = OStatus::feed($a, $rr['nickname'], $last_update);
$params = OStatus::feed($rr['nickname'], $last_update);
if (!$params) {
return;

1621
update.php

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,6 @@
<img src="{{$avatar}}" height="32" width="32">
</a>
{{/if}}
{{*<span><a href="{{$profile}}" target="_blank" class="shared-wall-item-name">{{$author}}</a> wrote the following <a href="{{$link}}" target="_blank">post</a>{{$reldate}}:</span>*}}
<div><a href="{{$profile}}" target="_blank" class="shared-wall-item-name"><span class="shared-author">{{$author}}</span></a></div>
<div class="shared-wall-item-ago"><small><a href="{{$link}}" target="_blank"><span class="shared-time">{{$posted}}</a></a></small></div>
</div>

View file

@ -8,7 +8,7 @@ $schemecss = "";
$schemecssfile = false;
$scheme_modified = 0;
if (! $a->install) {
if ($a->module !== 'install') {
// Get the UID of the profile owner.
$uid = get_theme_uid();
if ($uid) {
@ -57,7 +57,7 @@ if (! $a->install) {
// Setting $schema to '' wasn't working for some reason, so we'll check it's
// not --- like the mobile theme does instead.
// Allow layouts to over-ride the schema.
if ($_REQUEST['schema']) {
if (x($_REQUEST, 'schema')) {
$schema = $_REQUEST['schema'];
}
@ -103,7 +103,7 @@ $contentbg_transp = ((isset($contentbg_transp) && $contentbg_transp != "") ? $co
// Calculate some colors in dependance of existing colors.
// Some colors are calculated to don't have too many selection
// fields in the theme settings.
if (! $menu_background_hover_color) {
if (!isset($menu_background_hover_color)) {
$mbhc = new Color($nav_bg);
$mcolor = $mbhc->getHex();
@ -115,7 +115,7 @@ if (! $menu_background_hover_color) {
$menu_background_hover_color = '#' . $mbhc->lighten(5);
}
}
if (! $nav_icon_hover_color) {
if (!isset($nav_icon_hover_color)) {
$nihc = new Color($nav_bg);
if ($nihc->isLight()) {
@ -124,7 +124,7 @@ if (! $nav_icon_hover_color) {
$nav_icon_hover_color = '#' . $nihc->lighten(10);
}
}
if (! $link_hover_color) {
if (!isset($link_hover_color)) {
$lhc = new Color($link_color);
$lcolor = $lhc->getHex();
@ -137,6 +137,9 @@ if (! $link_hover_color) {
}
// Convert $bg_image_options into css.
if (!isset($bg_image_option)) {
$bg_image_option = null;
}
switch ($bg_image_option) {
case "stretch":
$background_size_img = "100%";

View file

@ -47,8 +47,10 @@ Some parts of this template will be moved by js to other places (see theme.js) -
</form>
</div>
{{* This form is inserted as experiment to move the search-save button to the second navbar with js *}}
{{if $savedsearch}}
<form id="search-save-form" action="{{$action_url}}" method="get" >
<input type="hidden" name="search" value="{{$s}}" />
<button class="btn btn-primary btn-sm btn-main pull-right" type="submit" name="save" id="search-save" value="{{$save_label}}"><i class="fa fa-floppy-o fa-2x" aria-hidden="true"></i></button>
</form>
{{/if}}
</div>

View file

@ -1,4 +1,5 @@
<?php
/*
* Name: frio
* Description: Bootstrap V3 theme. The theme is currently under construction, so it is far from finished. For further information have a look at the <a href="https://github.com/friendica/friendica/tree/develop/view/theme/frio/README.md">ReadMe</a>.
@ -18,8 +19,8 @@ $frio = "view/theme/frio";
global $frio;
function frio_init(App $a) {
function frio_init(App $a)
{
// disable the events module link in the profile tab
$a->theme_events_in_profile = false;
@ -43,11 +44,13 @@ function frio_init(App $a) {
EOT;
}
if ($style == "")
if ($style == "") {
$style = Config::get('frio', 'style');
}
}
function frio_install() {
function frio_install()
{
register_hook('prepare_body_final', 'view/theme/frio/theme.php', 'frio_item_photo_links');
register_hook('item_photo_menu', 'view/theme/frio/theme.php', 'frio_item_photo_menu');
register_hook('contact_photo_menu', 'view/theme/frio/theme.php', 'frio_contact_photo_menu');
@ -58,7 +61,8 @@ function frio_install() {
logger("installed theme frio");
}
function frio_uninstall() {
function frio_uninstall()
{
unregister_hook('prepare_body_final', 'view/theme/frio/theme.php', 'frio_item_photo_links');
unregister_hook('item_photo_menu', 'view/theme/frio/theme.php', 'frio_item_photo_menu');
unregister_hook('contact_photo_menu', 'view/theme/frio/theme.php', 'frio_contact_photo_menu');
@ -68,6 +72,7 @@ function frio_uninstall() {
logger("uninstalled theme frio");
}
/**
* @brief Replace friendica photo links hook
*
@ -118,15 +123,14 @@ function frio_item_photo_links(App $a, &$body_info)
* @param App $a Unused but required by the hook definition
* @param array $arr Contains item data and the original photo_menu
*/
function frio_item_photo_menu(App $a, &$arr) {
function frio_item_photo_menu(App $a, &$arr)
{
foreach ($arr["menu"] as $k => $v) {
if (strpos($v, 'poke/?f=&c=') === 0 || strpos($v, 'message/new/') === 0) {
$v = "javascript:addToModal('" . $v . "'); return false;";
$arr["menu"][$k] = $v;
}
}
$args = array('item' => $item, 'menu' => $menu);
}
/**
@ -141,12 +145,8 @@ function frio_item_photo_menu(App $a, &$arr) {
* @param App $a The app data
* @param array $args Contains contact data and the original photo_menu
*/
function frio_contact_photo_menu(App $a, &$args){
$pokelink = "";
$pmlink = "";
$cid = "";
function frio_contact_photo_menu(App $a, &$args)
{
$cid = $args["contact"]["id"];
$pokelink = $args["menu"]["poke"][1];
$pmlink = $args["menu"]["pm"][1];
@ -170,13 +170,13 @@ function frio_contact_photo_menu(App $a, &$args){
// Add to pm and poke links a new key with the value 'modal'.
// Later we can make conditions in the corresponing templates (e.g.
// contact_template.tpl)
if(strpos($pokelink,'poke/?f=&c='. $cid) !== false)
if (strpos($pokelink, 'poke/?f=&c=' . $cid) !== false) {
$args["menu"]["poke"][3] = "modal";
}
if(strpos($pmlink,'message/new/' . $cid) !== false)
if (strpos($pmlink, 'message/new/' . $cid) !== false) {
$args["menu"]["pm"][3] = "modal";
$args = array('contact' => $contact, 'menu' => &$menu);
}
}
/**
@ -193,11 +193,13 @@ function frio_contact_photo_menu(App $a, &$args){
* @param App $a The App class
* @param array $nav The original nav menu
*/
function frio_remote_nav($a,&$nav) {
function frio_remote_nav($a, &$nav)
{
// get the homelink from $_XSESSION
$homelink = get_my_url();
if(! $homelink)
$homelink = ((x($_SESSION,'visitor_home')) ? $_SESSION['visitor_home'] : '');
if (!$homelink) {
$homelink = defaults($_SESSION, 'visitor_home', '');
}
// split up the url in it's parts (protocol,domain/directory, /profile/, nickname
// I'm not familiar with regex, so someone might find a better solutionen
@ -228,11 +230,9 @@ function frio_remote_nav($a,&$nav) {
$r[0]['photo'] = (DBM::is_result($r) ? $a->remove_baseurl($r[0]['micro']) : "images/person-48.jpg");
$r[0]['name'] = $a->user['username'];
} elseif (!local_user() && remote_user()) {
$r = q("SELECT `name`, `nick`, `micro` AS `photo` FROM `contact` WHERE `id` = %d", intval(remote_user()));
$nav['remote'] = t("Guest");
} elseif (get_my_url()) {
$r = q("SELECT `name`, `nick`, `photo` FROM `gcontact`
WHERE `addr` = '%s' AND `network` = 'dfrn'",
@ -268,6 +268,7 @@ function frio_remote_nav($a,&$nav) {
$nav['sitename'] = $a->config['sitename'];
}
}
/**
* @brief: Search for contacts
*
@ -281,10 +282,11 @@ function frio_remote_nav($a,&$nav) {
* @param App $a The app data @TODO Unused
* @param array $results The array with the originals from acl_lookup()
*/
function frio_acl_lookup(App $a, &$results) {
require_once("mod/contacts.php");
function frio_acl_lookup(App $a, &$results)
{
require_once 'mod/contacts.php';
$nets = ((x($_GET,"nets")) ? notags(trim($_GET["nets"])) : "");
$nets = x($_GET, "nets") ? notags(trim($_GET["nets"])) : "";
// we introduce a new search type, r should do the same query like it's
// done in /mod/contacts for connections
@ -295,17 +297,17 @@ function frio_acl_lookup(App $a, &$results) {
$search_txt = dbesc(protect_sprintf(preg_quote($search)));
$searching = true;
}
$sql_extra .= (($searching) ? " AND (`attag` LIKE '%%".dbesc($search_txt)."%%' OR `name` LIKE '%%".dbesc($search_txt)."%%' OR `nick` LIKE '%%".dbesc($search_txt)."%%') " : "");
$sql_extra = '';
if ($searching) {
$sql_extra .= " AND (`attag` LIKE '%%" . dbesc($search_txt) . "%%' OR `name` LIKE '%%" . dbesc($search_txt) . "%%' OR `nick` LIKE '%%" . dbesc($search_txt) . "%%') ";
}
if ($nets) {
$sql_extra .= sprintf(" AND network = '%s' ", dbesc($nets));
}
$sql_extra2 = ((($sort_type > 0) && ($sort_type <= CONTACT_IS_FRIEND)) ? sprintf(" AND `rel` = %d ",intval($sort_type)) : '');
$r = q("SELECT COUNT(*) AS `total` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `pending` $sql_extra $sql_extra2 ",
WHERE `uid` = %d AND NOT `self` AND NOT `pending` $sql_extra ",
intval($_SESSION['uid']));
if (DBM::is_result($r)) {
$total = $r[0]["total"];
@ -313,7 +315,7 @@ function frio_acl_lookup(App $a, &$results) {
$sql_extra3 = unavailable_networks();
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `pending` $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT 100 ",
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `self` AND NOT `pending` $sql_extra $sql_extra3 ORDER BY `name` ASC LIMIT 100 ",
intval($_SESSION['uid'])
);
@ -340,11 +342,11 @@ function frio_acl_lookup(App $a, &$results) {
* 'item' => Array with item data<br>
* 'output' => Array with item actions<br>
*/
function frio_display_item(App $a,&$arr) {
function frio_display_item(App $a, &$arr)
{
// Add subthread to the item menu
$subthread = array();
if ((local_user()) && local_user() == $arr['item']['uid'] && $arr['item']['parent'] == $arr['item']['id'] && (! $arr['item']['self'])) {
if (local_user() == $arr['item']['uid'] && $arr['item']['parent'] == $arr['item']['id'] && !$arr['item']['self']) {
$subthread = array(
'menu' => 'follow_thread',
'title' => t('Follow Thread'),