Merge branch '3.4RC'
This commit is contained in:
@@ -23,6 +23,7 @@ function get_account_by_id($account_id) {
|
||||
|
||||
function check_account_email($email) {
|
||||
|
||||
$email = punify($email);
|
||||
$result = array('error' => false, 'message' => '');
|
||||
|
||||
// Caution: empty email isn't counted as an error in this function.
|
||||
@@ -139,7 +140,7 @@ function create_account($arr) {
|
||||
$result = array('success' => false, 'email' => '', 'password' => '', 'message' => '');
|
||||
|
||||
$invite_code = ((x($arr,'invite_code')) ? notags(trim($arr['invite_code'])) : '');
|
||||
$email = ((x($arr,'email')) ? notags(trim($arr['email'])) : '');
|
||||
$email = ((x($arr,'email')) ? notags(punify(trim($arr['email']))) : '');
|
||||
$password = ((x($arr,'password')) ? trim($arr['password']) : '');
|
||||
$password2 = ((x($arr,'password2')) ? trim($arr['password2']) : '');
|
||||
$parent = ((x($arr,'parent')) ? intval($arr['parent']) : 0 );
|
||||
|
||||
@@ -193,26 +193,18 @@ require_once('include/api_zot.php');
|
||||
$redirect = trim($_REQUEST['redirect_uris'][0]);
|
||||
else
|
||||
$redirect = trim($_REQUEST['redirect_uris']);
|
||||
$grant_types = trim($_REQUEST['grant_types']);
|
||||
$scope = trim($_REQUEST['scope']);
|
||||
$icon = trim($_REQUEST['logo_uri']);
|
||||
if($oauth2) {
|
||||
$r = q("INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id)
|
||||
VALUES ( '%s', '%s', '%s', null, null, null ) ",
|
||||
dbesc($key),
|
||||
dbesc($secret),
|
||||
dbesc($redirect)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)
|
||||
VALUES ('%s','%s','%s','%s','%s',%d)",
|
||||
dbesc($key),
|
||||
dbesc($secret),
|
||||
dbesc($name),
|
||||
dbesc($redirect),
|
||||
dbesc($icon),
|
||||
intval(0)
|
||||
);
|
||||
}
|
||||
$r = q("INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id)
|
||||
VALUES ( '%s', '%s', '%s', '%s', '%s', '%s' ) ",
|
||||
dbesc($key),
|
||||
dbesc($secret),
|
||||
dbesc($redirect),
|
||||
dbesc($grant_types),
|
||||
dbesc($scope),
|
||||
dbesc((string) api_user())
|
||||
);
|
||||
|
||||
$ret['client_id'] = $key;
|
||||
$ret['client_secret'] = $secret;
|
||||
|
||||
@@ -14,25 +14,58 @@ function api_login(&$a){
|
||||
|
||||
// login with oauth
|
||||
try {
|
||||
$oauth = new ZotOAuth1();
|
||||
$req = OAuth1Request::from_request();
|
||||
// OAuth 2.0
|
||||
$storage = new \Zotlabs\Identity\OAuth2Storage(\DBA::$dba->db);
|
||||
$server = new \Zotlabs\Identity\OAuth2Server($storage);
|
||||
$request = \OAuth2\Request::createFromGlobals();
|
||||
if ($server->verifyResourceRequest($request)) {
|
||||
$token = $server->getAccessTokenData($request);
|
||||
$uid = $token['user_id'];
|
||||
$r = q("SELECT * FROM channel WHERE channel_id = %d LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
if (count($r)) {
|
||||
$record = $r[0];
|
||||
} else {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo('This api requires login');
|
||||
killme();
|
||||
}
|
||||
|
||||
list($consumer,$token) = $oauth->verify_request($req);
|
||||
$_SESSION['uid'] = $record['channel_id'];
|
||||
$_SESSION['addr'] = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
if (!is_null($token)){
|
||||
$oauth->loginUser($token->uid);
|
||||
$x = q("select * from account where account_id = %d LIMIT 1",
|
||||
intval($record['channel_account_id'])
|
||||
);
|
||||
if ($x) {
|
||||
require_once('include/security.php');
|
||||
authenticate_success($x[0], null, true, false, true, true);
|
||||
$_SESSION['allow_api'] = true;
|
||||
call_hooks('logged_in', App::$user);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// OAuth 1.0
|
||||
$oauth = new ZotOAuth1();
|
||||
$req = OAuth1Request::from_request();
|
||||
|
||||
App::set_oauth_key($consumer->key);
|
||||
list($consumer, $token) = $oauth->verify_request($req);
|
||||
|
||||
call_hooks('logged_in', App::$user);
|
||||
return;
|
||||
if (!is_null($token)) {
|
||||
$oauth->loginUser($token->uid);
|
||||
|
||||
App::set_oauth_key($consumer->key);
|
||||
|
||||
call_hooks('logged_in', App::$user);
|
||||
return;
|
||||
}
|
||||
killme();
|
||||
}
|
||||
killme();
|
||||
}
|
||||
catch(Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
logger($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
// workarounds for HTTP-auth in CGI mode
|
||||
|
||||
foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) {
|
||||
|
||||
@@ -266,14 +266,12 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(! perm_is_allowed($r[0]['uid'], $observer_hash, 'view_storage')) {
|
||||
if(! attach_can_view($r[0]['uid'], $observer_hash, $hash)) {
|
||||
$ret['message'] = t('Permission denied.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$sql_extra = permissions_sql($r[0]['uid'],$observer_hash);
|
||||
|
||||
// Now we'll see if we can access the attachment
|
||||
// We've already checked for existence and permissions
|
||||
|
||||
$r = q("SELECT * FROM attach WHERE hash = '%s' and uid = %d $sql_extra LIMIT 1",
|
||||
dbesc($hash),
|
||||
@@ -281,20 +279,12 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
$ret['message'] = t('Permission denied.');
|
||||
$ret['message'] = t('Unknown error.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r[0]['content'] = dbunescbin($r[0]['content']);
|
||||
|
||||
if($r[0]['folder']) {
|
||||
$x = attach_can_view_folder($r[0]['uid'],$observer_hash,$r[0]['folder']);
|
||||
if(! $x) {
|
||||
$ret['message'] = t('Permission denied.');
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
$ret['success'] = true;
|
||||
$ret['data'] = $r[0];
|
||||
|
||||
@@ -302,6 +292,29 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
|
||||
}
|
||||
|
||||
|
||||
function attach_can_view($uid,$ob_hash,$resource) {
|
||||
|
||||
$sql_extra = permissions_sql($uid,$ob_hash);
|
||||
$hash = $resource;
|
||||
|
||||
if(! perm_is_allowed($uid,$ob_hash,'view_storage')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra",
|
||||
dbesc($hash),
|
||||
intval($uid)
|
||||
);
|
||||
if(! $r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return attach_can_view_folder($uid,$ob_hash,$r[0]['folder']);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
|
||||
|
||||
$sql_extra = permissions_sql($uid,$ob_hash);
|
||||
@@ -948,6 +961,16 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Update the folder timestamp @todo recurse to the storage root folder
|
||||
|
||||
if($folder_hash) {
|
||||
q("UPDATE attach set edited = '%s' where hash = '%s' and uid = %d and is_dir = 1",
|
||||
dbesc($edited),
|
||||
dbesc($folder_hash),
|
||||
intval($channel_id)
|
||||
);
|
||||
}
|
||||
|
||||
// Caution: This re-uses $sql_options set further above
|
||||
|
||||
$r = q("select * from attach where uid = %d and hash = '%s' $sql_options limit 1",
|
||||
@@ -2276,33 +2299,22 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
||||
if(! ($c && $resource_id))
|
||||
return false;
|
||||
|
||||
|
||||
// find the resource to be moved
|
||||
|
||||
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
|
||||
dbesc($resource_id),
|
||||
intval($channel_id)
|
||||
);
|
||||
if(! $r)
|
||||
if(! $r) {
|
||||
logger('resource_id not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldstorepath = dbunescbin($r[0]['content']);
|
||||
|
||||
if($r[0]['is_dir']) {
|
||||
$move_success = true;
|
||||
$x = q("select hash from attach where folder = '%s' and uid = %d",
|
||||
dbesc($r[0]['hash']),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
|
||||
if(! $rs) {
|
||||
$move_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $move_success;
|
||||
}
|
||||
|
||||
// find the resource we are moving to
|
||||
|
||||
if($new_folder_hash) {
|
||||
$n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
|
||||
@@ -2316,6 +2328,10 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
||||
$newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id;
|
||||
}
|
||||
else {
|
||||
|
||||
// root directory
|
||||
|
||||
$newdirname = EMPTY_STR;
|
||||
$newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id;
|
||||
}
|
||||
|
||||
@@ -2325,56 +2341,61 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
||||
|
||||
$filename = $r[0]['filename'];
|
||||
|
||||
$s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
|
||||
dbesc($filename),
|
||||
dbesc($new_folder_hash)
|
||||
);
|
||||
// don't do duplicate check unless our parent folder has changed.
|
||||
|
||||
if($s) {
|
||||
$overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
|
||||
if($overwrite) {
|
||||
/// @fixme
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(strpos($filename,'.') !== false) {
|
||||
$basename = substr($filename,0,strrpos($filename,'.'));
|
||||
$ext = substr($filename,strrpos($filename,'.'));
|
||||
if($r[0]['folder'] !== $new_folder_hash) {
|
||||
|
||||
$s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
|
||||
dbesc($filename),
|
||||
dbesc($new_folder_hash)
|
||||
);
|
||||
|
||||
if($s) {
|
||||
$overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
|
||||
if($overwrite) {
|
||||
/// @fixme
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$basename = $filename;
|
||||
$ext = '';
|
||||
}
|
||||
|
||||
$matches = false;
|
||||
if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
|
||||
$basename = $matches[1];
|
||||
|
||||
$v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
|
||||
dbesc($basename . $ext),
|
||||
dbesc($basename . '(%)' . $ext),
|
||||
dbesc($new_folder_hash)
|
||||
);
|
||||
|
||||
if($v) {
|
||||
$x = 1;
|
||||
|
||||
do {
|
||||
$found = false;
|
||||
foreach($v as $vv) {
|
||||
if($vv['filename'] === $basename . '(' . $x . ')' . $ext) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($found)
|
||||
$x++;
|
||||
if(strpos($filename,'.') !== false) {
|
||||
$basename = substr($filename,0,strrpos($filename,'.'));
|
||||
$ext = substr($filename,strrpos($filename,'.'));
|
||||
}
|
||||
while($found);
|
||||
$filename = $basename . '(' . $x . ')' . $ext;
|
||||
else {
|
||||
$basename = $filename;
|
||||
$ext = '';
|
||||
}
|
||||
|
||||
$matches = false;
|
||||
if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
|
||||
$basename = $matches[1];
|
||||
|
||||
$v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
|
||||
dbesc($basename . $ext),
|
||||
dbesc($basename . '(%)' . $ext),
|
||||
dbesc($new_folder_hash)
|
||||
);
|
||||
|
||||
if($v) {
|
||||
$x = 1;
|
||||
|
||||
do {
|
||||
$found = false;
|
||||
foreach($v as $vv) {
|
||||
if($vv['filename'] === $basename . '(' . $x . ')' . $ext) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if($found)
|
||||
$x++;
|
||||
}
|
||||
while($found);
|
||||
$filename = $basename . '(' . $x . ')' . $ext;
|
||||
}
|
||||
else
|
||||
$filename = $basename . $ext;
|
||||
}
|
||||
else
|
||||
$filename = $basename . $ext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2413,6 +2434,24 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
||||
);
|
||||
}
|
||||
|
||||
if($r[0]['is_dir']) {
|
||||
$move_success = true;
|
||||
$x = q("select hash from attach where folder = '%s' and uid = %d",
|
||||
dbesc($r[0]['hash']),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
|
||||
if(! $rs) {
|
||||
$move_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $move_success;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ require_once('include/security.php');
|
||||
function account_verify_password($login, $pass) {
|
||||
|
||||
$ret = [ 'account' => null, 'channel' => null, 'xchan' => null ];
|
||||
$login = punify($login);
|
||||
|
||||
$email_verify = get_config('system', 'verify_email');
|
||||
$register_policy = get_config('system', 'register_policy');
|
||||
@@ -144,8 +145,17 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
// process logout request
|
||||
$args = array('channel_id' => local_channel());
|
||||
call_hooks('logging_out', $args);
|
||||
App::$session->nuke();
|
||||
info( t('Logged out.') . EOL);
|
||||
|
||||
|
||||
if($_SESSION['delegate'] && $_SESSION['delegate_push']) {
|
||||
$_SESSION = $_SESSION['delegate_push'];
|
||||
info( t('Delegation session ended.') . EOL);
|
||||
}
|
||||
else {
|
||||
App::$session->nuke();
|
||||
info( t('Logged out.') . EOL);
|
||||
}
|
||||
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
@@ -235,7 +245,7 @@ else {
|
||||
$record = null;
|
||||
|
||||
$addon_auth = array(
|
||||
'username' => trim($_POST['username']),
|
||||
'username' => punify(trim($_POST['username'])),
|
||||
'password' => trim($_POST['password']),
|
||||
'authenticated' => 0,
|
||||
'user_record' => null
|
||||
@@ -261,7 +271,7 @@ else {
|
||||
$verify = account_verify_password($_POST['username'], $_POST['password']);
|
||||
if($verify && array_key_exists('reason',$verify) && $verify['reason'] === 'unvalidated') {
|
||||
notice( t('Email validation is incomplete. Please check your email.'));
|
||||
goaway(z_root() . '/email_validation/' . bin2hex(trim(escape_tags($_POST['username']))));
|
||||
goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($_POST['username'])))));
|
||||
}
|
||||
elseif($verify) {
|
||||
$atoken = $verify['xchan'];
|
||||
|
||||
@@ -85,12 +85,14 @@ function tryoembed($match) {
|
||||
function nakedoembed($match) {
|
||||
$url = ((count($match) == 2) ? $match[1] : $match[2]);
|
||||
|
||||
$o = oembed_fetch_url($url);
|
||||
$strip_url = strip_escaped_zids($url);
|
||||
|
||||
$o = oembed_fetch_url($strip_url);
|
||||
|
||||
if ($o['type'] == 'error')
|
||||
return $match[0];
|
||||
return str_replace($url,$strip_url,$match[0]);
|
||||
|
||||
return '[embed]' . $url . '[/embed]';
|
||||
return '[embed]' . $strip_url . '[/embed]';
|
||||
}
|
||||
|
||||
function tryzrlaudio($match) {
|
||||
@@ -311,6 +313,19 @@ function bb_ShareAttributes($match) {
|
||||
if ($matches[1] != "")
|
||||
$posted = $matches[1];
|
||||
|
||||
$auth = "";
|
||||
preg_match("/auth='(.*?)'/ism", $attributes, $matches);
|
||||
if ($matches[1] != "") {
|
||||
if($matches[1] === 'true')
|
||||
$auth = true;
|
||||
else
|
||||
$auth = false;
|
||||
}
|
||||
|
||||
if($auth === EMPTY_STR) {
|
||||
$auth = is_matrix_url($profile);
|
||||
}
|
||||
|
||||
// message_id is never used, do we still need it?
|
||||
$message_id = "";
|
||||
preg_match("/message_id='(.*?)'/ism", $attributes, $matches);
|
||||
@@ -329,7 +344,7 @@ function bb_ShareAttributes($match) {
|
||||
$headline = '<div class="shared_container"> <div class="shared_header">';
|
||||
|
||||
if ($avatar != "")
|
||||
$headline .= '<a href="' . zid($profile) . '" ><img src="' . $avatar . '" alt="' . $author . '" height="32" width="32" /></a>';
|
||||
$headline .= '<a href="' . (($auth) ? zid($profile) : $profile) . '" ><img src="' . $avatar . '" alt="' . $author . '" height="32" width="32" /></a>';
|
||||
|
||||
if(strpos($link,'/cards/'))
|
||||
$type = t('card');
|
||||
@@ -341,8 +356,8 @@ function bb_ShareAttributes($match) {
|
||||
// Bob Smith wrote the following post 2 hours ago
|
||||
|
||||
$fmt = sprintf( t('%1$s wrote the following %2$s %3$s'),
|
||||
'<a href="' . zid($profile) . '" >' . $author . '</a>',
|
||||
'<a href="' . zid($link) . '" >' . $type . '</a>',
|
||||
'<a href="' . (($auth) ? zid($profile) : $profile) . '" >' . $author . '</a>',
|
||||
'<a href="' . (($auth) ? zid($link) : $link) . '" >' . $type . '</a>',
|
||||
$reldate
|
||||
);
|
||||
|
||||
@@ -393,7 +408,7 @@ function bb_ShareAttributesSimple($match) {
|
||||
if ($matches[1] != "")
|
||||
$profile = $matches[1];
|
||||
|
||||
$text = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' <a href="' . $profile . '">' . $author . '</a>: div class="reshared-content">' . $match[2] . '</div>';
|
||||
$text = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8') . ' <a href="' . $profile . '">' . $author . '</a>: <div class="reshared-content">' . $match[2] . '</div>';
|
||||
|
||||
return($text);
|
||||
}
|
||||
@@ -668,6 +683,31 @@ function bb_fixtable_lf($match) {
|
||||
|
||||
}
|
||||
|
||||
function bbtopoll($s) {
|
||||
|
||||
$pl = [];
|
||||
|
||||
$match = '';
|
||||
if(! preg_match("/\[poll=(.*?)\](.*?)\[\/poll\]/ism",$s,$match)) {
|
||||
return null;
|
||||
}
|
||||
$pl['poll_id'] = $match[1];
|
||||
$pl['poll_question'] = $match[2];
|
||||
|
||||
$match = '';
|
||||
if(preg_match_all("/\[poll\-answer=(.*?)\](.*?)\[\/poll\-answer\]/is",$s,$match,PREG_SET_ORDER)) {
|
||||
$pl['answer'] = [];
|
||||
foreach($match as $m) {
|
||||
$ans = [ 'answer_id' => $m[1], 'answer_text' => $m[2] ];
|
||||
$pl['answer'][] = $ans;
|
||||
}
|
||||
}
|
||||
|
||||
return $pl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function parseIdentityAwareHTML($Text) {
|
||||
|
||||
// Hide all [noparse] contained bbtags by spacefying them
|
||||
@@ -742,10 +782,16 @@ function parseIdentityAwareHTML($Text) {
|
||||
|
||||
function bbcode($Text, $options = []) {
|
||||
|
||||
if(! is_array($options)) {
|
||||
$options = [];
|
||||
}
|
||||
|
||||
$preserve_nl = ((array_key_exists('preserve_nl',$options)) ? $options['preserve_nl'] : false);
|
||||
$tryoembed = ((array_key_exists('tryoembed',$options)) ? $options['tryoembed'] : true);
|
||||
$cache = ((array_key_exists('cache',$options)) ? $options['cache'] : false);
|
||||
$newwin = ((array_key_exists('newwin',$options)) ? $options['newwin'] : true);
|
||||
|
||||
$target = (($newwin) ? ' target="_blank" ' : '');
|
||||
|
||||
call_hooks('bbcode_filter', $Text);
|
||||
|
||||
@@ -766,6 +812,11 @@ function bbcode($Text, $options = []) {
|
||||
|
||||
$ev = bbtoevent($Text);
|
||||
|
||||
// and the same with polls
|
||||
|
||||
$pl = bbtopoll($Text);
|
||||
|
||||
|
||||
// process [observer] tags before we do anything else because we might
|
||||
// be stripping away stuff that then doesn't need to be worked on anymore
|
||||
|
||||
@@ -891,7 +942,7 @@ function bbcode($Text, $options = []) {
|
||||
if($tryoembed) {
|
||||
$Text = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", 'tryoembed', $Text);
|
||||
}
|
||||
$Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" target="_blank" rel="nofollow noopener">$2</a>', $Text);
|
||||
$Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ismu", '$1<a href="$2" ' . $target . ' rel="nofollow noopener">$2</a>', $Text);
|
||||
}
|
||||
|
||||
if (strpos($Text,'[/share]') !== false) {
|
||||
@@ -903,16 +954,16 @@ function bbcode($Text, $options = []) {
|
||||
}
|
||||
}
|
||||
if (strpos($Text,'[/url]') !== false) {
|
||||
$Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_blank" rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_blank" rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/zrl]') !== false) {
|
||||
$Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_blank" rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
}
|
||||
|
||||
if (get_account_techlevel() < 2)
|
||||
@@ -920,8 +971,8 @@ function bbcode($Text, $options = []) {
|
||||
|
||||
// Perform MAIL Search
|
||||
if (strpos($Text,'[/mail]') !== false) {
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" target="_blank" rel="nofollow noopener" >$2</a>', $Text);
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" ' . $target . ' rel="nofollow noopener" >$2</a>', $Text);
|
||||
}
|
||||
|
||||
|
||||
@@ -952,11 +1003,11 @@ function bbcode($Text, $options = []) {
|
||||
}
|
||||
// Check for strike-through text
|
||||
if (strpos($Text,'[s]') !== false) {
|
||||
$Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<strike>$1</strike>', $Text);
|
||||
$Text = preg_replace("(\[s\](.*?)\[\/s\])ism", '<span style="text-decoration: line-through;">$1</span>', $Text);
|
||||
}
|
||||
// Check for over-line text
|
||||
if (strpos($Text,'[o]') !== false) {
|
||||
$Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span class="overline">$1</span>', $Text);
|
||||
$Text = preg_replace("(\[o\](.*?)\[\/o\])ism", '<span style="text-decoration: overline;">$1</span>', $Text);
|
||||
}
|
||||
if (strpos($Text,'[sup]') !== false) {
|
||||
$Text = preg_replace("(\[sup\](.*?)\[\/sup\])ism", '<sup>$1</sup>', $Text);
|
||||
@@ -1243,29 +1294,19 @@ function bbcode($Text, $options = []) {
|
||||
|
||||
// if video couldn't be embedded, link to it instead.
|
||||
if (strpos($Text,'[/video]') !== false) {
|
||||
$Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/audio]') !== false) {
|
||||
$Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
}
|
||||
|
||||
if (strpos($Text,'[/zvideo]') !== false) {
|
||||
$Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
}
|
||||
if (strpos($Text,'[/zaudio]') !== false) {
|
||||
$Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" ' . $target . ' rel="nofollow noopener" >$1</a>', $Text);
|
||||
}
|
||||
|
||||
// if ($tryoembed){
|
||||
// if (strpos($Text,'[/iframe]') !== false) {
|
||||
// $Text = preg_replace_callback("/\[iframe\](.*?)\[\/iframe\]/ism", 'bb_iframe', $Text);
|
||||
// }
|
||||
// } else {
|
||||
// if (strpos($Text,'[/iframe]') !== false) {
|
||||
// $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1" target="_blank" rel="nofollow noopener" >$1</a>', $Text);
|
||||
// }
|
||||
// }
|
||||
|
||||
// oembed tag
|
||||
$Text = oembed_bbcode2html($Text);
|
||||
|
||||
|
||||
@@ -780,7 +780,7 @@ function identity_basic_export($channel_id, $sections = null) {
|
||||
}
|
||||
}
|
||||
|
||||
if(in_array('channel',$sections)) {
|
||||
if(in_array('channel',$sections) || in_array('profile',$sections)) {
|
||||
$r = q("select * from profile where uid = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
@@ -1234,7 +1234,7 @@ function profile_load($nickname, $profile = '') {
|
||||
);
|
||||
if($z) {
|
||||
$p[0]['picdate'] = $z[0]['xchan_photo_date'];
|
||||
$p[0]['reddress'] = str_replace('@','@',$z[0]['xchan_addr']);
|
||||
$p[0]['reddress'] = str_replace('@','@',unpunify($z[0]['xchan_addr']));
|
||||
}
|
||||
|
||||
// fetch user tags if this isn't the default profile
|
||||
@@ -1255,7 +1255,7 @@ function profile_load($nickname, $profile = '') {
|
||||
|
||||
App::$profile = $p[0];
|
||||
App::$profile_uid = $p[0]['profile_uid'];
|
||||
App::$page['title'] = App::$profile['channel_name'] . " - " . channel_reddress(App::$profile);
|
||||
App::$page['title'] = App::$profile['channel_name'] . " - " . unpunify(channel_reddress(App::$profile));
|
||||
|
||||
App::$profile['permission_to_view'] = $can_view_profile;
|
||||
|
||||
@@ -1573,14 +1573,25 @@ function advanced_profile() {
|
||||
$profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s'));
|
||||
}
|
||||
|
||||
if(App::$profile['keywords']) {
|
||||
$keywords = str_replace(',',' ', App::$profile['keywords']);
|
||||
$keywords = str_replace(' ',' ', $keywords);
|
||||
$karr = explode(' ', $keywords);
|
||||
if($karr) {
|
||||
for($cnt = 0; $cnt < count($karr); $cnt ++) {
|
||||
$karr[$cnt] = '<a href="' . z_root() . '/directory/f=&keywords=' . trim($karr[$cnt]) . '">' . $karr[$cnt] . '</a>';
|
||||
}
|
||||
}
|
||||
$profile['keywords'] = array( t('Tags:'), implode(' ', $karr));
|
||||
}
|
||||
|
||||
|
||||
if(App::$profile['sexual']) $profile['sexual'] = array( t('Sexual Preference:'), App::$profile['sexual'] );
|
||||
|
||||
if(App::$profile['homepage']) $profile['homepage'] = array( t('Homepage:'), linkify(App::$profile['homepage']) );
|
||||
|
||||
if(App::$profile['hometown']) $profile['hometown'] = array( t('Hometown:'), linkify(App::$profile['hometown']) );
|
||||
|
||||
if(App::$profile['keywords']) $profile['keywords'] = array( t('Tags:'), App::$profile['keywords']);
|
||||
|
||||
if(App::$profile['politic']) $profile['politic'] = array( t('Political Views:'), App::$profile['politic']);
|
||||
|
||||
if(App::$profile['religion']) $profile['religion'] = array( t('Religion:'), App::$profile['religion']);
|
||||
@@ -2552,7 +2563,7 @@ function channel_remove($channel_id, $local = true, $unset_session = false) {
|
||||
q("DELETE FROM photo WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM attach WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM profile WHERE uid = %d", intval($channel_id));
|
||||
q("DELETE FROM src WHERE src_channel_id = %d", intval($channel_id));
|
||||
q("DELETE FROM source WHERE src_channel_id = %d", intval($channel_id));
|
||||
|
||||
$r = q("select hash FROM attach WHERE uid = %d", intval($channel_id));
|
||||
if($r) {
|
||||
@@ -2714,7 +2725,7 @@ function anon_identity_init($reqvars) {
|
||||
|
||||
$hash = hash('md5',$anon_email);
|
||||
|
||||
$x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' limit 1",
|
||||
$x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1",
|
||||
dbesc($anon_email),
|
||||
dbesc($hash)
|
||||
);
|
||||
@@ -2725,19 +2736,19 @@ function anon_identity_init($reqvars) {
|
||||
'xchan_hash' => $hash,
|
||||
'xchan_name' => $anon_name,
|
||||
'xchan_url' => $anon_url,
|
||||
'xchan_network' => 'unknown',
|
||||
'xchan_network' => 'anon',
|
||||
'xchan_name_date' => datetime_convert()
|
||||
]);
|
||||
|
||||
|
||||
$x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' limit 1",
|
||||
$x = q("select * from xchan where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' limit 1",
|
||||
dbesc($anon_email),
|
||||
dbesc($hash)
|
||||
);
|
||||
|
||||
$photo = z_root() . '/' . get_default_profile_photo(300);
|
||||
$photos = import_xchan_photo($photo,$hash);
|
||||
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'unknown' ",
|
||||
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_guid = '%s' and xchan_hash = '%s' and xchan_network = 'anon' ",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
|
||||
@@ -100,7 +100,6 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
if(! $xchan)
|
||||
return;
|
||||
|
||||
// FIXME - show connect button to observer if appropriate
|
||||
$connect = false;
|
||||
if(local_channel()) {
|
||||
$r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
@@ -111,6 +110,12 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
$connect = t('Connect');
|
||||
}
|
||||
|
||||
// don't provide a connect button for transient or one-way identities
|
||||
|
||||
if(in_array($xchan['xchan_network'],['rss','anon','unknown']) || strpos($xchan['xchan_addr'],'guest:') === 0) {
|
||||
$connect = false;
|
||||
}
|
||||
|
||||
if(array_key_exists('channel_id',$xchan))
|
||||
App::$profile_uid = $xchan['channel_id'];
|
||||
|
||||
@@ -122,7 +127,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
return replace_macros(get_markup_template('xchan_vcard.tpl'),array(
|
||||
'$name' => $xchan['xchan_name'],
|
||||
'$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']),
|
||||
'$follow' => $xchan['xchan_addr'],
|
||||
'$follow' => (($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']),
|
||||
'$link' => zid($xchan['xchan_url']),
|
||||
'$connect' => $connect,
|
||||
'$newwin' => (($mode === 'chanview') ? t('New window') : ''),
|
||||
@@ -421,7 +426,10 @@ function random_profile() {
|
||||
|
||||
for($i = 0; $i < $retryrandom; $i++) {
|
||||
|
||||
$r = q("select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_hidden = 0 and xchan_system = 0 and hubloc_connected > %s - interval %s order by $randfunc limit 1",
|
||||
$r = q("select xchan_url, xchan_hash from xchan left join hubloc on hubloc_hash = xchan_hash where
|
||||
xchan_hidden = 0 and xchan_system = 0 and
|
||||
xchan_network = 'zot' and xchan_deleted = 0 and
|
||||
hubloc_connected > %s - interval %s order by $randfunc limit 1",
|
||||
db_utcnow(),
|
||||
db_quoteinterval('30 day')
|
||||
);
|
||||
|
||||
@@ -404,7 +404,7 @@ function count_descendants($item) {
|
||||
* @return boolean
|
||||
*/
|
||||
function visible_activity($item) {
|
||||
$hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE ];
|
||||
$hidden_activities = [ ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_AGREE, ACTIVITY_DISAGREE, ACTIVITY_ABSTAIN, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_POLLRESPONSE ];
|
||||
|
||||
if(intval($item['item_notshown']))
|
||||
return false;
|
||||
@@ -930,7 +930,7 @@ function thread_action_menu($item,$mode = '') {
|
||||
$menu[] = [
|
||||
'menu' => 'view_source',
|
||||
'title' => t('View Source'),
|
||||
'icon' => 'eye',
|
||||
'icon' => 'code',
|
||||
'action' => 'viewsrc(' . $item['id'] . '); return false;',
|
||||
'href' => '#'
|
||||
];
|
||||
@@ -1039,7 +1039,7 @@ function thread_author_menu($item, $mode = '') {
|
||||
if($posts_link) {
|
||||
$menu[] = [
|
||||
'menu' => 'view_posts',
|
||||
'title' => t('Activity/Posts'),
|
||||
'title' => t('Recent Activity'),
|
||||
'icon' => 'fw',
|
||||
'action' => '',
|
||||
'href' => $posts_link
|
||||
@@ -1301,7 +1301,9 @@ function status_editor($a, $x, $popup = false) {
|
||||
$id_select = '';
|
||||
|
||||
$webpage = ((x($x,'webpage')) ? $x['webpage'] : '');
|
||||
|
||||
|
||||
$feature_auto_save_draft = ((feature_enabled($x['profile_uid'], 'auto_save_draft')) ? "true" : "false");
|
||||
|
||||
$tpl = get_markup_template('jot-header.tpl');
|
||||
|
||||
App::$page['htmlhead'] .= replace_macros($tpl, array(
|
||||
@@ -1323,6 +1325,7 @@ function status_editor($a, $x, $popup = false) {
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$nocomment_enabled' => t('Comments enabled'),
|
||||
'$nocomment_disabled' => t('Comments disabled'),
|
||||
'$auto_save_draft' => $feature_auto_save_draft,
|
||||
));
|
||||
|
||||
$tpl = get_markup_template('jot.tpl');
|
||||
@@ -1607,7 +1610,7 @@ function prepare_page($item) {
|
||||
// prepare_body calls unobscure() as a side effect. Do it here so that
|
||||
// the template will get passed an unobscured title.
|
||||
|
||||
$body = prepare_body($item, true);
|
||||
$body = prepare_body($item, [ 'newwin' => false ]);
|
||||
if(App::$page['template'] == 'none') {
|
||||
$tpl = 'page_display_empty.tpl';
|
||||
|
||||
@@ -1721,7 +1724,7 @@ function network_tabs() {
|
||||
if(feature_enabled(local_channel(),'star_posts')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('Starred'),
|
||||
'url'=>z_root() . '/' . $cmd . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&star=1',
|
||||
'url'=>z_root() . '/' . $cmd . '/?f=' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . '&star=1',
|
||||
'sel'=>$starred_active,
|
||||
'title' => t('Favourite Posts'),
|
||||
);
|
||||
|
||||
@@ -125,10 +125,16 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
|
||||
*/
|
||||
function dob($dob) {
|
||||
|
||||
$y = substr($dob,0,4);
|
||||
if((! ctype_digit($y)) || ($y < 1900))
|
||||
$ignore_year = true;
|
||||
else
|
||||
$ignore_year = false;
|
||||
|
||||
if ($dob === '0000-00-00' || $dob === '')
|
||||
$value = '';
|
||||
else
|
||||
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
|
||||
$value = (($ignore_year) ? datetime_convert('UTC','UTC',$dob,'m-d') : datetime_convert('UTC','UTC',$dob,'Y-m-d'));
|
||||
|
||||
$o = replace_macros(get_markup_template("field_input.tpl"), [
|
||||
'$field' => [ 'dob', t('Birthday'), $value, ((intval($value)) ? t('Age: ') . age($value,App::$user['timezone'],App::$user['timezone']) : ''), '', 'placeholder="' . t('YYYY-MM-DD or MM-DD') .'"' ]
|
||||
|
||||
@@ -460,3 +460,28 @@ function db_logger($s,$level = LOGGER_NORMAL,$syslog = LOG_INFO) {
|
||||
\DBA::$logging = false;
|
||||
\DBA::$dba->debug = $saved;
|
||||
}
|
||||
|
||||
|
||||
function db_columns($table) {
|
||||
|
||||
if($table) {
|
||||
if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) {
|
||||
$r = q("SELECT column_name as field FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '%s'",
|
||||
dbesc($table)
|
||||
);
|
||||
if($r) {
|
||||
return ids_to_array($r,'field');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$r = q("show columns in %s",
|
||||
dbesc($table)
|
||||
);
|
||||
if($r) {
|
||||
return ids_to_array($r,'Field');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -100,7 +100,9 @@ class dba_pdo extends dba_driver {
|
||||
|
||||
if($this->debug) {
|
||||
db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO);
|
||||
db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
|
||||
if(intval($this->debug) > 1) {
|
||||
db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
return (($this->error) ? false : $r);
|
||||
|
||||
@@ -1322,3 +1322,25 @@ function translate_type($type) {
|
||||
return [$type, t('Other') . ' (' . $type . ')'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cal_store_lowlevel($arr) {
|
||||
|
||||
$store = [
|
||||
'cal_aid' => ((array_key_exists('cal_aid',$arr)) ? $arr['cal_aid'] : 0),
|
||||
'cal_uid' => ((array_key_exists('cal_uid',$arr)) ? $arr['cal_uid'] : 0),
|
||||
'cal_hash' => ((array_key_exists('cal_hash',$arr)) ? $arr['cal_hash'] : ''),
|
||||
'cal_name' => ((array_key_exists('cal_name',$arr)) ? $arr['cal_name'] : ''),
|
||||
'uri' => ((array_key_exists('uri',$arr)) ? $arr['uri'] : ''),
|
||||
'logname' => ((array_key_exists('logname',$arr)) ? $arr['logname'] : ''),
|
||||
'pass' => ((array_key_exists('pass',$arr)) ? $arr['pass'] : ''),
|
||||
'ctag' => ((array_key_exists('ctag',$arr)) ? $arr['ctag'] : ''),
|
||||
'synctoken' => ((array_key_exists('synctoken',$arr)) ? $arr['synctoken'] : ''),
|
||||
'cal_types' => ((array_key_exists('cal_types',$arr)) ? $arr['cal_types'] : ''),
|
||||
];
|
||||
|
||||
return create_table_from_array('cal', $store);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,8 +28,9 @@ function get_feature_default($feature) {
|
||||
$f = get_features(false);
|
||||
foreach($f as $cat) {
|
||||
foreach($cat as $feat) {
|
||||
if(is_array($feat) && $feat[0] === $feature)
|
||||
if(is_array($feat) && $feat[0] === $feature) {
|
||||
return $feat[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -43,8 +44,9 @@ function feature_level($feature,$def) {
|
||||
return $def;
|
||||
}
|
||||
|
||||
function get_features($filtered = true) {
|
||||
function get_features($filtered = true, $level = (-1)) {
|
||||
|
||||
$account = \App::get_account();
|
||||
|
||||
$arr = [
|
||||
|
||||
@@ -53,7 +55,14 @@ function get_features($filtered = true) {
|
||||
|
||||
t('General Features'),
|
||||
|
||||
|
||||
[
|
||||
'start_menu',
|
||||
t('New Member Links'),
|
||||
t('Display new member quick links menu'),
|
||||
(($account['account_created'] > datetime_convert('','','now - 60 days')) ? true : false),
|
||||
get_config('feature_lock','start_menu'),
|
||||
feature_level('start_menu',1),
|
||||
],
|
||||
|
||||
[
|
||||
'advanced_profiles',
|
||||
@@ -237,13 +246,22 @@ function get_features($filtered = true) {
|
||||
|
||||
[
|
||||
'oauth_clients',
|
||||
t('OAuth Clients'),
|
||||
t('Manage authenticatication tokens for mobile and remote apps.'),
|
||||
t('OAuth1 Clients'),
|
||||
t('Manage OAuth1 authenticatication tokens for mobile and remote apps.'),
|
||||
false,
|
||||
get_config('feature_lock','oauth_clients'),
|
||||
feature_level('oauth_clients',1),
|
||||
],
|
||||
|
||||
[
|
||||
'oauth2_clients',
|
||||
t('OAuth2 Clients'),
|
||||
t('Manage OAuth2 authenticatication tokens for mobile and remote apps.'),
|
||||
false,
|
||||
get_config('feature_lock','oauth2_clients'),
|
||||
feature_level('oauth2_clients',1),
|
||||
],
|
||||
|
||||
[
|
||||
'access_tokens',
|
||||
t('Access Tokens'),
|
||||
@@ -332,6 +350,15 @@ function get_features($filtered = true) {
|
||||
feature_level('suppress_duplicates',1),
|
||||
],
|
||||
|
||||
[
|
||||
'auto_save_draft',
|
||||
t('Auto-save drafts of posts and comments'),
|
||||
t('Automatically saves post and comment drafts in local browser storage to help prevent accidental loss of compositions'),
|
||||
true,
|
||||
get_config('feature_lock','auto_save_draft'),
|
||||
feature_level('auto_save_draft',1),
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
// Network Tools
|
||||
@@ -481,7 +508,7 @@ function get_features($filtered = true) {
|
||||
|
||||
$arr = $x['features'];
|
||||
|
||||
$techlevel = get_account_techlevel();
|
||||
$techlevel = (($level >= 0) ? $level : get_account_techlevel());
|
||||
|
||||
// removed any locked features and remove the entire category if this makes it empty
|
||||
|
||||
|
||||
@@ -668,6 +668,14 @@ function get_atom_elements($feed, $item) {
|
||||
}
|
||||
$termterm = notags(trim(unxmlify($term)));
|
||||
|
||||
// Mastodon auto generates an nsfw category tag for any 'content-warning' message.
|
||||
// Most people use CW and use both summary/content as a spoiler and we honour that
|
||||
// construct so the post will already be collapsed. The generated tag is almost
|
||||
// always wrong and even if it isn't we would already be doing the right thing.
|
||||
|
||||
if($mastodon && $termterm === 'nsfw' && $summary && $res['body'])
|
||||
continue;
|
||||
|
||||
if($termterm) {
|
||||
$terms[] = array(
|
||||
'otype' => TERM_OBJ_POST,
|
||||
@@ -926,6 +934,7 @@ function feed_get_reshare(&$res,$item) {
|
||||
"' profile='" . $share['profile'] .
|
||||
"' avatar='" . $share['avatar'] .
|
||||
"' link='" . $share['alternate'] .
|
||||
"' auth='" . 'false' .
|
||||
"' posted='" . $share['created'] .
|
||||
"' message_id='" . $share['message_id'] . "']";
|
||||
|
||||
|
||||
@@ -88,9 +88,18 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
||||
|
||||
// Premium channel, set confirm before callback to avoid recursion
|
||||
|
||||
if(array_key_exists('connect_url',$j) && ($interactive) && (! $confirm))
|
||||
goaway(zid($j['connect_url']));
|
||||
|
||||
if(array_key_exists('connect_url',$j) && (! $confirm)) {
|
||||
if($interactive) {
|
||||
goaway(zid($j['connect_url']));
|
||||
}
|
||||
else {
|
||||
$result['message'] = t('Premium channel - please visit:') . ' ' . zid($j['connect_url']);
|
||||
logger('mod_follow: ' . $result['message']);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// do we have an xchan and hubloc?
|
||||
// If not, create them.
|
||||
@@ -141,9 +150,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
||||
|
||||
// attempt network auto-discovery
|
||||
|
||||
$d = discover_by_webbie($url,$protocol);
|
||||
$wf = discover_by_webbie($url,$protocol);
|
||||
|
||||
if((! $d) && ($is_http)) {
|
||||
if((! $wf) && ($is_http)) {
|
||||
|
||||
// try RSS discovery
|
||||
|
||||
@@ -158,9 +167,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
||||
}
|
||||
}
|
||||
|
||||
if($d) {
|
||||
if($wf || $d) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1",
|
||||
dbesc($url),
|
||||
dbesc(($wf) ? $wf : $url),
|
||||
dbesc($url)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ function store_doc_file($s) {
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
$item['body'] = html2plain(prepare_text(file_get_contents($s),$mimetype, true));
|
||||
$item['body'] = html2plain(prepare_text(file_get_contents($s),$mimetype, [ 'cache' => true ]));
|
||||
$item['mimetype'] = 'text/plain';
|
||||
|
||||
$item['plink'] = z_root() . '/' . str_replace('doc','help',$s);
|
||||
|
||||
@@ -164,6 +164,7 @@ function html2bbcode($message)
|
||||
node2bbcode($doc, 'b', array(), '[b]', '[/b]');
|
||||
node2bbcode($doc, 'i', array(), '[i]', '[/i]');
|
||||
node2bbcode($doc, 'u', array(), '[u]', '[/u]');
|
||||
node2bbcode($doc, 's', array(), '[s]', '[/s]');
|
||||
|
||||
node2bbcode($doc, 'big', array(), "[size=large]", "[/size]");
|
||||
node2bbcode($doc, 'small', array(), "[size=small]", "[/size]");
|
||||
|
||||
@@ -270,7 +270,8 @@ function locations_by_netid($netid) {
|
||||
dbesc($netid)
|
||||
);
|
||||
|
||||
return array_elm_to_str($locs,'location',', ');
|
||||
|
||||
return array_elm_to_str($locs,'location',', ','trim_and_unpunify');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ function import_channel($channel, $account_id, $seize) {
|
||||
$channel['channel_removed'] = (($channel['channel_pageflags'] & 0x8000) ? 1 : 0);
|
||||
}
|
||||
|
||||
if(intval($channel['channel_removed'])) {
|
||||
notice( t('Unable to import a removed channel.') . EOL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore the hash provided and re-calculate
|
||||
|
||||
$channel['channel_hash'] = make_xchan_hash($channel['channel_guid'],$channel['channel_guid_sig']);
|
||||
@@ -94,7 +99,7 @@ function import_channel($channel, $account_id, $seize) {
|
||||
}
|
||||
|
||||
if($clean) {
|
||||
create_table_from_array('channel',$clean);
|
||||
channel_store_lowlevel($clean);
|
||||
}
|
||||
|
||||
$r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1",
|
||||
@@ -176,7 +181,7 @@ function import_profiles($channel, $profiles) {
|
||||
$profile['thumb'] = z_root() . '/photo/' . basename($profile['thumb']);
|
||||
}
|
||||
|
||||
create_table_from_array('profile', $profile);
|
||||
profile_store_lowlevel($profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1977,23 +1977,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
|
||||
*/
|
||||
call_hooks('post_remote_end', $arr);
|
||||
|
||||
// update the commented timestamp on the parent - unless this is potentially a clone of an older item
|
||||
// which we don't wish to bring to the surface. As the queue only holds deliveries for 3 days, it's
|
||||
// suspected of being an older cloned item if the creation time is older than that.
|
||||
|
||||
if($arr['created'] > datetime_convert('','','now - 4 days')) {
|
||||
$z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ",
|
||||
dbesc($arr['parent_mid']),
|
||||
intval($arr['uid'])
|
||||
);
|
||||
|
||||
q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d",
|
||||
dbesc(($z) ? $z[0]['commented'] : (datetime_convert())),
|
||||
dbesc(datetime_convert()),
|
||||
intval($parent_id)
|
||||
);
|
||||
}
|
||||
|
||||
item_update_parent_commented($arr);
|
||||
|
||||
// If _creating_ a deleted item, don't propagate it further or send out notifications.
|
||||
// We need to store the item details just in case the delete came in before the original post,
|
||||
@@ -2324,6 +2308,36 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function item_update_parent_commented($item) {
|
||||
|
||||
|
||||
$update_parent = true;
|
||||
|
||||
// update the commented timestamp on the parent
|
||||
// - unless this is a moderated comment or a potential clone of an older item
|
||||
// which we don't wish to bring to the surface. As the queue only holds deliveries
|
||||
// for 3 days, it's suspected of being an older cloned item if the creation time
|
||||
//is older than that.
|
||||
|
||||
if(intval($item['item_blocked']) === ITEM_MODERATED)
|
||||
$update_parent = false;
|
||||
|
||||
if($item['created'] < datetime_convert('','','now - 4 days'))
|
||||
$update_parent = false;
|
||||
|
||||
if($update_parent) {
|
||||
$z = q("select max(created) as commented from item where parent_mid = '%s' and uid = %d and item_delayed = 0 ",
|
||||
dbesc($item['parent_mid']),
|
||||
intval($item['uid'])
|
||||
);
|
||||
|
||||
q("UPDATE item set commented = '%s', changed = '%s' WHERE id = %d",
|
||||
dbesc(($z) ? $z[0]['commented'] : datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($item['parent'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function send_status_notifications($post_id,$item) {
|
||||
@@ -2518,43 +2532,7 @@ function tag_deliver($uid, $item_id) {
|
||||
*/
|
||||
|
||||
if($item['obj_type'] === ACTIVITY_OBJ_TAGTERM) {
|
||||
|
||||
// We received a community tag activity for a post.
|
||||
// See if we are the owner of the parent item and have given permission to tag our posts.
|
||||
// If so tag the parent post.
|
||||
|
||||
logger('tag_deliver: community tag activity received');
|
||||
|
||||
if(($item['owner_xchan'] === $u[0]['channel_hash']) && (! get_pconfig($u[0]['channel_id'],'system','blocktags'))) {
|
||||
logger('tag_deliver: community tag recipient: ' . $u[0]['channel_name']);
|
||||
$j_tgt = json_decode($item['target'],true);
|
||||
if($j_tgt && $j_tgt['id']) {
|
||||
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($j_tgt['id']),
|
||||
intval($u[0]['channel_id'])
|
||||
);
|
||||
if($p) {
|
||||
$j_obj = json_decode($item['obj'],true);
|
||||
logger('tag_deliver: tag object: ' . print_r($j_obj,true), LOGGER_DATA);
|
||||
if($j_obj && $j_obj['id'] && $j_obj['title']) {
|
||||
if(is_array($j_obj['link']))
|
||||
$taglink = get_rel_link($j_obj['link'],'alternate');
|
||||
|
||||
store_item_tag($u[0]['channel_id'],$p[0]['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$j_obj['title'],$j_obj['id']);
|
||||
$x = q("update item set edited = '%s', received = '%s', changed = '%s' where mid = '%s' and uid = %d",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($j_tgt['id']),
|
||||
intval($u[0]['channel_id'])
|
||||
);
|
||||
Zotlabs\Daemon\Master::Summon(array('Notifier','edit_post',$p[0]['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
logger('Tag permission denied for ' . $u[0]['channel_address']);
|
||||
item_community_tag($u[0],$item);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2749,6 +2727,61 @@ function tag_deliver($uid, $item_id) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
function item_community_tag($channel,$item) {
|
||||
|
||||
|
||||
// We received a community tag activity for a post.
|
||||
// See if we are the owner of the parent item and have given permission to tag our posts.
|
||||
// If so tag the parent post.
|
||||
|
||||
logger('tag_deliver: community tag activity received: channel: ' . $channel['channel_name']);
|
||||
|
||||
$tag_the_post = false;
|
||||
$p = null;
|
||||
|
||||
$j_obj = json_decode($item['obj'],true);
|
||||
$j_tgt = json_decode($item['target'],true);
|
||||
if($j_tgt && $j_tgt['id']) {
|
||||
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($j_tgt['id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
if($p) {
|
||||
xchan_query($p);
|
||||
$items = fetch_post_tags($p,true);
|
||||
$pitem = $items[0];
|
||||
$auth = get_iconfig($item,'system','communitytagauth');
|
||||
if($auth) {
|
||||
if(rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['owner']['xchan_pubkey']) || rsa_verify('tagauth.' . $item['mid'],base64url_decode($auth),$pitem['author']['xchan_pubkey'])) {
|
||||
logger('tag_deliver: tagging the post: ' . $channel['channel_name']);
|
||||
$tag_the_post = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(($pitem['owner_xchan'] === $channel['channel_hash']) && (! intval(get_pconfig($channel['channel_id'],'system','blocktags')))) {
|
||||
logger('tag_deliver: community tag recipient: ' . $channel['channel_name']);
|
||||
$tag_the_post = true;
|
||||
$sig = rsa_sign('tagauth.' . $item['mid'],$channel['channel_prvkey']);
|
||||
logger('tag_deliver: setting iconfig for ' . $item['id']);
|
||||
set_iconfig($item['id'],'system','communitytagauth',base64url_encode($sig),1);
|
||||
}
|
||||
}
|
||||
|
||||
if($tag_the_post) {
|
||||
store_item_tag($channel['channel_id'],$pitem['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$j_obj['title'],$j_obj['id']);
|
||||
}
|
||||
else {
|
||||
logger('Tag permission denied for ' . $channel['channel_address']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called pre-deliver to see if a post matches the criteria to be tag delivered.
|
||||
*
|
||||
@@ -3471,11 +3504,14 @@ function item_getfeedattach($item) {
|
||||
}
|
||||
|
||||
|
||||
function item_expire($uid,$days) {
|
||||
function item_expire($uid,$days,$comment_days = 7) {
|
||||
|
||||
if((! $uid) || ($days < 1))
|
||||
return;
|
||||
|
||||
if(! $comment_days)
|
||||
$comment_days = 7;
|
||||
|
||||
// $expire_network_only = save your own wall posts
|
||||
// and just expire conversations started by others
|
||||
// do not enable this until we can pass bulk delete messages through zot
|
||||
@@ -3494,6 +3530,7 @@ function item_expire($uid,$days) {
|
||||
$r = q("SELECT id FROM item
|
||||
WHERE uid = %d
|
||||
AND created < %s - INTERVAL %s
|
||||
AND commented < %s - INTERVAL %s
|
||||
AND item_retained = 0
|
||||
AND item_thread_top = 1
|
||||
AND resource_type = ''
|
||||
@@ -3501,7 +3538,9 @@ function item_expire($uid,$days) {
|
||||
$sql_extra $item_normal LIMIT $expire_limit ",
|
||||
intval($uid),
|
||||
db_utcnow(),
|
||||
db_quoteinterval(intval($days).' DAY')
|
||||
db_quoteinterval(intval($days) . ' DAY'),
|
||||
db_utcnow(),
|
||||
db_quoteinterval(intval($comment_days) . ' DAY')
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
|
||||
@@ -176,7 +176,7 @@ EOT;
|
||||
$nav['help'] = [$help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help];
|
||||
}
|
||||
|
||||
$nav['search'] = ['search', t('Search'), "", t('Search site @name, #tag, ?docs, content')];
|
||||
$nav['search'] = ['search', t('Search'), "", t('Search site @name, !forum, #tag, ?docs, content')];
|
||||
|
||||
|
||||
/**
|
||||
@@ -287,7 +287,7 @@ EOT;
|
||||
'$is_owner' => $is_owner,
|
||||
'$sel' => App::$nav_sel,
|
||||
'$powered_by' => $powered_by,
|
||||
'$help' => t('@name, #tag, ?doc, content'),
|
||||
'$help' => t('@name, !forum, #tag, ?doc, content'),
|
||||
'$pleasewait' => t('Please wait...'),
|
||||
'$nav_apps' => $nav_apps,
|
||||
'$navbar_apps' => $navbar_apps,
|
||||
|
||||
@@ -368,27 +368,6 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
|
||||
return($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Like z_post_url() but with an application/json HTTP header.
|
||||
*
|
||||
* Add a "Content-Type: application/json" HTTP-header to $opts and call z_post_url().
|
||||
*
|
||||
* @see z_post_url()
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $params
|
||||
* @param number $redirects default 0
|
||||
* @param array $opts (optional) curl options
|
||||
* @return z_post_url()
|
||||
*/
|
||||
function z_post_url_json($url, $params, $redirects = 0, $opts = array()) {
|
||||
|
||||
$opts = array_merge($opts, array('headers' => array('Content-Type: application/json')));
|
||||
|
||||
return z_post_url($url,json_encode($params),$redirects,$opts);
|
||||
}
|
||||
|
||||
|
||||
function json_return_and_die($x, $content_type = 'application/json') {
|
||||
header("Content-type: $content_type");
|
||||
echo json_encode($x);
|
||||
@@ -669,6 +648,7 @@ function parse_xml_string($s, $strict = true) {
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
|
||||
$x = @simplexml_load_string($s2);
|
||||
if($x === false) {
|
||||
logger('libxml: parse: error: ' . $s2, LOGGER_DATA);
|
||||
@@ -682,6 +662,16 @@ function parse_xml_string($s, $strict = true) {
|
||||
return $x;
|
||||
}
|
||||
|
||||
|
||||
function sxml2array ( $xmlObject, $out = array () )
|
||||
{
|
||||
foreach ( (array) $xmlObject as $index => $node )
|
||||
$out[$index] = ( is_object ( $node ) ) ? sxml2array ( $node ) : $node;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Scales an external image.
|
||||
*
|
||||
@@ -779,7 +769,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
|
||||
* @brief xml2array() will convert the given XML text to an array in the XML structure.
|
||||
*
|
||||
* Link: http://www.bin-co.com/php/scripts/xml2array/
|
||||
* Portions significantly re-written by mike@macgirvin.com for Friendica
|
||||
* Portions significantly re-written by mike@macgirvin.com
|
||||
* (namespaces, lowercase tags, get_attribute default changed, more...)
|
||||
*
|
||||
* Examples: $array = xml2array(file_get_contents('feed.xml'));
|
||||
@@ -1160,8 +1150,6 @@ function discover_by_webbie($webbie, $protocol = '') {
|
||||
|
||||
$network = null;
|
||||
|
||||
// $webbie = strtolower($webbie);
|
||||
|
||||
$x = webfinger_rfc7033($webbie, true);
|
||||
if($x && array_key_exists('links',$x) && $x['links']) {
|
||||
foreach($x['links'] as $link) {
|
||||
@@ -1192,9 +1180,10 @@ function discover_by_webbie($webbie, $protocol = '') {
|
||||
logger('webfinger: ' . print_r($x,true), LOGGER_DATA, LOG_INFO);
|
||||
|
||||
$arr = [
|
||||
'address' => $webbie,
|
||||
'protocol' => $protocol,
|
||||
'success' => false,
|
||||
'address' => $webbie,
|
||||
'protocol' => $protocol,
|
||||
'success' => false,
|
||||
'xchan' => '',
|
||||
'webfinger' => $x
|
||||
];
|
||||
/**
|
||||
@@ -1207,7 +1196,7 @@ function discover_by_webbie($webbie, $protocol = '') {
|
||||
*/
|
||||
call_hooks('discover_channel_webfinger', $arr);
|
||||
if($arr['success'])
|
||||
return true;
|
||||
return $arr['xchan'];
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1240,16 +1229,9 @@ function webfinger_rfc7033($webbie, $zot = false) {
|
||||
}
|
||||
logger('fetching url from resource: ' . $rhs . ':' . $webbie);
|
||||
|
||||
// The default curl Accept: header is */*, which is incorrectly handled by Mastodon servers
|
||||
// and results in a 406 (Not Acceptable) response, and will also incorrectly produce an XML
|
||||
// document if you use 'application/jrd+json, */*'. We could set this to application/jrd+json,
|
||||
// but some test webfinger servers may not explicitly set the content type and they would be
|
||||
// blocked. The best compromise until Mastodon is fixed is to remove the Accept header which is
|
||||
// accomplished by setting it to nothing.
|
||||
|
||||
$counter = 0;
|
||||
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''),
|
||||
false, $counter, [ 'headers' => [ 'Accept:' ] ]);
|
||||
false, $counter, [ 'headers' => [ 'Accept: application/jrd+json, */*' ] ]);
|
||||
|
||||
if($s['success']) {
|
||||
$j = json_decode($s['body'], true);
|
||||
@@ -1607,6 +1589,7 @@ function get_site_info() {
|
||||
'register_policy' => $register_policy[get_config('system','register_policy')],
|
||||
'invitation_only' => (bool) intval(get_config('system','invitation_only')),
|
||||
'directory_mode' => $directory_mode[get_config('system','directory_mode')],
|
||||
'directory_server' => get_config('system','directory_server'),
|
||||
'language' => get_config('system','language'),
|
||||
'rss_connections' => (bool) intval(get_config('system','feed_contacts')),
|
||||
'expiration' => $site_expire,
|
||||
@@ -1844,7 +1827,8 @@ function z_mail($params) {
|
||||
$messageHeader =
|
||||
$params['additionalMailHeader'] .
|
||||
"From: $fromName <{$params['fromEmail']}>\n" .
|
||||
"Reply-To: $fromName <{$params['replyTo']}>";
|
||||
"Reply-To: $fromName <{$params['replyTo']}>\n" .
|
||||
"Content-Type: text/plain; charset=UTF-8";
|
||||
|
||||
// send the message
|
||||
$res = mail(
|
||||
|
||||
@@ -32,6 +32,7 @@ function oembed_action($embedurl) {
|
||||
$action = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
if(strpos($embedurl,'.well-known') !== false)
|
||||
$action = 'block';
|
||||
|
||||
@@ -233,9 +234,11 @@ function oembed_fetch_url($embedurl){
|
||||
|
||||
if(preg_match('#\<iframe(.*?)src\=[\'\"](.*?)[\'\"]#',$j['html'],$matches)) {
|
||||
$x = z_fetch_url($matches[2]);
|
||||
$j['html'] = $x['body'];
|
||||
$orig = $j['html'] = $x['body'];
|
||||
}
|
||||
|
||||
|
||||
logger('frame src: ' . $j['html'], LOGGER_DATA);
|
||||
|
||||
$j['html'] = purify_html($j['html'],$allow_position);
|
||||
if($j['html'] != $orig) {
|
||||
logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j['html'], LOGGER_DEBUG, LOG_INFO);
|
||||
|
||||
@@ -46,7 +46,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
|
||||
|
||||
// First find out what the channel owner declared permissions to be.
|
||||
|
||||
$channel_perm = \Zotlabs\Access\PermissionLimits::Get($uid,$perm_name);
|
||||
$channel_perm = intval(\Zotlabs\Access\PermissionLimits::Get($uid,$perm_name));
|
||||
|
||||
if(! $channel_checked) {
|
||||
$r = q("select * from channel where channel_id = %d limit 1",
|
||||
|
||||
@@ -75,6 +75,7 @@ abstract class photo_driver {
|
||||
|
||||
abstract function imageString();
|
||||
|
||||
abstract function clearexif();
|
||||
|
||||
public function __construct($data, $type='') {
|
||||
$this->types = $this->supportedTypes();
|
||||
@@ -273,7 +274,7 @@ abstract class photo_driver {
|
||||
}
|
||||
|
||||
if($f) {
|
||||
return @exif_read_data($f);
|
||||
return @exif_read_data($f,null,true);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -289,12 +290,12 @@ abstract class photo_driver {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ort = $exif['IFD0']['Orientation'];
|
||||
$ort = ((array_key_exists('IFD0',$exif)) ? $exif['IFD0']['Orientation'] : $exif['Orientation']);
|
||||
|
||||
if(! $ort) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
switch($ort) {
|
||||
case 1: // nothing
|
||||
break;
|
||||
|
||||
@@ -35,6 +35,11 @@ class photo_gd extends photo_driver {
|
||||
}
|
||||
|
||||
|
||||
public function clearexif() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public function destroy() {
|
||||
if($this->is_valid()) {
|
||||
imagedestroy($this->image);
|
||||
|
||||
@@ -96,6 +96,19 @@ class photo_imagick extends photo_driver {
|
||||
}
|
||||
|
||||
|
||||
public function clearexif() {
|
||||
|
||||
$profiles = $this->image->getImageProfiles("icc", true);
|
||||
|
||||
$this->image->stripImage();
|
||||
|
||||
if(!empty($profiles)) {
|
||||
$this->image->profileImage("icc", $profiles['icc']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getImage() {
|
||||
if(!$this->is_valid())
|
||||
return FALSE;
|
||||
|
||||
@@ -211,6 +211,10 @@ function photo_upload($channel, $observer, $args) {
|
||||
$ph->orient($exif);
|
||||
}
|
||||
|
||||
|
||||
$ph->clearexif();
|
||||
|
||||
|
||||
@unlink($src);
|
||||
|
||||
$max_length = get_config('system','max_image_length');
|
||||
@@ -333,10 +337,17 @@ function photo_upload($channel, $observer, $args) {
|
||||
|
||||
$lat = $lon = null;
|
||||
|
||||
if($exif && $exif['GPS']) {
|
||||
if(feature_enabled($channel_id,'photo_location')) {
|
||||
$lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
|
||||
$lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
|
||||
if($exif && feature_enabled($channel_id,'photo_location')) {
|
||||
$gps = null;
|
||||
if(array_key_exists('GPS',$exif)) {
|
||||
$gps = $exif['GPS'];
|
||||
}
|
||||
elseif(array_key_exists('GPSLatitude',$exif)) {
|
||||
$gps = $exif;
|
||||
}
|
||||
if($gps) {
|
||||
$lat = getGps($gps['GPSLatitude'], $gps['GPSLatitudeRef']);
|
||||
$lon = getGps($gps['GPSLongitude'], $gps['GPSLongitudeRef']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,27 @@
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle errors in plugin calls
|
||||
*
|
||||
* @param string $plugin name of the addon
|
||||
* @param string $error_text text of error
|
||||
* @param bool $uninstall uninstall plugin
|
||||
*/
|
||||
function handleerrors_plugin($plugin,$notice,$log,$uninstall=false){
|
||||
logger("Addons: [" . $plugin . "] Error: ".$log, LOGGER_ERROR);
|
||||
if ($notice != '') {
|
||||
notice("[" . $plugin . "] Error: ".$notice, LOGGER_ERROR);
|
||||
}
|
||||
|
||||
if ($uninstall) {
|
||||
$idx = array_search($plugin, \App::$plugins);
|
||||
unset(\App::$plugins[$idx]);
|
||||
uninstall_plugin($plugin);
|
||||
set_config("system","addon", implode(", ",\App::$plugins));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unloads an addon.
|
||||
*
|
||||
@@ -17,7 +38,11 @@ function unload_plugin($plugin){
|
||||
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
|
||||
if(function_exists($plugin . '_unload')) {
|
||||
$func = $plugin . '_unload';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"Unable to unload.",$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +63,11 @@ function uninstall_plugin($plugin) {
|
||||
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
|
||||
if(function_exists($plugin . '_uninstall')) {
|
||||
$func = $plugin . '_uninstall';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"Unable to uninstall.","Unable to run _uninstall : ".$e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
q("DELETE FROM addon WHERE aname = '%s' ",
|
||||
@@ -64,7 +93,12 @@ function install_plugin($plugin) {
|
||||
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
|
||||
if(function_exists($plugin . '_install')) {
|
||||
$func = $plugin . '_install';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"Install failed.","Install failed : ".$e->getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$plugin_admin = (function_exists($plugin . '_plugin_admin') ? 1 : 0);
|
||||
@@ -94,7 +128,12 @@ function load_plugin($plugin) {
|
||||
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
|
||||
if(function_exists($plugin . '_load')) {
|
||||
$func = $plugin . '_load';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"Unable to load.","FAILED loading : ".$e->getMessage(),true);
|
||||
return;
|
||||
}
|
||||
|
||||
// we can add the following with the previous SQL
|
||||
// once most site tables have been updated.
|
||||
@@ -108,7 +147,7 @@ function load_plugin($plugin) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
logger("Addons: FAILED loading " . $plugin);
|
||||
logger("Addons: FAILED loading " . $plugin . " (missing _load function)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -160,11 +199,21 @@ function reload_plugins() {
|
||||
|
||||
if(function_exists($pl . '_unload')) {
|
||||
$func = $pl . '_unload';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"","UNLOAD FAILED (uninstalling) : ".$e->getMessage(),true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(function_exists($pl . '_load')) {
|
||||
$func = $pl . '_load';
|
||||
$func();
|
||||
try {
|
||||
$func();
|
||||
} catch (Exception $e) {
|
||||
handleerrors_plugin($plugin,"","LOAD FAILED (uninstalling): ".$e->getMessage(),true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
q("UPDATE addon SET tstamp = %d WHERE id = %d",
|
||||
intval($t),
|
||||
|
||||
@@ -95,6 +95,12 @@ function queue_set_delivered($id,$channel = 0) {
|
||||
|
||||
function queue_insert($arr) {
|
||||
|
||||
// do not queue anything with no destination
|
||||
|
||||
if(! (array_key_exists('posturl',$arr) && trim($arr['posturl']))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
|
||||
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
|
||||
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
|
||||
|
||||
@@ -266,6 +266,15 @@ function change_channel($change_channel) {
|
||||
$_SESSION['mobile_theme'] = get_pconfig(local_channel(),'system', 'mobile_theme');
|
||||
$_SESSION['cloud_tiles'] = get_pconfig(local_channel(),'system', 'cloud_tiles');
|
||||
date_default_timezone_set($r[0]['channel_timezone']);
|
||||
|
||||
// Update the active timestamp at most once a day
|
||||
|
||||
if(substr($r[0]['channel_active'],0,10) !== substr(datetime_convert(),0,10)) {
|
||||
$z = q("UPDATE channel SET channel_active = '%s' WHERE channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['channel_id'])
|
||||
);
|
||||
}
|
||||
$ret = $r[0];
|
||||
}
|
||||
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
|
||||
@@ -17,23 +17,10 @@ function update_channels_active_halfyear_stat() {
|
||||
db_utcnow(), db_quoteinterval('6 MONTH')
|
||||
);
|
||||
if($r) {
|
||||
$s = '';
|
||||
foreach($r as $rr) {
|
||||
if($s)
|
||||
$s .= ',';
|
||||
$s .= intval($rr['channel_id']);
|
||||
}
|
||||
$x = q("select uid from item where uid in ( $s ) and item_wall = 1 and created > %s - INTERVAL %s group by uid",
|
||||
db_utcnow(), db_quoteinterval('6 MONTH')
|
||||
);
|
||||
if($x) {
|
||||
$channels_active_halfyear_stat = count($x);
|
||||
set_config('system','channels_active_halfyear_stat',$channels_active_halfyear_stat);
|
||||
} else {
|
||||
set_config('system','channels_active_halfyear_stat',0);
|
||||
}
|
||||
} else {
|
||||
set_config('system','channels_active_halfyear_stat',0);
|
||||
set_config('system','channels_active_halfyear_stat',count($r));
|
||||
}
|
||||
else {
|
||||
set_config('system','channels_active_halfyear_stat','0');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,28 +30,15 @@ function update_channels_active_monthly_stat() {
|
||||
db_utcnow(), db_quoteinterval('1 MONTH')
|
||||
);
|
||||
if($r) {
|
||||
$s = '';
|
||||
foreach($r as $rr) {
|
||||
if($s)
|
||||
$s .= ',';
|
||||
$s .= intval($rr['channel_id']);
|
||||
}
|
||||
$x = q("select uid from item where uid in ( $s ) and item_wall = 1 and created > %s - INTERVAL %s group by uid",
|
||||
db_utcnow(), db_quoteinterval('1 MONTH')
|
||||
);
|
||||
if($x) {
|
||||
$channels_active_monthly_stat = count($x);
|
||||
set_config('system','channels_active_monthly_stat',$channels_active_monthly_stat);
|
||||
} else {
|
||||
set_config('system','channels_active_monthly_stat',0);
|
||||
}
|
||||
} else {
|
||||
set_config('system','channels_active_monthly_stat',0);
|
||||
set_config('system','channels_active_monthly_stat',count($r));
|
||||
}
|
||||
else {
|
||||
set_config('system','channels_active_monthly_stat','0');
|
||||
}
|
||||
}
|
||||
|
||||
function update_local_posts_stat() {
|
||||
$posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 ");
|
||||
$posts = q("SELECT COUNT(*) AS local_posts FROM item WHERE item_wall = 1 and id = parent");
|
||||
if (is_array($posts)) {
|
||||
$local_posts_stat = intval($posts[0]["local_posts"]);
|
||||
set_config('system','local_posts_stat',$local_posts_stat);
|
||||
|
||||
@@ -174,8 +174,7 @@ function tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0, $re
|
||||
if(! is_array($authors))
|
||||
$authors = array($authors);
|
||||
|
||||
stringify_array_elms($authors,true);
|
||||
$sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
|
||||
$sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") ";
|
||||
}
|
||||
|
||||
if($owner) {
|
||||
@@ -212,8 +211,9 @@ function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0
|
||||
if(! perm_is_allowed($uid,get_observer_hash(),'view_pages'))
|
||||
return array();
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' ";
|
||||
|
||||
$item_normal = item_normal();
|
||||
$sql_options = item_permissions_sql($uid);
|
||||
$count = intval($count);
|
||||
|
||||
@@ -226,8 +226,7 @@ function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0
|
||||
if(! is_array($authors))
|
||||
$authors = array($authors);
|
||||
|
||||
stringify_array_elms($authors,true);
|
||||
$sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
|
||||
$sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") ";
|
||||
}
|
||||
|
||||
if($owner) {
|
||||
@@ -236,15 +235,16 @@ function card_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags = 0
|
||||
|
||||
|
||||
// Fetch tags
|
||||
|
||||
$r = q("select term, count(term) as total from term left join item on term.oid = item.id
|
||||
where term.uid = %d and term.ttype = %d
|
||||
and otype = %d and item_type = %d and item_private = 0
|
||||
and otype = %d and item_type = %d
|
||||
$sql_options $item_normal
|
||||
group by term order by total desc %s",
|
||||
intval($uid),
|
||||
intval($type),
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($restrict),
|
||||
intval(ITEM_TYPE_CARD),
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
|
||||
@@ -263,7 +263,9 @@ function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags
|
||||
return array();
|
||||
|
||||
|
||||
$item_normal = item_normal();
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_deleted = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 and item.obj_type != 'http://purl.org/zot/activity/file' ";
|
||||
|
||||
$sql_options = item_permissions_sql($uid);
|
||||
$count = intval($count);
|
||||
|
||||
@@ -276,8 +278,7 @@ function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags
|
||||
if(! is_array($authors))
|
||||
$authors = array($authors);
|
||||
|
||||
stringify_array_elms($authors,true);
|
||||
$sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
|
||||
$sql_options .= " and author_xchan in (" . stringify_array($authors,true) . ") ";
|
||||
}
|
||||
|
||||
if($owner) {
|
||||
@@ -288,13 +289,13 @@ function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags
|
||||
// Fetch tags
|
||||
$r = q("select term, count(term) as total from term left join item on term.oid = item.id
|
||||
where term.uid = %d and term.ttype = %d
|
||||
and otype = %d and item_type = %d and item_private = 0
|
||||
and otype = %d and item_type = %d
|
||||
$sql_options $item_normal
|
||||
group by term order by total desc %s",
|
||||
intval($uid),
|
||||
intval($type),
|
||||
intval(TERM_OBJ_POST),
|
||||
intval($restrict),
|
||||
intval(ITEM_TYPE_ARTICLE),
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
|
||||
@@ -308,6 +309,70 @@ function article_tagadelic($uid, $count = 0, $authors = '', $owner = '', $flags
|
||||
|
||||
|
||||
|
||||
function pubtagblock($net,$site,$limit,$recent = 0,$safemode = 1, $type = TERM_HASHTAG) {
|
||||
$o = '';
|
||||
|
||||
$r = pub_tagadelic($net,$site,$limit,$recent,$safemode,$type);
|
||||
|
||||
$link = z_root() . '/pubstream';
|
||||
|
||||
if($r) {
|
||||
$o = '<div class="tagblock widget"><h3>' . (($recent) ? t('Trending') : t('Tags')) . '</h3><div class="tags" align="center">';
|
||||
foreach($r as $rr) {
|
||||
$o .= '<span class="tag'.$rr[2].'">#</span><a href="'.$link .'/' . '?f=&tag=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ' . "\r\n";
|
||||
}
|
||||
$o .= '</div></div>';
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function pub_tagadelic($net,$site,$limit,$recent,$safemode,$type) {
|
||||
|
||||
|
||||
$item_normal = item_normal();
|
||||
$count = intval($limit);
|
||||
|
||||
if($site) {
|
||||
$uids = " and item.uid in ( " . stream_perms_api_uids(PERMS_PUBLIC) . " ) and item_private = 0 and item_wall = 1 ";
|
||||
}
|
||||
else {
|
||||
$sys = get_sys_channel();
|
||||
$uids = " and item.uid = " . intval($sys['channel_id']) . " ";
|
||||
$sql_extra = " and item_private = 0 ";
|
||||
}
|
||||
|
||||
if($recent)
|
||||
$sql_extra .= " and item.created > '" . datetime_convert('UTC','UTC', 'now - ' . intval($recent) . ' days ') . "' ";
|
||||
|
||||
|
||||
if($safemode) {
|
||||
$unsafetags = get_config('system','unsafepubtags', [ 'boobs', 'bot', 'rss', 'girl','girls', 'nsfw', 'sexy', 'nude' ]);
|
||||
if($unsafetags) {
|
||||
$sql_extra .= " and not term.term in ( " . stringify_array($unsafetags,true) . ") ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fetch tags
|
||||
$r = q("select term, count(term) as total from term left join item on term.oid = item.id
|
||||
where term.ttype = %d
|
||||
and otype = %d and item_type = %d
|
||||
$sql_extra $uids $item_normal
|
||||
group by term order by total desc %s",
|
||||
intval($type),
|
||||
intval(TERM_OBJ_POST),
|
||||
intval(ITEM_TYPE_POST),
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
|
||||
if(! $r)
|
||||
return array();
|
||||
|
||||
return Zotlabs\Text\Tagadelic::calc($r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function dir_tagadelic($count = 0, $hub = '') {
|
||||
|
||||
@@ -553,9 +618,8 @@ function get_things($profile_hash,$uid) {
|
||||
if(! in_array($rr['obj_obj'],$profile_hashes))
|
||||
$profile_hashes[] = $rr['obj_obj'];
|
||||
}
|
||||
stringify_array_elms($profile_hashes);
|
||||
if(! $profile_hash) {
|
||||
$exp = explode(',',$profile_hashes);
|
||||
$exp = stringify_array($profile_hashes,true);
|
||||
$p = q("select profile_guid as hash, profile_name as name from profile where profile_guid in ( $exp ) ");
|
||||
if($p) {
|
||||
foreach($r as $rr) {
|
||||
|
||||
@@ -531,7 +531,7 @@ function paginate(&$a) {
|
||||
}
|
||||
|
||||
|
||||
function alt_pager(&$a, $i, $more = '', $less = '') {
|
||||
function alt_pager($i, $more = '', $less = '') {
|
||||
|
||||
if(! $more)
|
||||
$more = t('older');
|
||||
@@ -1588,7 +1588,7 @@ function generate_named_map($location) {
|
||||
}
|
||||
|
||||
|
||||
function prepare_body(&$item,$attach = false) {
|
||||
function prepare_body(&$item,$attach = false,$opts = false) {
|
||||
|
||||
call_hooks('prepare_body_init', $item);
|
||||
|
||||
@@ -1616,7 +1616,7 @@ function prepare_body(&$item,$attach = false) {
|
||||
$s .= prepare_binary($item);
|
||||
}
|
||||
else {
|
||||
$s .= prepare_text($item['body'],$item['mimetype'], false);
|
||||
$s .= prepare_text($item['body'],$item['mimetype'], $opts);
|
||||
}
|
||||
|
||||
$event = (($item['obj_type'] === ACTIVITY_OBJ_EVENT) ? format_event_obj($item['obj']) : false);
|
||||
@@ -1698,7 +1698,8 @@ function prepare_binary($item) {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
|
||||
function prepare_text($text, $content_type = 'text/bbcode', $opts = false) {
|
||||
|
||||
|
||||
switch($content_type) {
|
||||
case 'text/plain':
|
||||
@@ -1742,7 +1743,7 @@ function prepare_text($text, $content_type = 'text/bbcode', $cache = false) {
|
||||
if(stristr($text,'[nosmile]'))
|
||||
$s = bbcode($text, [ 'cache' => $cache ]);
|
||||
else
|
||||
$s = smilies(bbcode($text, [ 'cache' => $cache ]));
|
||||
$s = smilies(bbcode($text, ((is_array($opts)) ? $opts : [] )));
|
||||
|
||||
$s = zidify_links($s);
|
||||
|
||||
@@ -2189,13 +2190,13 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
|
||||
* @returns string
|
||||
*/
|
||||
|
||||
function array_elm_to_str($arr,$elm,$delim = ',') {
|
||||
function array_elm_to_str($arr,$elm,$delim = ',',$each = 'trim') {
|
||||
|
||||
$tmp = [];
|
||||
if($arr && is_array($arr)) {
|
||||
foreach($arr as $x) {
|
||||
if(is_array($x) && array_key_exists($elm,$x)) {
|
||||
$z = trim($x[$elm]);
|
||||
$z = $each($x[$elm]);
|
||||
if(($z) && (! in_array($z,$tmp))) {
|
||||
$tmp[] = $z;
|
||||
}
|
||||
@@ -2205,7 +2206,9 @@ function array_elm_to_str($arr,$elm,$delim = ',') {
|
||||
return implode($delim,$tmp);
|
||||
}
|
||||
|
||||
|
||||
function trim_and_unpunify($s) {
|
||||
return unpunify(trim($s));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -2248,7 +2251,7 @@ function xchan_query(&$items, $abook = true, $effective_uid = 0) {
|
||||
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
|
||||
where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1");
|
||||
}
|
||||
$xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown')");
|
||||
$xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown', 'anon')");
|
||||
if(! $chans)
|
||||
$chans = $xchans;
|
||||
else
|
||||
@@ -2321,6 +2324,23 @@ function stringify_array_elms(&$arr, $escape = false) {
|
||||
$arr[$x] = "'" . (($escape) ? dbesc($arr[$x]) : $arr[$x]) . "'";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Similar to stringify_array_elms but returns a string. If $escape is true, dbesc() each element before adding quotes.
|
||||
*
|
||||
* @param array $arr
|
||||
* @param boolean $escape (optional) default false
|
||||
* @return string
|
||||
*/
|
||||
function stringify_array($arr, $escape = false) {
|
||||
if($arr) {
|
||||
stringify_array_elms($arr);
|
||||
return(implode(',',$arr));
|
||||
}
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Indents a flat JSON string to make it more human-readable.
|
||||
*
|
||||
@@ -2384,7 +2404,7 @@ function jindent($json) {
|
||||
*/
|
||||
function design_tools() {
|
||||
|
||||
$channel = App::get_channel();
|
||||
$channel = channelx_by_n(App::$profile['profile_uid']);
|
||||
$sys = false;
|
||||
|
||||
if(App::$is_sys && is_site_admin()) {
|
||||
@@ -2574,6 +2594,9 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
|
||||
|
||||
// The @! tag will alter permissions
|
||||
$exclusive = (((! $grouptag) && (strpos($tag,'!') === 1) && (! $diaspora)) ? true : false);
|
||||
if(($grouptag) && (strpos($tag,'!!') === 0)) {
|
||||
$exclusive = true;
|
||||
}
|
||||
|
||||
//is it already replaced?
|
||||
if(strpos($tag,'[zrl='))
|
||||
@@ -2746,8 +2769,8 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
|
||||
$profile = str_replace(',','%2c',$profile);
|
||||
$url = $profile;
|
||||
if($grouptag) {
|
||||
$newtag = '!' . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
||||
$body = str_replace('!' . $name, $newtag, $body);
|
||||
$newtag = '!' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
|
||||
$body = str_replace('!' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
|
||||
}
|
||||
else {
|
||||
$newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . (($forum && ! $trailing_plus_name) ? '+' : '') . '[/zrl]';
|
||||
@@ -2797,6 +2820,7 @@ function linkify_tags($a, &$body, $uid, $diaspora = false) {
|
||||
continue;
|
||||
|
||||
$success = handle_tag($a, $body, $access_tag, $str_tags, ($uid) ? $uid : App::$profile_uid , $tag, $diaspora);
|
||||
|
||||
$results[] = array('success' => $success, 'access_tag' => $access_tag);
|
||||
if($success['replaced']) $tagged[] = $tag;
|
||||
}
|
||||
@@ -3243,6 +3267,7 @@ function cleanup_bbcode($body) {
|
||||
* First protect any url inside certain bbcode tags so we don't double link it.
|
||||
*/
|
||||
|
||||
|
||||
$body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
|
||||
$body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
|
||||
@@ -3272,7 +3297,6 @@ function cleanup_bbcode($body) {
|
||||
|
||||
$body = scale_external_images($body,false);
|
||||
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
@@ -3311,4 +3335,26 @@ function purify_filename($s) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
// callback for sorting the settings/featured entries.
|
||||
|
||||
function featured_sort($a,$b) {
|
||||
$s1 = substr($a,strpos($a,'id='),20);
|
||||
$s2 = substr($b,strpos($b,'id='),20);
|
||||
return(strcmp($s1,$s2));
|
||||
}
|
||||
|
||||
|
||||
function punify($s) {
|
||||
require_once('vendor/simplepie/simplepie/idn/idna_convert.class.php');
|
||||
$x = new idna_convert(['encoding' => 'utf8']);
|
||||
return $x->encode($s);
|
||||
|
||||
}
|
||||
|
||||
function unpunify($s) {
|
||||
require_once('vendor/simplepie/simplepie/idn/idna_convert.class.php');
|
||||
$x = new idna_convert(['encoding' => 'utf8']);
|
||||
return $x->decode($s);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -53,14 +53,14 @@ function zid($s, $address = '') {
|
||||
$mine = get_my_url();
|
||||
$myaddr = (($address) ? $address : get_my_address());
|
||||
|
||||
/**
|
||||
* @FIXME checking against our own channel url is no longer reliable. We may have a lot
|
||||
* of urls attached to our channel. Should probably match against our site, since we
|
||||
* will not need to remote authenticate on our own site anyway.
|
||||
*/
|
||||
$mine_parsed = parse_url($mine);
|
||||
$s_parsed = parse_url($s);
|
||||
|
||||
if ($mine && $myaddr && (! link_compare($mine,$s)))
|
||||
$zurl = $s . (($num_slashes >= 3) ? '' : '/') . $achar . 'zid=' . urlencode($myaddr);
|
||||
if($mine_parsed['host'] === $s_parsed['host'])
|
||||
$url_match = true;
|
||||
|
||||
if ($mine && $myaddr && (! $url_match))
|
||||
$zurl = $s . (($num_slashes >= 3) ? '' : '/') . (($achar === '?') ? '?f=&' : '&') . 'zid=' . urlencode($myaddr);
|
||||
else
|
||||
$zurl = $s;
|
||||
|
||||
@@ -103,12 +103,17 @@ function strip_zats($s) {
|
||||
return preg_replace('/[\?&]zat=(.*?)(&|$)/ism','$2',$s);
|
||||
}
|
||||
|
||||
function strip_escaped_zids($s) {
|
||||
$x = preg_replace('/&\;zid=(.*?)(&|$)/ism','$2',$s);
|
||||
return strip_query_param($x,'f');
|
||||
}
|
||||
|
||||
|
||||
function clean_query_string($s = '') {
|
||||
$x = strip_zids(($s) ? $s : \App::$query_string);
|
||||
$x = strip_owt($x);
|
||||
$x = strip_zats($x);
|
||||
$x = strip_query_param($x,'sort');
|
||||
|
||||
return strip_query_param($x,'f');
|
||||
}
|
||||
@@ -346,4 +351,4 @@ function owt_init($token) {
|
||||
info(sprintf( t('OpenWebAuth: %1$s welcomes %2$s'),\App::get_hostname(), $hubloc['xchan_name']));
|
||||
|
||||
logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,8 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
|
||||
* packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check'
|
||||
* @param array $recipients
|
||||
* envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts
|
||||
* @param string msg
|
||||
* optional message
|
||||
* @param string $remote_key
|
||||
* optional public site key of target hub used to encrypt entire packet
|
||||
* NOTE: remote_key and encrypted packets are required for 'auth_check' packets, optional for all others
|
||||
@@ -299,7 +301,7 @@ function zot_zot($url, $data, $channel = null,$crypto = null) {
|
||||
if($channel) {
|
||||
$headers['X-Zot-Token'] = random_string();
|
||||
$hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false);
|
||||
$headers['X-Zot-Digest'] = 'SHA-256=' . $hash;
|
||||
$headers['X-Zot-Digest'] = 'SHA-256=' . $hash;
|
||||
$h = \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,false,'sha512',(($crypto) ? $crypto['hubloc_sitekey'] : ''), (($crypto) ? zot_best_algorithm($crypto['site_crypto']) : ''));
|
||||
}
|
||||
|
||||
@@ -393,7 +395,7 @@ function zot_refresh($them, $channel = null, $force = false) {
|
||||
if($s && intval($s[0]['site_dead']) && (! $force)) {
|
||||
logger('zot_refresh: site ' . $url . ' is marked dead and force flag is not set. Cancelling operation.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$token = random_string();
|
||||
@@ -1159,7 +1161,7 @@ function zot_process_response($hub, $arr, $outq) {
|
||||
* and also that the signer and the sender match.
|
||||
* If that happens, we do not need to fetch/pickup the message - we have it already and it is verified.
|
||||
* Translate it into the form we need for zot_import() and import it.
|
||||
*
|
||||
*
|
||||
* Otherwise send back a pickup message, using our message tracking ID ($arr['secret']), which we will sign with our site
|
||||
* private key.
|
||||
* The entire pickup message is encrypted with the remote site's public key.
|
||||
@@ -2283,13 +2285,31 @@ function process_mail_delivery($sender, $arr, $deliveries) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(! perm_is_allowed($channel['channel_id'],$sender['hash'],'post_mail')) {
|
||||
logger("permission denied for mail delivery {$channel['channel_id']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Always allow somebody to reply if you initiated the conversation. It's anti-social
|
||||
* and a bit rude to send a private message to somebody and block their ability to respond.
|
||||
* If you are being harrassed and want to put an end to it, delete the conversation.
|
||||
*/
|
||||
|
||||
$return = false;
|
||||
if($arr['parent_mid']) {
|
||||
$return = q("select * from mail where mid = '%s' and channel_id = %d limit 1",
|
||||
dbesc($arr['parent_mid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
if(! $return) {
|
||||
logger("permission denied for mail delivery {$channel['channel_id']}");
|
||||
$DR->update('permission denied');
|
||||
$result[] = $DR->get();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$r = q("select id from mail where mid = '%s' and channel_id = %d limit 1",
|
||||
dbesc($arr['mid']),
|
||||
intval($channel['channel_id'])
|
||||
@@ -3188,6 +3208,9 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
||||
|
||||
$channel = $r[0];
|
||||
|
||||
// don't provide these in the export
|
||||
|
||||
unset($channel['channel_active']);
|
||||
unset($channel['channel_password']);
|
||||
unset($channel['channel_salt']);
|
||||
|
||||
@@ -3454,6 +3477,14 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the clone is active, so are we
|
||||
|
||||
if(substr($channel['channel_active'],0,10) !== substr(datetime_convert(),0,10)) {
|
||||
q("UPDATE channel set channel_active = '%s' where channel_id = %d",
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
if(array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) {
|
||||
foreach($arr['config'] as $cat => $k) {
|
||||
@@ -3780,25 +3811,27 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
foreach($x as $y) {
|
||||
|
||||
// for each group, loop on members list we just received
|
||||
foreach($members[$y['hash']] as $member) {
|
||||
$found = false;
|
||||
$z = q("select xchan from group_member where gid = %d and uid = %d and xchan = '%s' limit 1",
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($member)
|
||||
);
|
||||
if($z)
|
||||
$found = true;
|
||||
|
||||
// if somebody is in the group that wasn't before - add them
|
||||
|
||||
if(! $found) {
|
||||
q("INSERT INTO group_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($channel['channel_id']),
|
||||
if(isset($y['hash']) && isset($members[$y['hash']])) {
|
||||
foreach($members[$y['hash']] as $member) {
|
||||
$found = false;
|
||||
$z = q("select xchan from group_member where gid = %d and uid = %d and xchan = '%s' limit 1",
|
||||
intval($y['id']),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($member)
|
||||
);
|
||||
if($z)
|
||||
$found = true;
|
||||
|
||||
// if somebody is in the group that wasn't before - add them
|
||||
|
||||
if(! $found) {
|
||||
q("INSERT INTO group_member (uid, gid, xchan)
|
||||
VALUES( %d, %d, '%s' ) ",
|
||||
intval($channel['channel_id']),
|
||||
intval($y['id']),
|
||||
dbesc($member)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3835,11 +3868,14 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if(! $x) {
|
||||
q("insert into profile ( profile_guid, aid, uid ) values ('%s', %d, %d)",
|
||||
dbesc($profile['profile_guid']),
|
||||
intval($channel['channel_account_id']),
|
||||
intval($channel['channel_id'])
|
||||
profile_store_lowlevel(
|
||||
[
|
||||
'aid' => $channel['channel_account_id'],
|
||||
'uid' => $channel['channel_id'],
|
||||
'profile_guid' => $profile['profile_guid'],
|
||||
]
|
||||
);
|
||||
|
||||
$x = q("select * from profile where profile_guid = '%s' and uid = %d limit 1",
|
||||
dbesc($profile['profile_guid']),
|
||||
intval($channel['channel_id'])
|
||||
@@ -5093,7 +5129,7 @@ function zot_reply_refresh($sender, $recipients) {
|
||||
function zot6_check_sig() {
|
||||
|
||||
$ret = [ 'success' => false ];
|
||||
|
||||
|
||||
logger('server: ' . print_r($_SERVER,true), LOGGER_DATA);
|
||||
|
||||
if(array_key_exists('HTTP_SIGNATURE',$_SERVER)) {
|
||||
|
||||
Reference in New Issue
Block a user