aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/auth.php39
-rw-r--r--include/bbcode.php4
-rw-r--r--include/event.php182
-rw-r--r--include/feedutils.php20
-rw-r--r--include/html2bbcode.php2
-rw-r--r--include/items.php76
-rw-r--r--include/language.php5
-rw-r--r--include/nav.php4
-rw-r--r--include/network.php21
-rw-r--r--include/oembed.php12
-rw-r--r--include/plugin.php117
-rw-r--r--include/text.php22
-rw-r--r--include/zid.php2
13 files changed, 343 insertions, 163 deletions
diff --git a/include/auth.php b/include/auth.php
index 8eeb077b5..07b8e2971 100644
--- a/include/auth.php
+++ b/include/auth.php
@@ -30,9 +30,9 @@ require_once('include/security.php');
* The return array is dependent on the login mechanism.
* $ret['account'] will be set if either an email or channel address validation was successful (local login).
* $ret['channel'] will be set if a channel address validation was successful.
- * $ret['xchan'] will be set if a guest access token validation was successful.
- * Keys will exist for invalid return arrays but will be set to null.
- * This function does not perform a login. It merely validates systems passwords and tokens.
+ * $ret['xchan'] will be set if a guest access token validation was successful.
+ * Keys will exist for invalid return arrays but will be set to null.
+ * This function does not perform a login. It merely validates systems passwords and tokens.
*
*/
@@ -44,7 +44,7 @@ function account_verify_password($login, $pass) {
$email_verify = get_config('system', 'verify_email');
$register_policy = get_config('system', 'register_policy');
- if(! $login)
+ if(!$login || !$pass)
return null;
$account = null;
@@ -72,7 +72,7 @@ function account_verify_password($login, $pass) {
$ret['account'] = $addon_auth['user_record'];
return $ret;
}
- else {
+ else {
if(! strpos($login,'@')) {
$channel = channelx_by_nick($login);
if(! $channel) {
@@ -102,7 +102,7 @@ function account_verify_password($login, $pass) {
$account = $a[0];
// Currently we only verify email address if there is an open registration policy.
- // This isn't because of any policy - it's because the workflow gets too complicated if
+ // This isn't because of any policy - it's because the workflow gets too complicated if
// you have to verify the email and then go through the account approval workflow before
// letting them login.
@@ -112,7 +112,7 @@ function account_verify_password($login, $pass) {
}
if($channel) {
- // Try the authentication plugin again since weve determined we are using the channel login instead of account login
+ // Try the authentication plugin again since weve determined we are using the channel login instead of account login
$addon_auth = [
'username' => $account['account_email'],
'password' => trim($pass),
@@ -128,7 +128,7 @@ function account_verify_password($login, $pass) {
}
}
- if(($account['account_flags'] == ACCOUNT_OK)
+ if(($account['account_flags'] == ACCOUNT_OK)
&& (hash('whirlpool',$account['account_salt'] . $pass) === $account['account_password'])) {
logger('password verified for ' . $login);
$ret['account'] = $account;
@@ -193,7 +193,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
$_SESSION = $_SESSION['delegate_push'];
info( t('Delegation session ended.') . EOL);
}
- else {
+ else {
App::$session->nuke();
info( t('Logged out.') . EOL);
}
@@ -280,8 +280,11 @@ else {
// handle a fresh login request
- if((x($_POST, 'password')) && strlen($_POST['password']))
- $encrypted = hash('whirlpool', trim($_POST['password']));
+ $password = $_POST['main_login_password'] ?? $_POST['modal_login_password'];
+ $username = $_POST['main_login_username'] ?? $_POST['modal_login_username'];
+
+ if($password)
+ $encrypted = hash('whirlpool', trim($password));
if((x($_POST, 'auth-params')) && $_POST['auth-params'] === 'login') {
@@ -289,10 +292,10 @@ else {
$account = null;
$channel = null;
- $verify = account_verify_password($_POST['username'], $_POST['password']);
+ $verify = account_verify_password($username, $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(punify(trim(escape_tags($_POST['username'])))));
+ goaway(z_root() . '/email_validation/' . bin2hex(punify(trim(escape_tags($username)))));
}
elseif($verify) {
$atoken = $verify['xchan'];
@@ -311,8 +314,8 @@ else {
}
if(! ($account || $atoken)) {
- $error = 'authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR'];
- logger($error);
+ $error = 'authenticate: failed login attempt: ' . notags(trim($username)) . ' from IP ' . $_SERVER['REMOTE_ADDR'];
+ logger($error);
// Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention
$authlog = get_config('system', 'authlog');
if ($authlog)
@@ -334,7 +337,9 @@ else {
// (i.e. expire when the browser is closed), even when there's a time expiration
// on the cookie
- if(($_POST['remember_me']) || ($_POST['remember'])) {
+ $remember = $_POST['main_login_remember'] ?? $_POST['modal_login_remember'];
+
+ if($remember) {
$_SESSION['remember_me'] = 1;
App::$session->new_cookie(31449600); // one year
}
@@ -360,7 +365,7 @@ else {
* and returns the corresponding channel_id.
*
* @fixme How do we prevent that an OpenID identity is used more than once?
- *
+ *
* @param string $authid
* The given openid_identity
* @return int|bool
diff --git a/include/bbcode.php b/include/bbcode.php
index 03115effe..794cb25d0 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -488,9 +488,9 @@ function getAttachmentData($body) {
$data["preview"] = html_entity_decode($preview, ENT_QUOTES, 'UTF-8');
}
- $data["description"] = trim($match[3]);
+ $data["description"] = ((isset($match[3])) ? trim($match[3]) : '');
- $data["after"] = trim($match[4]);
+ $data["after"] = ((isset($match[4])) ? trim($match[4]) : '');
return $data;
}
diff --git a/include/event.php b/include/event.php
index 440f559da..3d3dda035 100644
--- a/include/event.php
+++ b/include/event.php
@@ -70,8 +70,87 @@ function format_event_html($ev) {
}
function format_event_obj($jobject) {
+
$event = [];
+ $object = json_decode($jobject, true);
+
+/*******
+ This is our encoded format
+
+ $x = [
+ 'type' => 'Event',
+ 'id' => z_root() . '/event/' . $r[0]['resource_id'],
+ 'summary' => bbcode($arr['summary']),
+ // RFC3339 Section 4.3
+ 'startTime' => (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtstart'],'Y-m-d\\TH:i:s-00:00')),
+ 'content' => bbcode($arr['description']),
+ 'location' => [ 'type' => 'Place', 'content' => $arr['location'] ],
+ 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ],
+ 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ],
+ 'actor' => Activity::encode_person($r[0],false),
+ ];
+ if(! $arr['nofinish']) {
+ $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC','UTC',$arr['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$arr['dtend'],'Y-m-d\\TH:i:s-00:00'));
+ }
+
+******/
+
+ if (is_array($object) && (array_key_exists('summary', $object) || array_key_exists('name', $object))) {
+
+ $dtend = ((array_key_exists('endTime', $object)) ? $object['endTime'] : NULL_DATE);
+ $title = ((isset($object['summary']) && $object['summary']) ? zidify_links(smilies(bbcode($object['summary']))) : $object['name']);
+
+ // mobilizon sets a timezone in the object
+ // we will assume that events with an timezone should be adjusted
+ $tz = $object['timezone'] ?? '';
+
+ // friendica has its own flag for adjust
+ $dfrn_adjust = $object['dfrn:adjust'] ?? '';
+
+ $adjust = ((strpos($object['startTime'], 'Z') !== false) || $tz || $dfrn_adjust);
+
+ $allday = (($adjust) ? false : true);
+
+ $dtstart = new DateTime($object['startTime']);
+ $dtend_obj = new DateTime($dtend);
+
+ $dtdiff = $dtstart->diff($dtend_obj);
+
+ if($allday && ($dtdiff->days < 2))
+ $oneday = true;
+
+ if($allday && !$oneday) {
+ // Subtract one day from the end date so we can use the "first day - last day" format for display.
+ $dtend_obj->modify('-1 day');
+ $dtend = datetime_convert('UTC', 'UTC', $dtend_obj->format('Y-m-d H:i:s'));
+ }
+
+ $bd_format = (($allday) ? t('l F d, Y') : t('l F d, Y \@ g:i A')); // Friday January 18, 2011 @ 8:01 AM or Friday January 18, 2011 for allday events
+
+ $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'), array(
+ '$title' => $title,
+ '$dtstart_label' => t('Start:'),
+ '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['startTime'], ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtstart_dt' => (($adjust) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['startTime'], $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $object['startTime'], $bd_format))),
+ '$finish' => ((array_key_exists('endTime', $object)) ? true : false),
+ '$dtend_label' => t('End:'),
+ '$dtend_title' => datetime_convert('UTC', 'UTC', $dtend, ((strpos($object['startTime'], 'Z')) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
+ '$dtend_dt' => (($adjust) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $dtend, $bd_format)) : day_translate(datetime_convert('UTC', 'UTC', $dtend, $bd_format))),
+ '$allday' => $allday,
+ '$oneday' => $oneday,
+ '$event_tz' => ['label' => t('Timezone'), 'value' => (($tz === date_default_timezone_get()) ? '' : $tz)]
+ ));
+ $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'), array(
+ '$description' => $object['content'],
+ '$location_label' => t('Location:'),
+ '$location' => ((array_path_exists('location/name', $object)) ? zidify_links(smilies(bbcode($object['location']['name']))) : EMPTY_STR)
+ ));
+ }
+
+ return $event;
+/*
+ $event = [];
$object = json_decode($jobject,true);
$event_tz = '';
@@ -136,6 +215,7 @@ function format_event_obj($jobject) {
));
return $event;
+*/
}
function ical_wrapper($ev) {
@@ -1122,34 +1202,35 @@ function event_store_item($arr, $event) {
if($r) {
- set_iconfig($r[0]['id'], 'event', 'timezone', $arr['timezone'], true);
- xchan_query($r);
- $r = fetch_post_tags($r,true);
-
- $object = json_encode(array(
- 'type' => ACTIVITY_OBJ_EVENT,
- 'id' => z_root() . '/event/' . $r[0]['resource_id'],
- 'title' => $arr['summary'],
- 'timezone' => $arr['timezone'],
- 'dtstart' => $arr['dtstart'],
- 'dtend' => $arr['dtend'],
- 'nofinish' => $arr['nofinish'],
- 'description' => $arr['description'],
- 'location' => $arr['location'],
- 'adjust' => $arr['adjust'],
- 'content' => format_event_bbcode($arr),
+ //set_iconfig($r[0]['id'], 'event', 'timezone', $arr['timezone'], true);
+ //xchan_query($r);
+ //$r = fetch_post_tags($r,true);
+
+ $x = [
+ 'type' => 'Event',
+ 'id' => z_root() . '/event/' . $r[0]['resource_id'],
+ 'name' => $arr['summary'],
+// 'summary' => bbcode($arr['summary']),
+ // RFC3339 Section 4.3
+ 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')),
+ 'content' => bbcode($arr['description']),
+ 'location' => [ 'type' => 'Place', 'name' => $arr['location'] ],
+ 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ],
+ 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ],
+ 'actor' => Activity::encode_person($r[0], false),
'attachment' => Activity::encode_attachment($r[0]),
- 'author' => array(
- 'name' => $r[0]['author']['xchan_name'],
- 'address' => $r[0]['author']['xchan_addr'],
- 'guid' => $r[0]['author']['xchan_guid'],
- 'guid_sig' => $r[0]['author']['xchan_guid_sig'],
- 'link' => array(
- array('rel' => 'alternate', 'type' => 'text/html', 'href' => $r[0]['author']['xchan_url']),
- array('rel' => 'photo', 'type' => $r[0]['author']['xchan_photo_mimetype'], 'href' => $r[0]['author']['xchan_photo_m'])
- ),
- ),
- ));
+ 'tag' => Activity::encode_taxonomy($r[0])
+ ];
+
+ if (! $arr['nofinish']) {
+ $x['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00'));
+ }
+
+ if ($event['event_repeat']) {
+ $x['eventRepeat'] = $event['event_repeat'];
+ }
+
+ $object = json_encode($x);
$private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0);
@@ -1285,29 +1366,30 @@ function event_store_item($arr, $event) {
dbesc($arr['event_xchan'])
);
if($x) {
- $item_arr['obj'] = json_encode(array(
- 'type' => ACTIVITY_OBJ_EVENT,
- 'id' => z_root() . '/event/' . $event['event_hash'],
- 'title' => $arr['summary'],
- 'timezone' => $arr['timezone'],
- 'dtstart' => $arr['dtstart'],
- 'dtend' => $arr['dtend'],
- 'nofinish' => $arr['nofinish'],
- 'description' => $arr['description'],
- 'location' => $arr['location'],
- 'adjust' => $arr['adjust'],
- 'content' => format_event_bbcode($arr),
- 'attachment' => Activity::encode_attachment($item_arr),
- 'author' => array(
- 'name' => $x[0]['xchan_name'],
- 'address' => $x[0]['xchan_addr'],
- 'guid' => $x[0]['xchan_guid'],
- 'guid_sig' => $x[0]['xchan_guid_sig'],
- 'link' => array(
- array('rel' => 'alternate', 'type' => 'text/html', 'href' => $x[0]['xchan_url']),
- array('rel' => 'photo', 'type' => $x[0]['xchan_photo_mimetype'], 'href' => $x[0]['xchan_photo_m'])),
- ),
- ));
+ $y = [
+ 'type' => 'Event',
+ 'id' => z_root() . '/event/' . $event['event_hash'],
+ 'name' => $arr['summary'],
+// 'summary' => bbcode($arr['summary']),
+ // RFC3339 Section 4.3
+ 'startTime' => (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtstart'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtstart'], 'Y-m-d\\TH:i:s-00:00')),
+ 'content' => bbcode($arr['description']),
+ 'location' => [ 'type' => 'Place', 'name' => bbcode($arr['location']) ],
+ 'source' => [ 'content' => format_event_bbcode($arr), 'mediaType' => 'text/x-multicode' ],
+ 'url' => [ [ 'mediaType' => 'text/calendar', 'href' => z_root() . '/events/ical/' . $event['event_hash'] ] ],
+ 'actor' => Activity::encode_person($z, false),
+ 'attachment' => Activity::encode_attachment($item_arr),
+ 'tag' => Activity::encode_taxonomy($item_arr)
+ ];
+
+ if (! $arr['nofinish']) {
+ $y['endTime'] = (($arr['adjust']) ? datetime_convert('UTC', 'UTC', $arr['dtend'], ATOM_TIME) : datetime_convert('UTC', 'UTC', $arr['dtend'], 'Y-m-d\\TH:i:s-00:00'));
+ }
+ if ($arr['event_repeat']) {
+ $y['eventRepeat'] = $arr['event_repeat'];
+ }
+
+ $item_arr['obj'] = json_encode($y);
}
// propagate the event resource_id so that posts containing it are easily searchable in downstream copies
diff --git a/include/feedutils.php b/include/feedutils.php
index 1c653325d..734018922 100644
--- a/include/feedutils.php
+++ b/include/feedutils.php
@@ -194,14 +194,14 @@ function construct_activity_object($item) {
$r = json_decode($item['obj'],false);
if(! $r)
- return '';
- if($r->type)
+ return EMPTY_STR;
+ if(isset($r->type))
$o .= '<as:obj_type>' . xmlify($r->type) . '</as:obj_type>' . "\r\n";
- if($r->id)
+ if(isset($r->id))
$o .= '<id>' . xmlify($r->id) . '</id>' . "\r\n";
- if($r->title)
+ if(isset($r->title))
$o .= '<title>' . xmlify($r->title) . '</title>' . "\r\n";
- if($r->links) {
+ if(isset($r->links)) {
/** @FIXME!! */
if(substr($r->link,0,1) === '<') {
$r->link = preg_replace('/\<link(.*?)\"\>/','<link$1"/>',$r->link);
@@ -210,7 +210,7 @@ function construct_activity_object($item) {
else
$o .= '<link rel="alternate" type="text/html" href="' . xmlify($r->link) . '" />' . "\r\n";
}
- if($r->content) {
+ if(isset($r->content)) {
$o .= '<content type="html" >' . xmlify(bbcode($r->content)) . '</content>' . "\r\n";
}
$o .= '</as:object>' . "\r\n";
@@ -218,7 +218,7 @@ function construct_activity_object($item) {
return $o;
}
- return '';
+ return EMPTY_STR;
}
function construct_activity_target($item) {
@@ -1060,6 +1060,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
return;
}
+
+
$sys_expire = intval(get_config('system', 'default_expire_days'));
$chn_expire = intval($importer['channel_expire_days']);
@@ -1353,7 +1355,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
}
}
- if(! post_is_importable($datarray, $contact))
+ if(! post_is_importable($importer['channel_id'], $datarray, [$contact]))
continue;
$datarray['parent_mid'] = $datarray['mid'];
@@ -1509,7 +1511,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
}
}
- if(! post_is_importable($datarray, $contact))
+ if(! post_is_importable($importer['channel_id'], $datarray, [$contact]))
continue;
logger('author: ' . print_r($author, true), LOGGER_DEBUG);
diff --git a/include/html2bbcode.php b/include/html2bbcode.php
index 173ea63bd..cc67a5666 100644
--- a/include/html2bbcode.php
+++ b/include/html2bbcode.php
@@ -87,7 +87,7 @@ function deletenode(&$doc, $node)
function html2bbcode($message)
{
- if(!$message)
+ if(!is_string($message) && !$message)
return;
$message = str_replace("\r", "", $message);
diff --git a/include/items.php b/include/items.php
index 0b33d876d..8a2faa623 100644
--- a/include/items.php
+++ b/include/items.php
@@ -10,6 +10,7 @@ use Zotlabs\Lib\MarkdownSoap;
use Zotlabs\Lib\MessageFilter;
use Zotlabs\Lib\ThreadListener;
use Zotlabs\Lib\IConfig;
+use Zotlabs\Lib\PConfig;
use Zotlabs\Lib\Activity;
use Zotlabs\Lib\Libsync;
use Zotlabs\Lib\Libzot;
@@ -1072,21 +1073,6 @@ function encode_item($item,$mirror = false,$zap_compat = false) {
$x['type'] = 'activity';
$x['encoding'] = 'zot';
- $r = q("select channel_id from channel where channel_id = %d limit 1",
- intval($item['uid'])
- );
-
- if($r)
- $comment_scope = PermissionLimits::Get($item['uid'],'post_comments');
- else
- $comment_scope = 0;
-
- $scope = $item['public_policy'];
- if(! $scope)
- $scope = 'public';
-
- $c_scope = map_scope($comment_scope);
-
$key = get_config('system','prvkey');
// If we're trying to backup an item so that it's recoverable or for export/imprt,
@@ -1179,10 +1165,7 @@ function encode_item($item,$mirror = false,$zap_compat = false) {
$x['public_scope'] = $scope;
- if($item['item_nocomment'])
- $x['comment_scope'] = 'none';
- else
- $x['comment_scope'] = $c_scope;
+ $x['comment_scope'] = $item['comment_policy'];
if(! empty($item['term']))
$x['tags'] = encode_item_terms($item['term'],$mirror);
@@ -2218,9 +2201,9 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) {
$arr['deny_gid'] = ((array_key_exists('deny_gid',$arr)) ? trim($arr['deny_gid']) : $orig[0]['deny_gid']);
$arr['item_private'] = ((array_key_exists('item_private',$arr)) ? intval($arr['item_private']) : $orig[0]['item_private']);
- $arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
- $arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
- $arr['html'] = ((array_key_exists('html',$arr) && strlen($arr['html'])) ? trim($arr['html']) : '');
+ $arr['title'] = ((array_key_exists('title',$arr) && $arr['title']) ? trim($arr['title']) : '');
+ $arr['body'] = ((array_key_exists('body',$arr) && $arr['body']) ? trim($arr['body']) : '');
+ $arr['html'] = ((array_key_exists('html',$arr) && $arr['html']) ? trim($arr['html']) : '');
$arr['attach'] = ((array_key_exists('attach',$arr)) ? notags(trim($arr['attach'])) : $orig[0]['attach']);
$arr['app'] = ((array_key_exists('app',$arr)) ? notags(trim($arr['app'])) : $orig[0]['app']);
@@ -3495,24 +3478,57 @@ function check_item_source($uid, $item) {
return false;
}
-function post_is_importable($item,$abook) {
- if(! $abook)
- return true;
+// Checks an incoming item against the per-channel and per-connection content filter.
+// This implements the backend of the 'Content Filter' system app
- if(($abook['abook_channel']) && (! feature_enabled($abook['abook_channel'],'connfilter')))
- return true;
+function post_is_importable($channel_id, $item, $abook) {
- if(! $item)
+ if (! $item) {
return false;
+ }
- if(! ($abook['abook_incl'] || $abook['abook_excl']))
+ $incl = PConfig::get($channel_id, 'system', 'message_filter_incl', EMPTY_STR);
+ $excl = PConfig::get($channel_id, 'system', 'message_filter_excl', EMPTY_STR);
+
+ if ($incl || $excl) {
+ $x = MessageFilter::evaluate($item, $incl, $excl);
+ if (! $x) {
+ logger('MessageFilter: channel blocked content', LOGGER_DEBUG, LOG_INFO);
+ return false;
+ }
+ }
+
+ if(!feature_enabled($channel_id, 'connfilter')) {
return true;
+ }
- return MessageFilter::evaluate($item,$abook['abook_incl'],$abook['abook_excl']);
+ if (! $abook) {
+ return true;
+ }
+ foreach ($abook as $ab) {
+ // check eligibility
+ if (intval($ab['abook_self'])) {
+ continue;
+ }
+ if (! ($ab['abook_incl'] || $ab['abook_excl'])) {
+ continue;
+ }
+
+ $evaluator = MessageFilter::evaluate($item, $ab['abook_incl'], $ab['abook_excl']);
+ // A negative assessment for any individual connections
+ // is an instant fail
+ if (! $evaluator) {
+ logger('MessageFilter: connection blocked content', LOGGER_DEBUG, LOG_INFO);
+ return false;
+ }
+ }
+
+ return true;
}
+
function fix_private_photos($s, $uid, $item = null, $cid = 0) {
logger('fix_private_photos', LOGGER_DEBUG);
diff --git a/include/language.php b/include/language.php
index d291deb63..23aff0a02 100644
--- a/include/language.php
+++ b/include/language.php
@@ -311,6 +311,11 @@ function string_plural_select_default($n) {
* @return string Language code in 2-letter ISO 639-1 (en, de, fr) format
*/
function detect_language($s) {
+
+ if (!$s) {
+ return EMPTY_STR;
+ }
+
$min_length = get_config('system', 'language_detect_min_length');
if ($min_length === false)
$min_length = LANGUAGE_DETECT_MIN_LENGTH;
diff --git a/include/nav.php b/include/nav.php
index 9278c1587..b9b24e34c 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -118,11 +118,11 @@ function nav($template = 'default') {
else {
if (!get_account_id()) {
if (App::$module === 'channel') {
- $nav['login'] = login(true, 'main-login', false, false);
+ $nav['login'] = login(true, 'modal_login', false, false);
$nav['loginmenu'][] = ['login', t('Login'), '', t('Sign in'), ''];
}
else {
- $nav['login'] = login(true, 'main-login', false, false);
+ $nav['login'] = login(true, 'modal_login', false, false);
$nav['loginmenu'][] = ['login', t('Login'), '', t('Sign in'), 'login_nav_btn'];
App::$page['content'] .= replace_macros(get_markup_template('nav_login.tpl'),
diff --git a/include/network.php b/include/network.php
index 64605749d..a236a6f8e 100644
--- a/include/network.php
+++ b/include/network.php
@@ -365,9 +365,14 @@ function z_post_url($url, $params, $redirects = 0, $opts = array()) {
if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308) {
$matches = array();
preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches);
- $newurl = trim(array_pop($matches));
- if(strpos($newurl,'/') === 0)
+
+ $newurl = '';
+ if (array_pop($matches))
+ $newurl = trim(array_pop($matches));
+
+ if($newurl && strpos($newurl,'/') === 0)
$newurl = $url . $newurl;
+
$url_parsed = @parse_url($newurl);
if (isset($url_parsed)) {
curl_close($ch);
@@ -554,6 +559,14 @@ function z_dns_check($h,$check_mx = 0) {
return((@dns_get_record($h,$opts) || filter_var($h, FILTER_VALIDATE_IP)) ? true : false);
}
+function is_local_url($url) {
+ if (str_starts_with($url, z_root()) || str_starts_with($url, '/')) {
+ return true;
+ }
+
+ return false;
+}
+
/**
* @brief Validates a given URL.
*
@@ -1986,6 +1999,10 @@ function getBestSupportedMimeType($mimeTypes = null, $acceptedTypes = false) {
if($acceptedTypes === false)
$acceptedTypes = $_SERVER['HTTP_ACCEPT'];
+ if (!$acceptedTypes) {
+ return null;
+ }
+
// Accept header is case insensitive, and whitespace isn’t important
$accept = strtolower(str_replace(' ', '', $acceptedTypes));
// divide it into parts in the place of a ","
diff --git a/include/oembed.php b/include/oembed.php
index 9a25686fa..36938c577 100644
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -134,6 +134,7 @@ function oembed_fetch_url($embedurl){
}
$txt = null;
+ $j = null;
// we should try to cache this and avoid a lookup on each render
$is_matrix = is_matrix_url($embedurl);
@@ -160,7 +161,7 @@ function oembed_fetch_url($embedurl){
if(is_null($txt)) {
- $txt = "";
+ $txt = EMPTY_STR;
if ($action !== 'block') {
// try oembed autodiscovery
@@ -168,7 +169,7 @@ function oembed_fetch_url($embedurl){
$result = z_fetch_url($furl, false, $redirects,
[
'timeout' => 30,
- 'accept_content' => "text/*",
+ 'accept_content' => 'text/*',
'novalidate' => true,
'session' => ((local_channel() && $zrl) ? true : false)
]
@@ -227,9 +228,10 @@ function oembed_fetch_url($embedurl){
$txt = $x['embed'];
}
- $txt=trim($txt);
+ $txt = trim($txt);
- if ($txt[0]!="{") $txt='{"type":"error"}';
+ if (substr($txt, 0, 1) !== '{')
+ $txt = '{"type":"error"}';
// save in cache
@@ -247,7 +249,7 @@ function oembed_fetch_url($embedurl){
}
if($action === 'filter') {
- if($j['html']) {
+ if(isset($j['html']) && $j['html']) {
$orig = $j['html'];
$allow_position = (($is_matrix) ? true : false);
diff --git a/include/plugin.php b/include/plugin.php
index 95c9882d0..f9cee7ed6 100644
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -794,6 +794,79 @@ function get_theme_info($theme){
}
/**
+ * @brief Parse template comment in search of template info.
+ *
+ * like
+ * \code
+ * * Name: MyWidget
+ * * Description: A widget
+ * * Version: 1.2.3
+ * * Author: John <profile url>
+ * * Author: Jane <email>
+ * * ContentRegionID: some_id
+ * * ContentRegionID: some_other_id
+ * *
+ *\endcode
+ * @param string $widget the name of the widget
+ * @return array with the information
+ */
+function get_template_info($template){
+ $m = array();
+ $info = array(
+ 'name' => $template,
+ 'description' => '',
+ 'author' => array(),
+ 'maintainer' => array(),
+ 'version' => '',
+ 'content_regions' => []
+ );
+
+ $checkpaths = [
+ "view/php/$template.php",
+ ];
+
+ $template_found = false;
+
+ foreach ($checkpaths as $path) {
+ if (is_file($path)) {
+ $template_found = true;
+ $f = file_get_contents($path);
+ break;
+ }
+ }
+
+ if(! ($template_found && $f))
+ return $info;
+
+ $f = escape_tags($f);
+ $r = preg_match("|/\*.*\*/|msU", $f, $m);
+
+ if ($r) {
+ $ll = explode("\n", $m[0]);
+ foreach( $ll as $l ) {
+ $l = trim($l, "\t\n\r */");
+ if ($l != ""){
+ list($k, $v) = array_map("trim", explode(":", $l, 2));
+ $k = strtolower($k);
+ if ($k == 'author' || $k == 'maintainer'){
+ $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);
+ if ($r) {
+ $info[$k][] = array('name' => $m[1], 'link' => $m[2]);
+ } else {
+ $info[$k][] = array('name' => $v);
+ }
+ }
+ else {
+ $info[$k] = $v;
+ }
+ }
+ }
+ }
+
+ return $info;
+}
+
+/**
* @brief Returns the theme's screenshot.
*
* The screenshot is expected as view/theme/$theme/img/screenshot.[png|jpg].
@@ -868,9 +941,7 @@ function head_get_links() {
function format_css_if_exists($source) {
- // script_path() returns https://yoursite.tld
-
- $path_prefix = script_path();
+ $path_prefix = z_root();
$script = $source[0];
@@ -892,44 +963,6 @@ function format_css_if_exists($source) {
}
}
-/**
- * This basically calculates the baseurl. We have other functions to do that, but
- * there was an issue with script paths and mixed-content whose details are arcane
- * and perhaps lost in the message archives. The short answer is that we're ignoring
- * the URL which we are "supposed" to use, and generating script paths relative to
- * the URL which we are currently using; in order to ensure they are found and aren't
- * blocked due to mixed content issues.
- *
- * @return string
- */
-function script_path() {
- if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS'])
- $scheme = 'https';
- elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443))
- $scheme = 'https';
- elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on')
- $scheme = 'https';
- else
- $scheme = 'http';
-
- // Some proxy setups may require using http_host
-
- if(isset(App::$config['system']['script_path_use_http_host']) && intval(App::$config['system']['script_path_use_http_host']))
- $server_var = 'HTTP_HOST';
- else
- $server_var = 'SERVER_NAME';
-
-
- if(x($_SERVER,$server_var)) {
- $hostname = $_SERVER[$server_var];
- }
- else {
- return z_root();
- }
-
- return $scheme . '://' . $hostname;
-}
-
function head_add_js($src, $priority = 0) {
if(isset(App::$js_sources[$priority]) && !is_array(App::$js_sources[$priority]))
App::$js_sources[$priority] = [];
@@ -981,7 +1014,7 @@ function head_get_main_js() {
}
function format_js_if_exists($source) {
- $path_prefix = script_path();
+ $path_prefix = z_root();
if(strpos($source,'/') !== false) {
// The source is a known path on the system
diff --git a/include/text.php b/include/text.php
index 29a2ab3b1..0c806d009 100644
--- a/include/text.php
+++ b/include/text.php
@@ -108,9 +108,24 @@ function notags($string) {
* @return string
*/
function escape_tags($string) {
- return(htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false));
+ if (!$string) {
+ return EMPTY_STR;
+ }
+ return (htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false));
}
+/**
+ * Escape URL's so they're safe for use in HTML and in HTML element attributes.
+ */
+function escape_url($input) {
+ if (empty($input)) {
+ return EMPTY_STR;
+ }
+
+ // This is a bit crude but seems to do the trick for now. It makes no
+ // guarantees that the URL is valid for use after escaping.
+ return htmlspecialchars($input, ENT_HTML5 | ENT_QUOTES);
+}
function z_input_filter($s,$type = 'text/bbcode',$allow_code = false) {
@@ -3531,7 +3546,7 @@ function text_highlight($s, $lang) {
// echo (($xml->asXML('data.xml')) ? 'Your XML file has been generated successfully!' : 'Error generating XML file!');
function arrtoxml($root_elem,$arr) {
- $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><' . $root_elem . '></' . $root_elem . '>', null, false);
+ $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><' . $root_elem . '></' . $root_elem . '>', 0, false);
array2XML($xml,$arr);
return $xml->asXML();
@@ -4054,9 +4069,10 @@ function sanitize_text_field($str) {
*/
function substr_words($str, $max_length, $suffix = '...') {
+ $ret = '';
+
if (strlen($str) > $max_length) {
$words = preg_split('/\s/', $str);
- $ret = '';
$i = 0;
while (true) {
$length = (strlen($ret) + strlen($words[$i]));
diff --git a/include/zid.php b/include/zid.php
index ae7d9e252..5710d9f3f 100644
--- a/include/zid.php
+++ b/include/zid.php
@@ -58,6 +58,8 @@ function zid($s, $address = '') {
$mine_parsed = parse_url($mine);
$s_parsed = parse_url($s);
+
+ $url_match = false;
if(isset($mine_parsed['host']) && isset($s_parsed['host']) && $mine_parsed['host'] === $s_parsed['host'])
$url_match = true;