aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--Zotlabs/Daemon/Queue.php6
-rw-r--r--Zotlabs/Module/Admin/Accounts.php7
-rw-r--r--Zotlabs/Module/Admin/Security.php12
-rw-r--r--Zotlabs/Module/Admin/Site.php3
-rw-r--r--Zotlabs/Module/Cards.php79
-rw-r--r--Zotlabs/Module/Channel.php6
-rw-r--r--Zotlabs/Module/Connections.php2
-rw-r--r--Zotlabs/Module/Connedit.php24
-rw-r--r--Zotlabs/Module/Display.php17
-rw-r--r--Zotlabs/Module/Email_validation.php11
-rw-r--r--Zotlabs/Module/Go.php66
-rw-r--r--Zotlabs/Module/Hq.php4
-rw-r--r--Zotlabs/Module/Item.php1
-rw-r--r--Zotlabs/Module/Linkinfo.php4
-rw-r--r--Zotlabs/Module/Network.php36
-rw-r--r--Zotlabs/Module/New_channel.php4
-rw-r--r--Zotlabs/Module/Ping.php19
-rw-r--r--Zotlabs/Module/Pubstream.php4
-rw-r--r--Zotlabs/Module/Settings/Display.php26
-rw-r--r--Zotlabs/Render/Theme.php30
-rw-r--r--Zotlabs/Widget/Forums.php3
-rwxr-xr-xboot.php85
-rw-r--r--doc/member/member_guide.bb8
-rw-r--r--images/video_poster.jpgbin0 -> 24871 bytes
-rw-r--r--include/acl_selectors.php97
-rw-r--r--include/auth.php1
-rw-r--r--include/bbcode.php6
-rw-r--r--include/datetime.php97
-rw-r--r--include/feedutils.php277
-rw-r--r--include/hubloc.php18
-rwxr-xr-xinclude/items.php2
-rwxr-xr-xinclude/plugin.php60
-rw-r--r--include/text.php31
-rw-r--r--install/schema_mysql.sql9
-rw-r--r--install/update.php31
-rw-r--r--library/Mobile_Detect/Mobile_Detect.php221
-rw-r--r--view/pdl/mod_go.pdl6
-rwxr-xr-xview/tpl/abook_edit.tpl2
-rwxr-xr-xview/tpl/admin_accounts.tpl4
-rwxr-xr-xview/tpl/admin_site.tpl1
-rwxr-xr-xview/tpl/atom_feed.tpl2
-rwxr-xr-xview/tpl/connections.tpl4
-rw-r--r--view/tpl/go.tpl16
-rwxr-xr-xview/tpl/jot-header.tpl11
-rw-r--r--view/tpl/notifications_widget.tpl8
-rwxr-xr-xview/tpl/settings_display.tpl9
47 files changed, 578 insertions, 798 deletions
diff --git a/README.md b/README.md
index 54f80bebe..240d976f3 100644
--- a/README.md
+++ b/README.md
@@ -3,18 +3,18 @@
Hubzilla - Community Server
===========================
+
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
</p>
-
**What is Hubzilla?**
-Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online.
+Hubzilla is a general purpose communication server integrated with a web publishing system and a decentralised permission system. If this sounds like a bunch of technical mumbo-jumbo to you, just think of it as an independent platform for sharing stuff online (publicly or privately).
Hubzilla contains some social network bits, some cloud storage bits, some blog and forum bits, and some content management bits. These are all integrated within a common privacy framework - and it is all decentralised.
-Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - even with channels on different servers or other communications services.
+Everything you publish or share can be restricted to those channels and people you wish to share them with; and these permissions work completely invisibly - **even with channels on different servers or other communications services**.
Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
diff --git a/Zotlabs/Daemon/Queue.php b/Zotlabs/Daemon/Queue.php
index 17d150250..8f529ff13 100644
--- a/Zotlabs/Daemon/Queue.php
+++ b/Zotlabs/Daemon/Queue.php
@@ -13,10 +13,10 @@ class Queue {
require_once('include/bbcode.php');
- if(argc() > 1)
- $queue_id = argv(1);
+ if($argc > 1)
+ $queue_id = $argv[1];
else
- $queue_id = 0;
+ $queue_id = EMPTY_STR;
logger('queue: start');
diff --git a/Zotlabs/Module/Admin/Accounts.php b/Zotlabs/Module/Admin/Accounts.php
index 2043550fc..2e417edd1 100644
--- a/Zotlabs/Module/Admin/Accounts.php
+++ b/Zotlabs/Module/Admin/Accounts.php
@@ -16,6 +16,7 @@ class Accounts {
*/
function post() {
+
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
$blocked = ( x($_POST, 'blocked') ? $_POST['blocked'] : array() );
@@ -24,7 +25,7 @@ class Accounts {
// change to switch structure?
// account block/unblock button was submitted
- if (x($_POST, 'page_users_block')) {
+ if (x($_POST, 'page_accounts_block')) {
for ($i = 0; $i < count($users); $i++) {
// if account is blocked remove blocked bit-flag, otherwise add blocked bit-flag
$op = ($blocked[$i]) ? '& ~' : '| ';
@@ -43,13 +44,13 @@ class Accounts {
notice( sprintf( tt("%s account deleted", "%s accounts deleted", count($users)), count($users)) );
}
// registration approved button was submitted
- if (x($_POST, 'page_users_approve')) {
+ if (x($_POST, 'page_accounts_approve')) {
foreach ($pending as $hash) {
account_allow($hash);
}
}
// registration deny button was submitted
- if (x($_POST, 'page_users_deny')) {
+ if (x($_POST, 'page_accounts_deny')) {
foreach ($pending as $hash) {
account_deny($hash);
}
diff --git a/Zotlabs/Module/Admin/Security.php b/Zotlabs/Module/Admin/Security.php
index a1e4bf537..49e1ccf42 100644
--- a/Zotlabs/Module/Admin/Security.php
+++ b/Zotlabs/Module/Admin/Security.php
@@ -52,24 +52,24 @@ class Security {
function get() {
$whitesites = get_config('system','whitelisted_sites');
- $whitesites_str = ((is_array($whitesites)) ? implode($whitesites,"\n") : '');
+ $whitesites_str = ((is_array($whitesites)) ? implode("\n",$whitesites) : '');
$blacksites = get_config('system','blacklisted_sites');
- $blacksites_str = ((is_array($blacksites)) ? implode($blacksites,"\n") : '');
+ $blacksites_str = ((is_array($blacksites)) ? implode("\n",$blacksites) : '');
$whitechannels = get_config('system','whitelisted_channels');
- $whitechannels_str = ((is_array($whitechannels)) ? implode($whitechannels,"\n") : '');
+ $whitechannels_str = ((is_array($whitechannels)) ? implode("\n",$whitechannels) : '');
$blackchannels = get_config('system','blacklisted_channels');
- $blackchannels_str = ((is_array($blackchannels)) ? implode($blackchannels,"\n") : '');
+ $blackchannels_str = ((is_array($blackchannels)) ? implode("\n",$blackchannels) : '');
$whiteembeds = get_config('system','embed_allow');
- $whiteembeds_str = ((is_array($whiteembeds)) ? implode($whiteembeds,"\n") : '');
+ $whiteembeds_str = ((is_array($whiteembeds)) ? implode("\n",$whiteembeds) : '');
$blackembeds = get_config('system','embed_deny');
- $blackembeds_str = ((is_array($blackembeds)) ? implode($blackembeds,"\n") : '');
+ $blackembeds_str = ((is_array($blackembeds)) ? implode("\n",$blackembeds) : '');
$embed_coop = intval(get_config('system','embed_coop'));
diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php
index 037f49277..52b36e03e 100644
--- a/Zotlabs/Module/Admin/Site.php
+++ b/Zotlabs/Module/Admin/Site.php
@@ -38,6 +38,7 @@ class Site {
$site_sellpage = ((x($_POST,'site_sellpage')) ? notags(trim($_POST['site_sellpage'])) : '');
$site_location = ((x($_POST,'site_location')) ? notags(trim($_POST['site_location'])) : '');
$frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
+ $firstpage = ((x(trim($_POST,'firstpage'))) ? notags(trim($_POST['firstpage'])) : 'profiles');
$mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
$directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : '');
$allowed_sites = ((x($_POST,'allowed_sites')) ? notags(trim($_POST['allowed_sites'])) : '');
@@ -80,6 +81,7 @@ class Site {
set_config('system', 'maxloadavg', $maxloadavg);
set_config('system', 'frontpage', $frontpage);
set_config('system', 'sellpage', $site_sellpage);
+ set_config('system', 'workflow_channel_next', $firstpage);
set_config('system', 'site_location', $site_location);
set_config('system', 'mirror_frontpage', $mirror_frontpage);
set_config('system', 'sitename', $sitename);
@@ -340,6 +342,7 @@ class Site {
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
'$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())),
+ '$firstpage' => array('firstpage', t('Page to display after creating a new channel'), get_config('system','workflow_channel_next','profiles'), t('Recommend: profiles, go, or settings')),
'$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')),
diff --git a/Zotlabs/Module/Cards.php b/Zotlabs/Module/Cards.php
index 22c5d673c..f87988183 100644
--- a/Zotlabs/Module/Cards.php
+++ b/Zotlabs/Module/Cards.php
@@ -9,18 +9,22 @@ require_once('include/acl_selectors.php');
class Cards extends \Zotlabs\Web\Controller {
function init() {
-
+
if(argc() > 1)
$which = argv(1);
else
return;
-
+
profile_load($which);
-
+
}
-
+
+ /**
+ * {@inheritDoc}
+ * @see \Zotlabs\Web\Controller::get()
+ */
function get($update = 0, $load = false) {
-
+
if(observer_prohibited(true)) {
return login();
}
@@ -31,13 +35,13 @@ class Cards extends \Zotlabs\Web\Controller {
return;
}
- if(! feature_enabled(\App::$profile_uid,'cards')) {
+ if(! feature_enabled(\App::$profile_uid, 'cards')) {
return;
}
nav_set_selected(t('Cards'));
- head_add_link([
+ head_add_link([
'rel' => 'alternate',
'type' => 'application/json+oembed',
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
@@ -46,48 +50,48 @@ class Cards extends \Zotlabs\Web\Controller {
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
-
+
if($category) {
- $sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
+ $sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'], 'item', $category, TERM_CATEGORY));
}
$which = argv(1);
-
+
$selected_card = ((argc() > 2) ? argv(2) : '');
$_SESSION['return_url'] = \App::$query_string;
-
+
$uid = local_channel();
$owner = \App::$profile_uid;
$observer = \App::get_observer();
-
+
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
-
- if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
+
+ if(! perm_is_allowed($owner, $ob_hash, 'view_pages')) {
notice( t('Permission denied.') . EOL);
return;
}
-
+
$is_owner = ($uid && $uid == $owner);
-
+
$channel = channelx_by_n($owner);
if($channel) {
- $channel_acl = array(
+ $channel_acl = [
'allow_cid' => $channel['channel_allow_cid'],
'allow_gid' => $channel['channel_allow_gid'],
'deny_cid' => $channel['channel_deny_cid'],
'deny_gid' => $channel['channel_deny_gid']
- );
+ ];
}
else {
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
}
-
- if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
+
+ if(perm_is_allowed($owner, $ob_hash, 'write_pages')) {
$x = [
'webpage' => ITEM_TYPE_CARD,
@@ -95,9 +99,9 @@ class Cards extends \Zotlabs\Web\Controller {
'content_label' => t('Add Card'),
'button' => t('Create'),
'nickname' => $channel['channel_address'],
- 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
+ 'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
- 'acl' => (($is_owner) ? populate_acl($channel_acl, false,
+ 'acl' => (($is_owner) ? populate_acl($channel_acl, false,
\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
'permissions' => $channel_acl,
'showacl' => (($is_owner) ? true : false),
@@ -110,7 +114,7 @@ class Cards extends \Zotlabs\Web\Controller {
'layoutselect' => false,
'expanded' => false,
'novoting' => false,
- 'catsenabled' => feature_enabled($owner,'categories'),
+ 'catsenabled' => feature_enabled($owner, 'categories'),
'bbco_autocomplete' => 'bbcode',
'bbcode' => true
];
@@ -119,14 +123,14 @@ class Cards extends \Zotlabs\Web\Controller {
$x['title'] = $_REQUEST['title'];
if($_REQUEST['body'])
$x['body'] = $_REQUEST['body'];
- $editor = status_editor($a,$x);
+ $editor = status_editor($a, $x);
}
else {
$editor = '';
}
-
-
+
+
$sql_extra = item_permissions_sql($owner);
if($selected_card) {
@@ -137,9 +141,9 @@ class Cards extends \Zotlabs\Web\Controller {
$sql_extra .= "and item.id = " . intval($r[0]['iid']) . " ";
}
}
-
- $r = q("select * from item
- where item.uid = %d and item_type = %d
+
+ $r = q("select * from item
+ where uid = %d and item_type = %d
$sql_extra order by item.created desc",
intval($owner),
intval(ITEM_TYPE_CARD)
@@ -149,9 +153,10 @@ class Cards extends \Zotlabs\Web\Controller {
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
and item.item_blocked = 0 ";
+ $items_result = [];
if($r) {
- $parents_str = ids_to_querystr($r,'id');
+ $parents_str = ids_to_querystr($r, 'id');
$items = q("SELECT item.*, item.id AS item_id
FROM item
@@ -164,24 +169,22 @@ class Cards extends \Zotlabs\Web\Controller {
if($items) {
xchan_query($items);
$items = fetch_post_tags($items, true);
- $items = conv_sort($items,'updated');
+ $items_result = conv_sort($items, 'updated');
}
- else
- $items = [];
}
$mode = 'cards';
-
- $content = conversation($items,$mode,false,'traditional');
+
+ $content = conversation($items_result, $mode, false, 'traditional');
$o = replace_macros(get_markup_template('cards.tpl'), [
'$title' => t('Cards'),
'$editor' => $editor,
'$content' => $content,
- '$pager' => alt_pager($a,count($items))
+ '$pager' => alt_pager($a, count($items_result))
]);
- return $o;
- }
+ return $o;
+ }
}
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 7c4c900a1..b7e18f954 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -239,7 +239,7 @@ class Channel extends \Zotlabs\Web\Controller {
if($load || ($checkjs->disabled())) {
if($mid) {
- $r = q("SELECT distinct parent AS item_id from item where mid like '%s' and uid = %d $item_normal
+ $r = q("SELECT parent AS item_id from item where mid like '%s' and uid = %d $item_normal
AND item_wall = 1 $sql_extra limit 1",
dbesc($mid . '%'),
intval(\App::$profile['profile_uid'])
@@ -249,13 +249,13 @@ class Channel extends \Zotlabs\Web\Controller {
}
}
else {
- $r = q("SELECT distinct id AS item_id, created FROM item
+ $r = q("SELECT id AS item_id FROM item
left join abook on item.author_xchan = abook.abook_xchan
WHERE uid = %d $item_normal
AND item_wall = 1 and item_thread_top = 1
AND (abook_blocked = 0 or abook.abook_flags is null)
$sql_extra $sql_extra2
- ORDER BY created DESC $pager_sql ",
+ ORDER BY created DESC, id $pager_sql ",
intval(\App::$profile['profile_uid'])
);
}
diff --git a/Zotlabs/Module/Connections.php b/Zotlabs/Module/Connections.php
index f42ff9b84..255731c9c 100644
--- a/Zotlabs/Module/Connections.php
+++ b/Zotlabs/Module/Connections.php
@@ -232,7 +232,7 @@ class Connections extends \Zotlabs\Web\Controller {
if($rr['xchan_url']) {
if(($rr['vcard']) && is_array($rr['vcard']['tels']) && $rr['vcard']['tels'][0]['nr'])
- $phone = ((\App::$is_mobile || \App::$is_tablet) ? $rr['vcard']['tels'][0]['nr'] : '');
+ $phone = $rr['vcard']['tels'][0]['nr'];
else
$phone = '';
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index 8288886cd..f359175c1 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -826,27 +826,10 @@ class Connedit extends \Zotlabs\Web\Controller {
}
}
- $locstr = '';
-
- $locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s'
- and hubloc_deleted = 0 and site_dead = 0",
- dbesc($contact['xchan_hash'])
- );
-
- if($locs) {
- foreach($locs as $l) {
- if(!($l['location']))
- continue;
- if(strpos($locstr,$l['location']) !== false)
- continue;
- if(strlen($locstr))
- $locstr .= ', ';
- $locstr .= $l['location'];
- }
- }
- else
+ $locstr = locations_by_netid($contact['xchan_hash']);
+ if(! $locstr)
$locstr = $contact['xchan_url'];
-
+
$clone_warn = '';
$clonable = (in_array($contact['xchan_network'],['zot','rss']) ? true : false);
if(! $clonable) {
@@ -912,7 +895,6 @@ class Connedit extends \Zotlabs\Web\Controller {
'$permnote_self' => t('Some permissions may be inherited from your channel\'s <a href="settings"><strong>privacy settings</strong></a>, which have higher priority than individual settings. You can change those settings here but they wont have any impact unless the inherited setting changes.'),
'$lastupdtext' => t('Last update:'),
'$last_update' => relative_date($contact['abook_connected']),
- '$is_mobile' => ((\App::$is_mobile || \App::$is_tablet) ? true : false),
'$profile_select' => contact_profile_assign($contact['abook_profile']),
'$multiprofs' => $multiprofs,
'$contact_id' => $contact['abook_id'],
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index 6d895feb5..11dd0d174 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -343,14 +343,15 @@ class Display extends \Zotlabs\Web\Controller {
case 'atom':
$atom = replace_macros(get_markup_template('atom_feed.tpl'), array(
- '$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
- '$red' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
- '$feed_id' => xmlify(\App::$cmd),
- '$feed_title' => xmlify(t('Article')),
- '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
- '$author' => '',
- '$owner' => '',
- '$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']),
+ '$version' => xmlify(\Zotlabs\Lib\System::get_project_version()),
+ '$generator' => xmlify(\Zotlabs\Lib\System::get_platform_name()),
+ '$generator_uri' => 'https://hubzilla.org',
+ '$feed_id' => xmlify(\App::$cmd),
+ '$feed_title' => xmlify(t('Article')),
+ '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
+ '$author' => '',
+ '$owner' => '',
+ '$profile_page' => xmlify(z_root() . '/display/' . $target_item['mid']),
));
$x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ];
diff --git a/Zotlabs/Module/Email_validation.php b/Zotlabs/Module/Email_validation.php
index 4cc016847..b8bb720cd 100644
--- a/Zotlabs/Module/Email_validation.php
+++ b/Zotlabs/Module/Email_validation.php
@@ -8,9 +8,18 @@ class Email_validation extends \Zotlabs\Web\Controller {
function post() {
if($_POST['token']) {
- if(! account_approve(trim($_POST['token']))) {
+ // This will redirect internally on success unless the channel is auto_created
+ if(! account_approve(trim(basename($_POST['token'])))) {
notice('Token verification failed.');
}
+ else {
+ if(get_config('system','auto_channel_create')) {
+ $next_page = get_config('system', 'workflow_channel_next', 'profiles');
+ }
+ if($next_page) {
+ goaway(z_root() . '/' . $next_page);
+ }
+ }
}
}
diff --git a/Zotlabs/Module/Go.php b/Zotlabs/Module/Go.php
new file mode 100644
index 000000000..2c2dcf460
--- /dev/null
+++ b/Zotlabs/Module/Go.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Zotlabs\Module;
+
+
+class Go extends \Zotlabs\Web\Controller {
+
+ function init() {
+ if(local_channel()) {
+ $channel = \App::get_channel();
+ if($channel) {
+ profile_load($channel['channel_address'],0);
+ }
+ }
+ }
+
+
+
+ function get() {
+ if(! local_channel()) {
+ notify( t('This page is available only to site members') . EOL);
+ }
+
+ $channel = \App::get_channel();
+
+
+ $title = t('Welcome');
+
+ $m = t('What would you like to do?');
+
+ $m1 = t('Please bookmark this page if you would like to return to it in the future');
+
+
+ $options = [
+ 'profile_photo' => t('Upload a profile photo'),
+ 'profiles' => t('Edit your default profile'),
+ 'suggest' => t('View friend suggestions'),
+ 'directory' => t('View the directory to find other interesting channels'),
+ 'settings' => t('View/edit your channel settings'),
+ 'help' => t('View the site or project documentation'),
+ 'channel/' . $channel['channel_address'] => t('Visit your channel homepage'),
+ 'connections' => t('View your connections and/or add somebody whose address you already know'),
+ 'network' => t('View your personal stream (this may be empty until you add some connections)'),
+
+ ];
+
+ $site_firehose = ((intval(get_config('system','site_firehose',0))) ? true : false);
+ $net_firehose = ((get_config('system','disable_discover_tab',1)) ? false : true);
+
+ if($site_firehose || $net_firehose) {
+ $options['pubstream'] = t('View the public stream. Warning: this content is not moderated');
+ }
+
+ $o = replace_macros(get_markup_template('go.tpl'), [
+ '$title' => $title,
+ '$m' => $m,
+ '$m1' => $m1,
+ '$options' => $options
+
+ ]);
+
+ return $o;
+
+ }
+
+} \ No newline at end of file
diff --git a/Zotlabs/Module/Hq.php b/Zotlabs/Module/Hq.php
index c46695b65..baeba82e8 100644
--- a/Zotlabs/Module/Hq.php
+++ b/Zotlabs/Module/Hq.php
@@ -51,10 +51,8 @@ class Hq extends \Zotlabs\Web\Controller {
$item_normal = item_normal();
$item_normal_update = item_normal_update();
- $use_index = db_use_index('created');
-
if(! $item_hash) {
- $r = q("SELECT mid FROM item $use_index
+ $r = q("SELECT mid FROM item
WHERE uid = %d $item_normal
AND mid = parent_mid
ORDER BY created DESC LIMIT 1",
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index ad829137a..db2d64d70 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -753,6 +753,7 @@ class Item extends \Zotlabs\Web\Controller {
if ((! $plink) && ($item_thread_top)) {
$plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid;
+ $plink = substr($plink,0,190);
}
$datarray['aid'] = $channel['channel_account_id'];
diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php
index 78c34583e..3392e4114 100644
--- a/Zotlabs/Module/Linkinfo.php
+++ b/Zotlabs/Module/Linkinfo.php
@@ -120,9 +120,9 @@ class Linkinfo extends \Zotlabs\Web\Controller {
$siteinfo = self::parseurl_getsiteinfo($url);
- // If this is a Red site, use zrl rather than url so they get zids sent to them by default
+ // If the site uses this platform, use zrl rather than url so they get zids sent to them by default
- if( x($siteinfo,'generator') && (strpos($siteinfo['generator'], \Zotlabs\Lib\System::get_platform_name() . ' ') === 0))
+ if(is_matrix_url($url))
$template = str_replace('url','zrl',$template);
if($siteinfo["title"] == "") {
diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php
index 551303984..70e0048fb 100644
--- a/Zotlabs/Module/Network.php
+++ b/Zotlabs/Module/Network.php
@@ -209,8 +209,11 @@ class Network extends \Zotlabs\Web\Controller {
: '');
$sql_nets = '';
+
+ $distinct = '';
+ $item_thread_top = ' AND item_thread_top = 1 ';
- $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options ) ";
+ $sql_extra = $sql_options;
if($group) {
$contact_str = '';
@@ -226,7 +229,8 @@ class Network extends \Zotlabs\Web\Controller {
$contact_str = ' 0 ';
info( t('Privacy group is empty'));
}
-
+ $distinct = ' distinct ';
+ $item_thread_top = '';
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) ";
$x = group_rec_byhash(local_channel(), $group_hash);
@@ -250,6 +254,8 @@ class Network extends \Zotlabs\Web\Controller {
intval(local_channel())
);
if($r) {
+ $distinct = ' distinct ';
+ $item_thread_top = '';
$sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) $item_normal ) ";
$title = replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => '<a href="' . zid($r[0]['xchan_url']) . '" ><img src="' . zid($r[0]['xchan_photo_s']) . '" alt="' . urlencode($r[0]['xchan_name']) . '" /></a> <a href="' . zid($r[0]['xchan_url']) . '" >' . $r[0]['xchan_name'] . '</a>'
@@ -264,13 +270,15 @@ class Network extends \Zotlabs\Web\Controller {
}
}
elseif($xchan) {
- $r = q("select * from xchan where xchan_hash = '%s'",
- dbesc($xchan)
- );
- if($r) {
- $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($xchan) . "' or owner_xchan = '" . dbesc($xchan) . "' ) $item_normal ) ";
- $title = replace_macros(get_markup_template("section_title.tpl"),array(
- '$title' => '<a href="' . zid($r[0]['xchan_url']) . '" ><img src="' . zid($r[0]['xchan_photo_s']) . '" alt="' . urlencode($r[0]['xchan_name']) . '" /></a> <a href="' . zid($r[0]['xchan_url']) . '" >' . $r[0]['xchan_name'] . '</a>'
+ $r = q("select * from xchan where xchan_hash = '%s'",
+ dbesc($xchan)
+ );
+ if($r) {
+ $distinct = ' distinct ';
+ $item_thread_top = '';
+ $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($xchan) . "' or owner_xchan = '" . dbesc($xchan) . "' ) $item_normal ) ";
+ $title = replace_macros(get_markup_template("section_title.tpl"),array(
+ '$title' => '<a href="' . zid($r[0]['xchan_url']) . '" ><img src="' . zid($r[0]['xchan_photo_s']) . '" alt="' . urlencode($r[0]['xchan_name']) . '" /></a> <a href="' . zid($r[0]['xchan_url']) . '" >' . $r[0]['xchan_name'] . '</a>'
));
$o = $tabs;
$o .= $title;
@@ -373,6 +381,8 @@ class Network extends \Zotlabs\Web\Controller {
}
if($conv) {
+ $distinct = ' distinct ';
+ $item_thread_top = '';
$sql_extra .= sprintf(" AND parent IN (SELECT distinct(parent) from item where ( author_xchan like '%s' or item_mentionsme = 1 )) ",
dbesc(protect_sprintf($channel['channel_hash']))
);
@@ -448,7 +458,7 @@ class Network extends \Zotlabs\Web\Controller {
if($nouveau && $load) {
// "New Item View" - show all items unthreaded in reverse created date order
- $items = q("SELECT item.*, item.id AS item_id, received FROM item
+ $items = q("SELECT item.*, item.id AS item_id, received FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
WHERE true $uids $item_normal
@@ -477,11 +487,11 @@ class Network extends \Zotlabs\Web\Controller {
if($load) {
// Fetch a page full of parent items for this page
- $r = q("SELECT distinct item.id AS item_id, $ordering FROM item
+ $r = q("SELECT $distinct item.parent AS item_id FROM item
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
$net_query
- WHERE true $uids $item_normal
- AND item.parent = item.id
+ WHERE true $uids $item_thread_top $item_normal
+ AND item.mid = item.parent_mid
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_nets
$net_query2
diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php
index 2b73fa191..9f2fea802 100644
--- a/Zotlabs/Module/New_channel.php
+++ b/Zotlabs/Module/New_channel.php
@@ -89,9 +89,7 @@ class New_channel extends \Zotlabs\Web\Controller {
change_channel($result['channel']['channel_id']);
- if(! strlen($next_page = get_config('system','workflow_channel_next')))
- $next_page = 'settings';
-
+ $next_page = get_config('system', 'workflow_channel_next', 'profiles');
goaway(z_root() . '/' . $next_page);
}
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index f8399d871..2e86804ac 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -149,13 +149,11 @@ class Ping extends \Zotlabs\Web\Controller {
$pubs = q("SELECT count(id) as total from item
WHERE uid = %d
AND author_xchan != '%s'
- AND obj_type != '%s'
AND item_unseen = 1
AND created > '" . datetime_convert('UTC','UTC',$_SESSION['static_loadtime']) . "'
$item_normal",
intval($sys['channel_id']),
- dbesc(get_observer_hash()),
- dbesc(ACTIVITY_OBJ_FILE)
+ dbesc(get_observer_hash())
);
if($pubs)
@@ -320,12 +318,13 @@ class Ping extends \Zotlabs\Web\Controller {
if(argc() > 1 && (argv(1) === 'network' || argv(1) === 'home')) {
$result = array();
- $use_index = db_use_index('uid_item_unseen');
-
- $r = q("SELECT * FROM item $use_index
- WHERE item_unseen = 1 and uid = %d $item_normal
+ $r = q("SELECT * FROM item
+ WHERE uid = %d
AND author_xchan != '%s'
- ORDER BY created DESC limit 300",
+ AND item_unseen = 1
+ $item_normal
+ ORDER BY created DESC, id
+ LIMIT 300",
intval(local_channel()),
dbesc($ob_hash)
);
@@ -495,9 +494,7 @@ class Ping extends \Zotlabs\Web\Controller {
if($vnotify & (VNOTIFY_NETWORK|VNOTIFY_CHANNEL)) {
- $use_index = db_use_index('uid_item_unseen');
-
- $r = q("SELECT id, item_wall FROM item $use_index
+ $r = q("SELECT id, item_wall FROM item
WHERE item_unseen = 1 and uid = %d
$item_normal
AND author_xchan != '%s'",
diff --git a/Zotlabs/Module/Pubstream.php b/Zotlabs/Module/Pubstream.php
index 2c25e2ce0..16a5fdbba 100644
--- a/Zotlabs/Module/Pubstream.php
+++ b/Zotlabs/Module/Pubstream.php
@@ -196,10 +196,10 @@ class Pubstream extends \Zotlabs\Web\Controller {
}
else {
// Fetch a page full of parent items for this page
- $r = q("SELECT distinct item.id AS item_id, $ordering FROM item
+ $r = q("SELECT item.id AS item_id FROM item
left join abook on item.author_xchan = abook.abook_xchan
$net_query
- WHERE true $uids $item_normal
+ WHERE item_thread_top = 1 $uids $item_normal
AND item.parent = item.id
and (abook.abook_blocked = 0 or abook.abook_flags is null)
$sql_extra3 $sql_extra $sql_nets $net_query2
diff --git a/Zotlabs/Module/Settings/Display.php b/Zotlabs/Module/Settings/Display.php
index e1ea0e3e5..340b3c0bb 100644
--- a/Zotlabs/Module/Settings/Display.php
+++ b/Zotlabs/Module/Settings/Display.php
@@ -21,7 +21,7 @@ class Display {
if(! $theme)
$theme = 'redbasic';
- $mobile_theme = ((x($_POST,'mobile_theme')) ? notags(trim($_POST['mobile_theme'])) : '');
+
$preload_images = ((x($_POST,'preload_images')) ? intval($_POST['preload_images']) : 0);
$channel_menu = ((x($_POST,'channel_menu')) ? intval($_POST['channel_menu']) : 0);
$user_scalable = ((x($_POST,'user_scalable')) ? intval($_POST['user_scalable']) : 0);
@@ -47,11 +47,6 @@ class Display {
if($itemspage > 100)
$itemspage = 100;
- if ($mobile_theme == "---")
- del_pconfig(local_channel(),'system','mobile_theme');
- else {
- set_pconfig(local_channel(),'system','mobile_theme',$mobile_theme);
- }
set_pconfig(local_channel(),'system','preload_images',$preload_images);
set_pconfig(local_channel(),'system','user_scalable',$user_scalable);
@@ -114,10 +109,6 @@ class Display {
$theme = (($existing_theme) ? $existing_theme : $default_theme);
- $default_mobile_theme = get_config('system','mobile_theme');
- if(! $mobile_default_theme)
- $mobile_default_theme = 'none';
-
$allowed_themes_str = get_config('system','allowed_themes');
$allowed_themes_raw = explode(',',$allowed_themes_str);
$allowed_themes = array();
@@ -135,26 +126,19 @@ class Display {
$info = get_theme_info($th);
$compatible = check_plugin_versions($info);
- if(!$compatible) {
- $mobile_themes[$f] = $themes[$f] = sprintf(t('%s - (Incompatible)'), $f);
+ if(! $compatible) {
+ $themes[$f] = sprintf(t('%s - (Incompatible)'), $f);
continue;
}
$is_experimental = file_exists('view/theme/' . $th . '/experimental');
$unsupported = file_exists('view/theme/' . $th . '/unsupported');
- $is_mobile = file_exists('view/theme/' . $th . '/mobile');
$is_library = file_exists('view/theme/'. $th . '/library');
- $mobile_themes['---'] = t("No special theme for mobile devices");
if (!$is_experimental or ($is_experimental && (get_config('experimentals','exp_themes')==1 or get_config('experimentals','exp_themes')===false))){
$theme_name = (($is_experimental) ? sprintf(t('%s - (Experimental)'), $f) : $f);
if (! $is_library) {
- if($is_mobile) {
- $mobile_themes[$f] = $themes[$f] = $theme_name . ' (' . t('mobile') . ')';
- }
- else {
- $mobile_themes[$f] = $themes[$f] = $theme_name;
- }
+ $themes[$f] = $theme_name;
}
}
}
@@ -166,7 +150,6 @@ class Display {
$theme_selected = explode(':', $theme_selected)[0];
}
- $mobile_theme_selected = (!x($_SESSION,'mobile_theme')? $default_mobile_theme : $_SESSION['mobile_theme']);
$preload_images = get_pconfig(local_channel(),'system','preload_images');
$preload_images = (($preload_images===false)? '0': $preload_images); // default if not set: 0
@@ -213,7 +196,6 @@ class Display {
'$theme' => (($themes) ? array('theme', t('Display Theme:'), $theme_selected, '', $themes, 'preview') : false),
'$schema' => array('schema', t('Select scheme'), $existing_schema, '' , $schemas),
- '$mobile_theme' => (($mobile_themes) ? array('mobile_theme', t('Mobile Theme:'), $mobile_theme_selected, '', $mobile_themes, '') : false),
'$preload_images' => array('preload_images', t("Preload images before rendering the page"), $preload_images, t("The subjective page load time will be longer but the page will be ready when displayed"), $yes_no),
'$user_scalable' => array('user_scalable', t("Enable user zoom on mobile devices"), $user_scalable, '', $yes_no),
'$ajaxint' => array('browser_update', t("Update browser every xx seconds"), $browser_update, t('Minimum of 10 seconds, no maximum')),
diff --git a/Zotlabs/Render/Theme.php b/Zotlabs/Render/Theme.php
index 09cc7a4d4..0eebba1ba 100644
--- a/Zotlabs/Render/Theme.php
+++ b/Zotlabs/Render/Theme.php
@@ -8,10 +8,8 @@ use App;
class Theme {
static $system_theme = null;
- static $system_mobile_theme = null;
static $session_theme = null;
- static $session_mobile_theme = null;
/**
* @brief Array with base or fallback themes.
@@ -32,10 +30,6 @@ class Theme {
? \App::$config['system']['theme'] : '');
self::$session_theme = ((isset($_SESSION) && x($_SESSION, 'theme'))
? $_SESSION['theme'] : self::$system_theme);
- self::$system_mobile_theme = ((isset(\App::$config['system']['mobile_theme']))
- ? \App::$config['system']['mobile_theme'] : '');
- self::$session_mobile_theme = ((isset($_SESSION) && x($_SESSION, 'mobile_theme'))
- ? $_SESSION['mobile_theme'] : self::$system_mobile_theme);
$page_theme = null;
@@ -55,30 +49,12 @@ class Theme {
if(array_key_exists('theme', \App::$layout) && \App::$layout['theme'])
$page_theme = \App::$layout['theme'];
- // If the viewer is on a mobile device, ensure that we're using a mobile
- // theme of some kind or whatever the viewer's preference is for mobile
- // viewing (if applicable)
+ $chosen_theme = self::$session_theme;
- if(\App::$is_mobile || \App::$is_tablet) {
- if(isset($_SESSION['show_mobile']) && (! $_SESSION['show_mobile'])) {
- $chosen_theme = self::$session_theme;
- }
- else {
- $chosen_theme = self::$session_mobile_theme;
-
- if($chosen_theme === '' || $chosen_theme === '---' ) {
- // user has selected to have the mobile theme be the same as the normal one
- $chosen_theme = self::$session_theme;
- }
- }
+ if($page_theme) {
+ $chosen_theme = $page_theme;
}
- else {
- $chosen_theme = self::$session_theme;
- if($page_theme) {
- $chosen_theme = $page_theme;
- }
- }
if(array_key_exists('theme_preview', $_GET))
$chosen_theme = $_GET['theme_preview'];
diff --git a/Zotlabs/Widget/Forums.php b/Zotlabs/Widget/Forums.php
index 44d95012f..f65a639ff 100644
--- a/Zotlabs/Widget/Forums.php
+++ b/Zotlabs/Widget/Forums.php
@@ -64,7 +64,8 @@ class Forums {
// There also should be a way to update this via ajax.
for($x = 0; $x < count($r1); $x ++) {
- $r = q("select sum(item_unseen) as unseen from item where owner_xchan = '%s' and uid = %d and item_unseen = 1 $perms_sql ",
+ $r = q("select sum(item_unseen) as unseen from item
+ where uid = %d and owner_xchan = '%s' and item_unseen = 1 $perms_sql ",
dbesc($r1[$x]['xchan_hash']),
intval(local_channel())
);
diff --git a/boot.php b/boot.php
index c4c4dbc5b..184ff6ea2 100755
--- a/boot.php
+++ b/boot.php
@@ -38,7 +38,6 @@ require_once('include/datetime.php');
require_once('include/language.php');
require_once('include/nav.php');
require_once('include/permissions.php');
-require_once('library/Mobile_Detect/Mobile_Detect.php');
require_once('include/features.php');
require_once('include/taxonomy.php');
require_once('include/channel.php');
@@ -51,10 +50,10 @@ require_once('include/attach.php');
require_once('include/bbcode.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
-define ( 'STD_VERSION', '3.1.5' );
+define ( 'STD_VERSION', '3.1.7' );
define ( 'ZOT_REVISION', '1.3' );
-define ( 'DB_UPDATE_VERSION', 1198 );
+define ( 'DB_UPDATE_VERSION', 1200 );
define ( 'PROJECT_BASE', __DIR__ );
@@ -788,9 +787,7 @@ class App {
public static $theme_info = array();
public static $is_sys = false;
public static $nav_sel;
- public static $is_mobile = false;
- public static $is_tablet = false;
- public static $comanche;
+ public static $comanche;
public static $channel_links;
@@ -961,14 +958,6 @@ class App {
self::$pager['total'] = 0;
/*
- * Detect mobile devices
- */
-
- $mobile_detect = new Mobile_Detect();
- self::$is_mobile = $mobile_detect->isMobile();
- self::$is_tablet = $mobile_detect->isTablet();
-
- /*
* register template engines
*/
@@ -1014,7 +1003,7 @@ class App {
self::$baseurl = $url;
- if($parsed) {
+ if($parsed !== false) {
self::$scheme = $parsed['scheme'];
self::$hostname = $parsed['host'];
@@ -1450,58 +1439,10 @@ function check_config() {
$x = new \Zotlabs\Lib\DB_Upgrade(DB_UPDATE_VERSION);
- /**
- *
- * Synchronise plugins:
- *
- * App::$config['system']['addon'] contains a comma-separated list of names
- * of plugins/addons which are used on this system.
- * Go through the database list of already installed addons, and if we have
- * an entry, but it isn't in the config list, call the unload procedure
- * and mark it uninstalled in the database (for now we'll remove it).
- * Then go through the config list and if we have a plugin that isn't installed,
- * call the install procedure and add it to the database.
- *
- */
-
- $r = q("SELECT * FROM addon WHERE installed = 1");
- if($r)
- $installed = $r;
- else
- $installed = array();
-
- $plugins = get_config('system', 'addon');
- $plugins_arr = array();
-
- if($plugins)
- $plugins_arr = explode(',', str_replace(' ', '', $plugins));
-
- App::$plugins = $plugins_arr;
-
- $installed_arr = array();
-
- if(count($installed)) {
- foreach($installed as $i) {
- if(! in_array($i['aname'], $plugins_arr)) {
- unload_plugin($i['aname']);
- }
- else {
- $installed_arr[] = $i['aname'];
- }
- }
- }
-
- if(count($plugins_arr)) {
- foreach($plugins_arr as $p) {
- if(! in_array($p, $installed_arr)) {
- load_plugin($p);
- }
- }
- }
+ plugins_sync();
load_hooks();
-
check_for_new_perms();
check_cron_broken();
@@ -2246,22 +2187,6 @@ function construct_page() {
}
}
- if(App::$is_mobile || App::$is_tablet) {
- if(isset($_SESSION['show_mobile']) && !$_SESSION['show_mobile']) {
- $link = z_root() . '/toggle_mobile?f=&address=' . curPageURL();
- }
- else {
- $link = z_root() . '/toggle_mobile?f=&off=1&address=' . curPageURL();
- }
- if ((isset($_SESSION) && $_SESSION['mobile_theme'] !='' && $_SESSION['mobile_theme'] !='---' ) ||
- (isset(App::$config['system']['mobile_theme']) && !isset($_SESSION['mobile_theme']))) {
- App::$page['footer'] .= replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array(
- '$toggle_link' => $link,
- '$toggle_text' => t('toggle mobile')
- ));
- }
- }
-
$page = App::$page;
$profile = App::$profile;
diff --git a/doc/member/member_guide.bb b/doc/member/member_guide.bb
index 6286e74a3..10ea4db57 100644
--- a/doc/member/member_guide.bb
+++ b/doc/member/member_guide.bb
@@ -345,16 +345,18 @@ If the person mentioned is in the list of recipients for the post, they will rec
[h4]Deliverable Mentions[/h4]
-Some connections in the mention auto-complete box behave differently than others. If you mention a channel which provides "re-delivery of mentions" it will also send the post to all of that channel's default delivery connections. This is how one posts to "forums". The auto-complete box will provide two entries for these channels, one will mention just the channel. The other will invoke re-delivery and be listed as the channel's "network".
+The [b]![/b] character designates a deliverable mention to a forum or special channel which allows "re-delivery of mentions".
[code]
@Gardening - mention the Gardening forum
[/code]
[code]
-@Gardening+ - mention the Gardening Forum and also post to the Gardening "network" (e.g. all the forum members; if you have permission to do so)
+!Gardening - mention the Gardening Forum and also post to the Gardening "network" (e.g. send to all the forum members; if you have permission to do so)
[/code]
+Note: In previous releases, forums were delivered by using @forum+ with a plus sign at the end. This mechanism is still used occasionally but is deprecated and !forum is now preferred.
+
[h4]Private Mentions[/h4]
If you wish to restrict a post to a single person or a number of people, you can do this by selecting channels or privacy groups from the privacy tool. You can also just tag them with a privacy tag. A privacy tag is a name preceded by the two characters @! - and in addition to tagging these channels, will also change the privacy permissions of the post to only include them. You can have more than one privacy tag, for instance @!bob and @!linda will send the post only to Bob and Linda. This mechanism over-rides the privacy selector.
@@ -369,7 +371,7 @@ Topical tags are indicated by preceding the tag name with the # character. This
Topical tags are also not linked if they are purely numeric, e.g. #1. If you wish to use a numeric hashtag, please add some descriptive text such as #2012-elections.
[h4]Bookmarks[/h4]
-Bookmarks indicate a link which can be saved to your bookmark folder. They use the sequence #^ followed by the link. Often these are generated automatically. If the 'bookmarker' addon is installed, this sequence will be converted to a bookmark icon when viewing the post or comment online and clicking the icon will save the bookmark. If the bookmarker addon is not installed, the post 'dropdown menu' contains a link for saving the bookmark or bookmarks.
+Bookmarks indicate a link which can be saved to your bookmark folder. They use the sequence #^ followed by the link. Often these are generated automatically. If the 'bookmarker' addon is installed, this sequence will be converted to a bookmark icon when viewing the post or comment online, and clicking the icon will save the bookmark. If the bookmarker addon is not installed, the post 'dropdown menu' contains a link for saving the bookmark or bookmarks.
[h4]Spaces in Tags and Mentions[/h4]
Where possible please use the auto-complete window to select tag and mention recipients, because it will generate a coded tag which uniquely identifies one channel. Names are sometimes ambiguous. However, you can "manually" tag a channel by matching the channel name or address.
diff --git a/images/video_poster.jpg b/images/video_poster.jpg
new file mode 100644
index 000000000..e4fc3b2da
--- /dev/null
+++ b/images/video_poster.jpg
Binary files differ
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index 4e203074b..bada3e528 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -5,104 +5,9 @@
* @package acl_selectors
*/
-/**
- * @brief
- *
- * @param string $selname
- * @param string $selclass
- * @param mixed $preselected
- * @param number $size
- * @return string
- */
-function group_select($selname, $selclass, $preselected = false, $size = 4) {
-
- $o = '';
-
- $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\">\r\n";
-
- $r = q("SELECT * FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
- intval(local_channel())
- );
-
-
- $arr = array('group' => $r, 'entry' => $o);
-
- // e.g. 'network_pre_group_deny', 'profile_pre_group_allow'
-
- call_hooks(App::$module . '_pre_' . $selname, $arr);
-
- if($r) {
- foreach($r as $rr) {
- if((is_array($preselected)) && in_array($rr['id'], $preselected))
- $selected = " selected=\"selected\" ";
- else
- $selected = '';
- $trimmed = mb_substr($rr['gname'],0,12);
-
- $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}\" >$trimmed</option>\r\n";
- }
-
- }
- $o .= "</select>\r\n";
-
- call_hooks(App::$module . '_post_' . $selname, $o);
-
- return $o;
-}
-
-function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false, $tabindex = null) {
-
- $o = '';
-
- // When used for private messages, we limit correspondence to mutual DFRN/Friendica friends and the selector
- // to one recipient. By default our selector allows multiple selects amongst all contacts.
-
- $sql_extra = '';
-
- $tabindex = ($tabindex > 0 ? 'tabindex="$tabindex"' : '');
-
- if($privmail)
- $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" $tabindex >\r\n";
- else
- $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex>\r\n";
-
- $r = q("SELECT abook_id, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash
- where abook_self = 0 and abook_channel = %d
- $sql_extra
- ORDER BY xchan_name ASC",
- intval(local_channel())
- );
-
-
- $arr = array('contact' => $r, 'entry' => $o);
-
- // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
-
- call_hooks(App::$module . '_pre_' . $selname, $arr);
-
- if($r) {
- foreach($r as $rr) {
- if((is_array($preselected)) && in_array($rr['id'], $preselected))
- $selected = ' selected="selected" ';
- else
- $selected = '';
-
- $trimmed = mb_substr($rr['xchan_name'], 0, 20);
-
- $o .= "<option value=\"{$rr['abook_id']}\" $selected title=\"{$rr['xchan_name']}|{$rr['xchan_url']}\" >$trimmed</option>\r\n";
- }
- }
-
- $o .= "</select>\r\n";
-
- call_hooks(App::$module . '_post_' . $selname, $o);
-
- return $o;
-}
-
function fixacl(&$item) {
- $item = str_replace(array('<', '>'), array('', ''), $item);
+ $item = str_replace( [ '<', '>' ], [ '', '' ], $item);
}
/**
diff --git a/include/auth.php b/include/auth.php
index 78be32bf4..6f5e58361 100644
--- a/include/auth.php
+++ b/include/auth.php
@@ -261,6 +261,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']))));
}
elseif($verify) {
$atoken = $verify['xchan'];
diff --git a/include/bbcode.php b/include/bbcode.php
index 2b8274c0f..0c85a0a4e 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -108,7 +108,11 @@ function tryzrlvideo($match) {
if($zrl)
$link = zid($link);
- return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
+ $static_link = get_config('system','video_default_poster','images/video_poster.jpg');
+ if($static_link)
+ $poster = 'poster="' . escape_tags($static_link) . '" ' ;
+
+ return '<video ' . $poster . ' controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
}
// [noparse][i]italic[/i][/noparse] turns into
diff --git a/include/datetime.php b/include/datetime.php
index 0fcd957be..1e9a1fa51 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -93,16 +93,6 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
return $d->format($fmt);
}
- // Slight hackish adjustment so that 'zero' datetime actually returns what is intended
- // otherwise we end up with -0001-11-30 ...
- // add 32 days so that we at least get year 00, and then hack around the fact that
- // months and days always start with 1.
-
-// if(substr($s,0,10) == '0000-00-00') {
-// $d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC'));
-// return str_replace('1', '0', $d->format($fmt));
-// }
-
try {
$from_obj = new DateTimeZone($from);
} catch(Exception $e) {
@@ -135,70 +125,20 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
*/
function dob($dob) {
- list($year, $month, $day) = sscanf($dob, '%4d-%2d-%2d');
- $f = get_config('system', 'birthday_input_format');
- if (! $f)
- $f = 'ymd';
-
if ($dob === '0000-00-00')
$value = '';
else
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
- $o = replace_macros(get_markup_template("field_input.tpl"), array('$field' => array(
- 'dob',
- t('Birthday'),
- $value,
- ((intval($value)) ? t('Age: ') . age($value,App::$user['timezone'],App::$user['timezone']) : ''),
- '',
- 'placeholder="' . t('YYYY-MM-DD or MM-DD') .'"'
- )));
-
+ $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') .'"' ]
+ ]);
-// if ($dob && $dob != '0000-00-00')
-// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
-// else
-// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),false,'dob');
return $o;
}
/**
- * @brief Returns a date selector.
- *
- * @see datetimesel()
- * @param string $format
- * format string, e.g. 'ymd' or 'mdy'. Not currently supported
- * @param DateTime $min
- * unix timestamp of minimum date
- * @param DateTime $max
- * unix timestap of maximum date
- * @param DateTime $default
- * unix timestamp of default date
- * @param string $id
- * id and name of datetimepicker (defaults to "datetimepicker")
- */
-function datesel($format, $min, $max, $default, $id = 'datepicker') {
- return datetimesel($format, $min, $max, $default, '', $id, true, false, '', '');
-}
-
-/**
- * @brief Returns a time selector.
- *
- * @param string $format
- * format string, e.g. 'ymd' or 'mdy'. Not currently supported
- * @param string $h
- * already selected hour
- * @param string $m
- * already selected minute
- * @param string $id
- * id and name of datetimepicker (defaults to "timepicker")
- */
-function timesel($format, $h, $m, $id='timepicker') {
- return datetimesel($format, new DateTime(), new DateTime(), new DateTime("$h:$m"), '', $id, false, true);
-}
-
-/**
* @brief Returns a datetime selector.
*
* @param string $format
@@ -449,12 +389,7 @@ function cal($y = 0, $m = 0, $links = false, $class='') {
// month table - start at 1 to match human usage.
- $mtab = array(' ',
- 'January','February','March',
- 'April','May','June',
- 'July','August','September',
- 'October','November','December'
- );
+ $mtab = [ ' ', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
$thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
$thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m');
@@ -463,7 +398,7 @@ function cal($y = 0, $m = 0, $links = false, $class='') {
if (! $m)
$m = intval($thismonth);
- $dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
+ $dn = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
$f = get_first_dim($y, $m);
$l = get_dim($y, $m);
$d = 1;
@@ -569,17 +504,17 @@ function update_birthdays() {
if (! perm_is_allowed($rr['abook_channel'], $rr['xchan_hash'], 'send_stream'))
continue;
- $ev = array();
- $ev['uid'] = $rr['abook_channel'];
- $ev['account'] = $rr['abook_account'];
- $ev['event_xchan'] = $rr['xchan_hash'];
- $ev['dtstart'] = datetime_convert('UTC', 'UTC', $rr['abook_dob']);
- $ev['dtend'] = datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day ');
- $ev['adjust'] = intval(feature_enabled($rr['abook_channel'],'smart_birthdays'));
- $ev['summary'] = sprintf( t('%1$s\'s birthday'), $rr['xchan_name']);
- $ev['description'] = sprintf( t('Happy Birthday %1$s'),
- '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]') ;
- $ev['etype'] = 'birthday';
+ $ev = [
+ 'uid' => $rr['abook_channel'],
+ 'account' => $rr['abook_account'],
+ 'event_xchan' => $rr['xchan_hash'],
+ 'dtstart' => datetime_convert('UTC', 'UTC', $rr['abook_dob']),
+ 'dtend' => datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day '),
+ 'adjust' => intval(feature_enabled($rr['abook_channel'],'smart_birthdays')),
+ 'summary' => sprintf( t('%1$s\'s birthday'), $rr['xchan_name']),
+ 'description' => sprintf( t('Happy Birthday %1$s'), '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]'),
+ 'etype' => 'birthday',
+ ];
$z = event_store_event($ev);
if ($z) {
diff --git a/include/feedutils.php b/include/feedutils.php
index 5e48cb1ee..504f65092 100644
--- a/include/feedutils.php
+++ b/include/feedutils.php
@@ -15,15 +15,6 @@
*/
function get_public_feed($channel, $params) {
-/* $type = 'xml';
- $begin = NULL_DATE;
- $end = '';
- $start = 0;
- $records = 40;
- $direction = 'desc';
- $pages = 0;
-*/
-
if(! $params)
$params = [];
@@ -106,23 +97,15 @@ function get_feed_for($channel, $observer_hash, $params) {
$owner = atom_render_author('zot:owner',$channel);
$atom .= replace_macros($feed_template, array(
- '$version' => xmlify(Zotlabs\Lib\System::get_project_version()),
- '$red' => xmlify(Zotlabs\Lib\System::get_platform_name()),
- '$feed_id' => xmlify($channel['xchan_url']),
- '$feed_title' => xmlify($channel['channel_name']),
- '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
- '$author' => $feed_author,
- '$owner' => $owner,
- '$name' => xmlify($channel['channel_name']),
- '$profile_page' => xmlify($channel['xchan_url']),
- '$mimephoto' => xmlify($channel['xchan_photo_mimetype']),
- '$photo' => xmlify($channel['xchan_photo_l']),
- '$thumb' => xmlify($channel['xchan_photo_m']),
- '$picdate' => '',
- '$uridate' => '',
- '$namdate' => '',
- '$birthday' => '',
- '$community' => '',
+ '$version' => xmlify(Zotlabs\Lib\System::get_project_version()),
+ '$generator' => xmlify(Zotlabs\Lib\System::get_platform_name()),
+ '$generator_uri' => 'https://hubzilla.org',
+ '$feed_id' => xmlify($channel['xchan_url']),
+ '$feed_title' => xmlify($channel['channel_name']),
+ '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
+ '$author' => $feed_author,
+ '$owner' => $owner,
+ '$profile_page' => xmlify($channel['xchan_url']),
));
@@ -270,19 +253,18 @@ function construct_activity_target($item) {
return '';
}
+
/**
- * @brief Return an array with a parsed atom item.
+ * @brief Return an array with a parsed atom author.
*
* @param SimplePie $feed
- * @param array $item
- * @param[out] array $author
- * @return array Associative array with the parsed item data
+ * @param SimplePie $item
+ * @return array $author
*/
-function get_atom_elements($feed, $item, &$author) {
- require_once('include/html2bbcode.php');
+function get_atom_author($feed, $item) {
- $res = array();
+ $author = [];
$found_author = $item->get_author();
if($found_author) {
@@ -307,52 +289,6 @@ function get_atom_elements($feed, $item, &$author) {
if(substr($author['author_link'],-1,1) == '/')
$author['author_link'] = substr($author['author_link'],0,-1);
- $res['mid'] = normalise_id(unxmlify($item->get_id()));
- $res['title'] = unxmlify($item->get_title());
- $res['body'] = unxmlify($item->get_content());
- $res['plink'] = unxmlify($item->get_link(0));
- $res['item_rss'] = 1;
-
-
- $summary = unxmlify($item->get_description(true));
-
- // removing the content of the title if its identically to the body
- // This helps with auto generated titles e.g. from tumblr
-
- if (title_is_body($res['title'], $res['body']))
- $res['title'] = "";
-
- if($res['plink'])
- $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
- else
- $base_url = '';
-
-
- $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published');
- if($rawcreated)
- $res['created'] = unxmlify($rawcreated[0]['data']);
-
- $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated');
- if($rawedited)
- $res['edited'] = unxmlify($rawedited[0]['data']);
-
- if((x($res,'edited')) && (! (x($res,'created'))))
- $res['created'] = $res['edited'];
-
- if(! $res['created'])
- $res['created'] = $item->get_date('c');
-
- if(! $res['edited'])
- $res['edited'] = $item->get_date('c');
-
- $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
-
- // select between supported verbs
-
- if($rawverb) {
- $res['verb'] = unxmlify($rawverb[0]['data']);
- }
-
// look for a photo. We should check media size and find the best one,
// but for now let's just find any author photo
@@ -431,6 +367,112 @@ function get_atom_elements($feed, $item, &$author) {
}
}
+ $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
+ if(! $rawowner)
+ $rawowner = $item->get_item_tags(NAMESPACE_ZOT, 'owner');
+
+ if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
+ $author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
+ elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
+ $author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
+ if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
+ $author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
+ elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
+ $author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
+
+ if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
+ $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
+
+ foreach($base as $link) {
+ if(!x($author, 'owner_photo') || ! $author['owner_photo']) {
+ if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
+ $author['owner_photo'] = unxmlify($link['attribs']['']['href']);
+ }
+ }
+ }
+
+ // build array to pass to hook
+ $arr = [
+ 'feed' => $feed,
+ 'item' => $item,
+ 'author' => $author
+ ];
+ /**
+ * @hooks parse_atom
+ * * \e SimplePie \b feed - The original SimplePie feed
+ * * \e SimplePie \b item
+ * * \e array \b result - the result array that will also get returned
+ */
+ call_hooks('parse_atom_author', $arr);
+
+ logger('author: ' . print_r($arr['author'], true), LOGGER_DATA);
+
+ return $arr['author'];
+}
+
+
+/**
+ * @brief Return an array with a parsed atom item.
+ *
+ * @param SimplePie $feed
+ * @param SimplePie $item
+ * @param[out] array $author
+ * @return array Associative array with the parsed item data
+ */
+
+function get_atom_elements($feed, $item) {
+
+ require_once('include/html2bbcode.php');
+
+ $res = array();
+
+
+ $res['mid'] = normalise_id(unxmlify($item->get_id()));
+ $res['title'] = unxmlify($item->get_title());
+ $res['body'] = unxmlify($item->get_content());
+ $res['plink'] = unxmlify($item->get_link(0));
+ $res['item_rss'] = 1;
+
+
+ $summary = unxmlify($item->get_description(true));
+
+ // removing the content of the title if its identically to the body
+ // This helps with auto generated titles e.g. from tumblr
+
+ if (title_is_body($res['title'], $res['body']))
+ $res['title'] = "";
+
+ if($res['plink'])
+ $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
+ else
+ $base_url = '';
+
+
+ $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published');
+ if($rawcreated)
+ $res['created'] = unxmlify($rawcreated[0]['data']);
+
+ $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated');
+ if($rawedited)
+ $res['edited'] = unxmlify($rawedited[0]['data']);
+
+ if((x($res,'edited')) && (! (x($res,'created'))))
+ $res['created'] = $res['edited'];
+
+ if(! $res['created'])
+ $res['created'] = $item->get_date('c');
+
+ if(! $res['edited'])
+ $res['edited'] = $item->get_date('c');
+
+ $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
+
+ // select between supported verbs
+
+ if($rawverb) {
+ $res['verb'] = unxmlify($rawverb[0]['data']);
+ }
+
$rawcnv = $item->get_item_tags(NAMESPACE_OSTATUS, 'conversation');
if($rawcnv) {
// new style
@@ -588,29 +630,6 @@ function get_atom_elements($feed, $item, &$author) {
$res['created'] = datetime_convert('UTC','UTC',$res['created']);
$res['edited'] = datetime_convert('UTC','UTC',$res['edited']);
- $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
- if(! $rawowner)
- $rawowner = $item->get_item_tags(NAMESPACE_ZOT, 'owner');
-
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
- $author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
- elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
- $author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
- $author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
- elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
- $author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
-
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
- $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
-
- foreach($base as $link) {
- if(!x($author, 'owner_photo') || ! $author['owner_photo']) {
- if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
- $author['owner_photo'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
$rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point');
if($rawgeo)
@@ -773,19 +792,16 @@ function get_atom_elements($feed, $item, &$author) {
$arr = [
'feed' => $feed,
'item' => $item,
- 'author' => $author,
'result' => $res
];
/**
* @hooks parse_atom
* * \e SimplePie \b feed - The original SimplePie feed
- * * \e array \b item
- * * \e array \b author
+ * * \e SimplePie \b item
* * \e array \b result - the result array that will also get returned
*/
call_hooks('parse_atom', $arr);
- logger('author: ' .print_r($arr['author'], true), LOGGER_DATA);
logger('result: ' .print_r($arr['result'], true), LOGGER_DATA);
return $arr['result'];
@@ -1074,8 +1090,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Have we seen it? If not, import it.
- $author = array();
- $datarray = get_atom_elements($feed,$item,$author);
+ $author = get_atom_author($feed,$item);
+ $datarray = get_atom_elements($feed,$item);
if(! $datarray['mid'])
continue;
@@ -1327,8 +1343,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Head post of a conversation. Have we seen it? If not, import it.
- $author = array();
- $datarray = get_atom_elements($feed,$item,$author);
+ $author = get_atom_author($feed,$item);
+ $datarray = get_atom_elements($feed,$item);
if(! $datarray['mid'])
continue;
@@ -1530,11 +1546,11 @@ function normalise_id($id) {
*/
function process_salmon_feed($xml, $importer) {
- $ret = array();
+ $ret = [];
if(! strlen($xml)) {
logger('process_feed: empty input');
- return;
+ return $ret;
}
$feed = new SimplePie();
@@ -1548,8 +1564,10 @@ function process_salmon_feed($xml, $importer) {
$feed->init();
- if($feed->error())
+ if($feed->error()) {
logger('Error parsing XML: ' . $feed->error());
+ return $ret;
+ }
$permalink = $feed->get_permalink();
@@ -1576,16 +1594,13 @@ function process_salmon_feed($xml, $importer) {
if($is_reply)
$ret['parent_mid'] = $parent_mid;
- $ret['author'] = array();
-
- $datarray = get_atom_elements($feed, $item, $ret['author']);
+ $ret['author'] = get_atom_author($feed,$item);
+ $ret['item'] = get_atom_elements($feed,$item);
// reset policies which are restricted by default for RSS connections
// This item is likely coming from GNU-social via salmon and allows public interaction
- $datarray['public_policy'] = '';
- $datarray['comment_policy'] = 'authenticated';
-
- $ret['item'] = $datarray;
+ $ret['item']['public_policy'] = '';
+ $ret['item']['comment_policy'] = 'authenticated';
}
}
@@ -1843,10 +1858,24 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
create_export_photo_body($item);
- if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
- $body = fix_private_photos($item['body'],$owner['uid'],$item,$cid);
+ // provide separate summary and content unless compat is true; as summary represents a content-warning on some networks
+
+ $matches = false;
+ if(preg_match('|\[summary\](.*?)\[/summary\]|ism',$item['body'],$matches))
+ $summary = $matches[1];
else
- $body = $item['body'];
+ $summary = '';
+
+ $body = $item['body'];
+
+ if($summary)
+ $body = preg_replace('|^(.*?)\[summary\](.*?)\[/summary\](.*?)$|ism','$1$3',$item['body']);
+
+ if($compat)
+ $summary = '';
+
+ if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
+ $body = fix_private_photos($body,$owner['uid'],$item,$cid);
if($compat) {
$compat_photos = compat_photos_list($body);
@@ -1887,6 +1916,8 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
}
else {
$o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
+ if($summary)
+ $o .= '<summary type="' . $type . '" >' . xmlify(prepare_text($summary,$item['mimetype'])) . '</summary>' . "\r\n";
$o .= '<content type="' . $type . '" >' . xmlify(prepare_text($body,$item['mimetype'])) . '</content>' . "\r\n";
}
diff --git a/include/hubloc.php b/include/hubloc.php
index 0daa5908c..0d1a2e560 100644
--- a/include/hubloc.php
+++ b/include/hubloc.php
@@ -257,6 +257,24 @@ function hubloc_mark_as_down($posturl) {
}
+/**
+ * @brief return comma separated string of non-dead clone locations (net addresses) for a given netid
+ *
+ * @param string $netid network identity (typically xchan_hash or hubloc_hash)
+ * @return string
+ */
+
+function locations_by_netid($netid) {
+
+ $locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_deleted = 0 and site_dead = 0",
+ dbesc($netid)
+ );
+
+ return array_elm_to_str($locs,'location',', ');
+
+}
+
+
function ping_site($url) {
diff --git a/include/items.php b/include/items.php
index b12ad1d85..c7206458e 100755
--- a/include/items.php
+++ b/include/items.php
@@ -390,7 +390,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
$arr['comment_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'));
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
- $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
+ $arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']),0,190);
}
diff --git a/include/plugin.php b/include/plugin.php
index 67157dee7..f452d8342 100755
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -179,6 +179,66 @@ function reload_plugins() {
}
+function plugins_installed_list() {
+
+ $r = q("select * from addon where installed = 1 order by aname asc");
+ return(($r) ? ids_to_array($r,'aname') : []);
+}
+
+
+function plugins_sync() {
+
+ /**
+ *
+ * Synchronise plugins:
+ *
+ * App::$config['system']['addon'] contains a comma-separated list of names
+ * of plugins/addons which are used on this system.
+ * Go through the database list of already installed addons, and if we have
+ * an entry, but it isn't in the config list, call the unload procedure
+ * and mark it uninstalled in the database (for now we'll remove it).
+ * Then go through the config list and if we have a plugin that isn't installed,
+ * call the install procedure and add it to the database.
+ *
+ */
+
+ $installed = plugins_installed_list();
+
+ $plugins = get_config('system', 'addon', '');
+
+ $plugins_arr = explode(',', $plugins);
+
+ // array_trim is in include/text.php
+
+ if(! array_walk($plugins_arr,'array_trim'))
+ return;
+
+ App::$plugins = $plugins_arr;
+
+ $installed_arr = [];
+
+ if(count($installed)) {
+ foreach($installed as $i) {
+ if(! in_array($i, $plugins_arr)) {
+ unload_plugin($i);
+ }
+ else {
+ $installed_arr[] = $i;
+ }
+ }
+ }
+
+ if(count($plugins_arr)) {
+ foreach($plugins_arr as $p) {
+ if(! in_array($p, $installed_arr)) {
+ load_plugin($p);
+ }
+ }
+ }
+
+}
+
+
/**
* @brief Get a list of non hidden addons.
*
diff --git a/include/text.php b/include/text.php
index 8ec6ebace..35a367d43 100644
--- a/include/text.php
+++ b/include/text.php
@@ -2160,6 +2160,35 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
}
/**
+ * @brief array_elm_to_str($arr,$elm,$delim = ',') extract unique individual elements from an array of arrays and return them as a string separated by a delimiter
+ * similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option
+ * empty elements (evaluated after trim()) are ignored.
+ * @param $arr array
+ * @param $elm array key to extract from sub-array
+ * @param $delim string default ','
+ * @returns string
+ */
+
+function array_elm_to_str($arr,$elm,$delim = ',') {
+
+ $tmp = [];
+ if($arr && is_array($arr)) {
+ foreach($arr as $x) {
+ if(is_array($x) && array_key_exists($elm,$x)) {
+ $z = trim($x[$elm]);
+ if(($z) && (! in_array($z,$tmp))) {
+ $tmp[] = $z;
+ }
+ }
+ }
+ }
+ return implode($delim,$tmp);
+}
+
+
+
+
+/**
* @brief Fetches xchan and hubloc data for an array of items with only an
* author_xchan and owner_xchan.
*
@@ -3261,3 +3290,5 @@ function purify_filename($s) {
return '';
return $s;
}
+
+
diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql
index 673e4cd75..ea13e0de6 100644
--- a/install/schema_mysql.sql
+++ b/install/schema_mysql.sql
@@ -644,7 +644,6 @@ CREATE TABLE IF NOT EXISTS `item` (
`item_pending_remove` tinyint(1) NOT NULL DEFAULT 0 ,
`item_blocked` tinyint(1) NOT NULL DEFAULT 0 ,
PRIMARY KEY (`id`),
- KEY `uid` (`uid`),
KEY `parent` (`parent`),
KEY `created` (`created`),
KEY `edited` (`edited`),
@@ -690,14 +689,8 @@ CREATE TABLE IF NOT EXISTS `item` (
KEY `item_verified` (`item_verified`),
KEY `item_retained` (`item_retained`),
KEY `item_rss` (`item_rss`),
- KEY `item_deleted` (`item_deleted`),
- KEY `item_type` (`item_type`),
- KEY `item_hidden` (`item_hidden`),
KEY `item_consensus` (`item_consensus`),
- KEY `item_unpublished` (`item_unpublished`),
- KEY `item_delayed` (`item_delayed`),
- KEY `item_pending_remove` (`item_pending_remove`),
- KEY `item_blocked` (`item_blocked`)
+ KEY `item_type` (`item_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `item_id` (
diff --git a/install/update.php b/install/update.php
index f7b9b03ed..ceaccdfa3 100644
--- a/install/update.php
+++ b/install/update.php
@@ -1,6 +1,6 @@
<?php
-define( 'UPDATE_VERSION' , 1198 );
+define( 'UPDATE_VERSION' , 1200 );
/**
*
@@ -3070,3 +3070,32 @@ function update_r1197() {
return UPDATE_SUCCESS;
}
+
+function update_r1198() {
+
+ if(ACTIVE_DBTYPE == DBTYPE_MYSQL) {
+ $r = q("ALTER TABLE item
+ DROP INDEX item_blocked,
+ DROP INDEX item_unpublished,
+ DROP INDEX item_deleted,
+ DROP INDEX item_delayed,
+ DROP INDEX item_hidden,
+ DROP INDEX item_pending_remove,
+ DROP INDEX item_type
+ ");
+ }
+
+ return UPDATE_SUCCESS;
+}
+
+function update_r1199() {
+
+ if(ACTIVE_DBTYPE == DBTYPE_MYSQL) {
+ $r = q("ALTER TABLE item
+ DROP INDEX uid,
+ ADD INDEX (item_type)
+ ");
+ }
+
+ return UPDATE_SUCCESS;
+}
diff --git a/library/Mobile_Detect/Mobile_Detect.php b/library/Mobile_Detect/Mobile_Detect.php
deleted file mode 100644
index 4b8c9fecb..000000000
--- a/library/Mobile_Detect/Mobile_Detect.php
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-/**
- * Mobile Detect
- * $Id: Mobile_Detect.php 49 2012-06-06 20:46:30Z serbanghita@gmail.com $
- *
- * @usage require_once 'Mobile_Detect.php';
- * $detect = new Mobile_Detect();
- * $detect->isMobile() or $detect->isTablet()
- *
- * For more specific usage see the documentation navigate to:
- * http://code.google.com/p/php-mobile-detect/wiki/Mobile_Detect
- *
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-class Mobile_Detect {
-
- protected $detectionRules;
- protected $userAgent = null;
- protected $accept = null;
- // Assume the visitor has a desktop environment.
- protected $isMobile = false;
- protected $isTablet = false;
- protected $phoneDeviceName = null;
- protected $tabletDevicename = null;
- protected $operatingSystemName = null;
- protected $userAgentName = null;
- // List of mobile devices (phones)
- protected $phoneDevices = array(
- 'iPhone' => '(iPhone.*Mobile|iPod|iTunes)',
- 'BlackBerry' => 'BlackBerry|rim[0-9]+',
- 'HTC' => 'HTC|HTC.*(6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT',
- 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus',
- 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35',
- 'Motorola' => '\bDroid\b.*Build|DROIDX|HRI39|MOT\-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT909|XT910|XT912|XT928',
- 'Samsung' => 'Samsung|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9300 |GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-P6810|GT-P7100|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100',
- 'Sony' => 'E10i|SonyEricsson|SonyEricssonLT15iv',
- 'Asus' => 'Asus.*Galaxy',
- 'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.
- 'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
- 'GenericPhone' => '(mmp|pocket|psp|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|wap|nokia|Series40|Series60|S60|SonyEricsson|N900|PPC;|MAUI.*WAP.*Browser|LG-P500)'
- );
- // List of tablet devices.
- protected $tabletDevices = array(
- 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
- 'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.
- 'Kindle' => 'Kindle|Silk.*Accelerated',
- 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|GT-P1000|GT-P1010|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P1000|GT-P3100|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7300|GT-P7320|GT-P7500|GT-P7510|GT-P7511',
- 'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',
- 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
- 'AsusTablet' => 'Transformer|TF101',
- 'NookTablet' => 'NookColor|nook browser|BNTV250A|LogicPD Zoom2',
- 'AcerTablet' => 'Android.*\b(A100|A101|A200|A500|A501|A510|W500|W500P|W501|W501P)\b',
- 'YarvikTablet' => 'Android.*(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468)',
- 'GenericTablet' => 'Tablet(?!.*PC)|ViewPad7|LG-V909|MID7015|BNTV250A|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b',
- );
- // List of mobile Operating Systems.
- protected $operatingSystems = array(
- 'AndroidOS' => '(android.*mobile|android(?!.*mobile))',
- 'BlackBerryOS' => '(blackberry|rim tablet os)',
- 'PalmOS' => '(avantgo|blazer|elaine|hiptop|palm|plucker|xiino)',
- 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|\bS60\b',
- 'WindowsMobileOS' => 'IEMobile|Windows Phone|Windows CE.*(PPC|Smartphone)|MSIEMobile|Window Mobile|XBLWP7',
- 'iOS' => '(iphone|ipod|ipad)',
- 'FlashLiteOS' => '',
- 'JavaOS' => '',
- 'NokiaOS' => '',
- 'webOS' => '',
- 'badaOS' => '\bBada\b',
- 'BREWOS' => '',
- );
- // List of mobile User Agents.
- protected $userAgents = array(
- 'Chrome' => '\bCrMo\b|Chrome\/[.0-9]* Mobile',
- 'Dolfin' => '\bDolfin\b',
- 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera',
- 'Skyfire' => 'skyfire',
- 'IE' => 'IEMobile|MSIEMobile',
- 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
- 'Bolt' => 'bolt',
- 'TeaShark' => 'teashark',
- 'Blazer' => 'Blazer',
- 'Safari' => 'Mobile.*Safari|Safari.*Mobile',
- 'Midori' => 'midori',
- 'GenericBrowser' => 'NokiaBrowser|OviBrowser|SEMC.*Browser'
- );
-
- function __construct(){
-
- // Merge all rules together.
- $this->detectionRules = array_merge(
- $this->phoneDevices,
- $this->tabletDevices,
- $this->operatingSystems,
- $this->userAgents
- );
- $this->userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
- $this->accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null;
-
- if (
- isset($_SERVER['HTTP_X_WAP_PROFILE']) ||
- isset($_SERVER['HTTP_X_WAP_CLIENTID']) ||
- isset($_SERVER['HTTP_WAP_CONNECTION']) ||
- isset($_SERVER['HTTP_PROFILE']) ||
- isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA']) || // Reported by Nokia devices (eg. C3)
- isset($_SERVER['HTTP_X_NOKIA_IPADDRESS']) ||
- isset($_SERVER['HTTP_X_NOKIA_GATEWAY_ID']) ||
- isset($_SERVER['HTTP_X_ORANGE_ID']) ||
- isset($_SERVER['HTTP_X_VODAFONE_3GPDPCONTEXT']) ||
- isset($_SERVER['HTTP_X_HUAWEI_USERID']) ||
- isset($_SERVER['HTTP_UA_OS']) || // Reported by Windows Smartphones
- (isset($_SERVER['HTTP_UA_CPU']) && $_SERVER['HTTP_UA_CPU'] == 'ARM') // Seen this on a HTC
- ) {
- $this->isMobile = true;
- } elseif (!empty($this->accept) && (strpos($this->accept, 'text/vnd.wap.wml') !== false || strpos($this->accept, 'application/vnd.wap.xhtml+xml') !== false)) {
- $this->isMobile = true;
- } else {
- $this->_detect();
- }
-
- }
-
- public function getRules()
- {
- return $this->detectionRules;
- }
-
- /**
- * Magic overloading method.
- *
- * @method boolean is[...]()
- * @param string $name
- * @param array $arguments
- * @return mixed
- */
- public function __call($name, $arguments)
- {
-
- $key = substr($name, 2);
- return $this->_detect($key);
-
- }
-
- /**
- * Private method that does the detection of the
- * mobile devices.
- *
- * @param string $key
- * @return boolean|null
- */
- private function _detect($key='')
- {
-
- if(empty($key)){
-
- // Begin general search.
- foreach($this->detectionRules as $_regex){
- if(empty($_regex)){ continue; }
- if(preg_match('/'.$_regex.'/is', $this->userAgent)){
- $this->isMobile = true;
- return true;
- }
- }
- return false;
-
- } else {
-
- // Search for a certain key.
- // Make the keys lowecase so we can match: isIphone(), isiPhone(), isiphone(), etc.
- $key = strtolower($key);
- $_rules = array_change_key_case($this->detectionRules);
-
- if(array_key_exists($key, $_rules)){
- if(empty($_rules[$key])){ return null; }
- if(preg_match('/'.$_rules[$key].'/is', $this->userAgent)){
- $this->isMobile = true;
- return true;
- } else {
- return false;
- }
- } else {
- trigger_error("Method $key is not defined", E_USER_WARNING);
- }
-
- return false;
-
- }
-
- }
-
- /**
- * Check if the device is mobile.
- * Returns true if any type of mobile device detected, including special ones
- * @return bool
- */
- public function isMobile()
- {
- return $this->isMobile;
- }
-
- /**
- * Check if the device is a tablet.
- * Return true if any type of tablet device is detected.
- * @return boolean
- */
- public function isTablet()
- {
-
- foreach($this->tabletDevices as $_regex){
- if(preg_match('/'.$_regex.'/is', $this->userAgent)){
- $this->isTablet = true;
- return true;
- }
- }
-
- return false;
-
- }
-
-
-} \ No newline at end of file
diff --git a/view/pdl/mod_go.pdl b/view/pdl/mod_go.pdl
new file mode 100644
index 000000000..c34898dd5
--- /dev/null
+++ b/view/pdl/mod_go.pdl
@@ -0,0 +1,6 @@
+[region=aside]
+[widget=fullprofile][/widget]
+[/region]
+[region=right_aside]
+[widget=notifications][/widget]
+[/region]
diff --git a/view/tpl/abook_edit.tpl b/view/tpl/abook_edit.tpl
index 81c182e1b..d72258fa0 100755
--- a/view/tpl/abook_edit.tpl
+++ b/view/tpl/abook_edit.tpl
@@ -215,7 +215,7 @@
<span id="vcard-preview-{{$vcard.id}}" class="vcard-preview">
{{if $vcard.fn}}<span class="vcard-fn-preview">{{$vcard.fn}}</span>{{/if}}
{{if $vcard.emails.0.address}}<span class="vcard-email-preview d-none d-md-table-cell"><a href="mailto:{{$vcard.emails.0.address}}">{{$vcard.emails.0.address}}</a></span>{{/if}}
- {{if $vcard.tels.0}}<span class="vcard-tel-preview d-none d-md-table-cell">{{$vcard.tels.0.nr}}{{if $is_mobile}} <a class="btn btn-outline-secondary btn-sm" href="tel:{{$vcard.tels.0.nr}}"><i class="fa fa-phone connphone"></i></a>{{/if}}</span>{{/if}}
+ {{if $vcard.tels.0}}<span class="vcard-tel-preview d-none d-md-table-cell">{{$vcard.tels.0.nr}} <a class="btn btn-outline-secondary btn-sm" href="tel:{{$vcard.tels.0.nr}}"><i class="fa fa-phone connphone"></i></a></span>{{/if}}
</span>
<input id="vcard-fn-{{$vcard.id}}" class="vcard-fn" type="text" name="fn" value="{{$vcard.fn}}" size="{{$vcard.fn|count_characters:true}}" placeholder="{{$name_label}}">
</div>
diff --git a/view/tpl/admin_accounts.tpl b/view/tpl/admin_accounts.tpl
index 3535363a0..d6c9591fd 100755
--- a/view/tpl/admin_accounts.tpl
+++ b/view/tpl/admin_accounts.tpl
@@ -41,7 +41,7 @@
</tbody>
</table>
<div class="selectall"><a href="#" onclick="return toggle_selectall('pending_ckbx');">{{$select_all}}</a></div>
- <div class="submit"><input type="submit" name="page_users_deny" value="{{$deny}}"> <input type="submit" name="page_users_approve" value="{{$approve}}"></div>
+ <div class="submit"><input type="submit" name="page_accounts_deny" value="{{$deny}}"> <input type="submit" name="page_accounts_approve" value="{{$approve}}"></div>
{{else}}
<p>{{$no_pending}}</p>
{{/if}}
@@ -80,7 +80,7 @@
</tbody>
</table>
<div class="selectall"><a href="#" onclick="return toggle_selectall('users_ckbx');">{{$select_all}}</a></div>
- <div class="submit"><input type="submit" name="page_users_block" value="{{$block}}/{{$unblock}}"> <input type="submit" name="page_users_delete" value="{{$delete}}" onclick="return confirm_delete_multi()"></div>
+ <div class="submit"><input type="submit" name="page_accounts_block" value="{{$block}}/{{$unblock}}"> <input type="submit" name="page_accounts_delete" value="{{$delete}}" onclick="return confirm_delete_multi()"></div>
{{else}}
NO USERS?!?
{{/if}}
diff --git a/view/tpl/admin_site.tpl b/view/tpl/admin_site.tpl
index 50482f03d..0eabe620d 100755
--- a/view/tpl/admin_site.tpl
+++ b/view/tpl/admin_site.tpl
@@ -74,6 +74,7 @@
{{include file="field_select.tpl" field=$access_policy}}
{{include file="field_input.tpl" field=$location}}
{{include file="field_input.tpl" field=$sellpage}}
+ {{include file="field_input.tpl" field=$firstpage}}
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
diff --git a/view/tpl/atom_feed.tpl b/view/tpl/atom_feed.tpl
index b1e92cdbf..8dc145ae9 100755
--- a/view/tpl/atom_feed.tpl
+++ b/view/tpl/atom_feed.tpl
@@ -13,7 +13,7 @@
<id>{{$feed_id}}</id>
<title>{{$feed_title}}</title>
- <generator uri="http://hubzilla.org" version="{{$version}}">{{$red}}</generator>
+ <generator uri="{{$generator_uri}}" version="{{$version}}">{{$generator}}</generator>
<link rel="license" href="http://creativecommons.org/licenses/by/3.0/" />
{{if $profile_page}}
<link rel="alternate" type="text/html" href="{{$profile_page}}" />
diff --git a/view/tpl/connections.tpl b/view/tpl/connections.tpl
index cfb7ae67e..32973353e 100755
--- a/view/tpl/connections.tpl
+++ b/view/tpl/connections.tpl
@@ -5,7 +5,7 @@
<i class="fa fa-search"></i>&nbsp;{{$label}}
</button>
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{{$sort}}">
- <i class="fa fa-sort"></i>
+ <i class="fa fa-filter"></i>
</button>
<div class="dropdown-menu dropdown-menu-right">
{{foreach $tabs as $menu}}
@@ -25,7 +25,7 @@
</div>
</form>
</div>
- <div id="connections-wrapper clearfix">
+ <div class="connections-wrapper clearfix">
{{foreach $contacts as $contact}}
{{include file="connection_template.tpl"}}
{{/foreach}}
diff --git a/view/tpl/go.tpl b/view/tpl/go.tpl
new file mode 100644
index 000000000..f0f9ee79e
--- /dev/null
+++ b/view/tpl/go.tpl
@@ -0,0 +1,16 @@
+<h2>{{$title}}</h2>
+
+<div class="descriptive-text">
+ <p>{{$m}}</p>
+ <p>{{$m1}}</p>
+</div>
+
+{{if $options}}
+<ul class="nav nav-pills flex-column">
+{{foreach $options as $k => $v}}
+ <li class="nav-item"><a href="{{$k}}" class="nav-link">{{$v}}</a></li>
+{{/foreach}}
+</ul>
+{{/if}}
+
+
diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl
index ffaa4e208..0ffc8b349 100755
--- a/view/tpl/jot-header.tpl
+++ b/view/tpl/jot-header.tpl
@@ -110,10 +110,21 @@ var activeCommentID = 0;
var activeCommentText = '';
$(document).ready(function() {
+
/* enable tinymce on focus and click */
$("#profile-jot-text").focus(enableOnUser);
$("#profile-jot-text").click(enableOnUser);
+ $('#id_mimetype').on('load', jotSetMime);
+ $('#id_mimetype').on('change', jotSetMime);
+
+ function jotSetMime() {
+ var mtype = $('#id_mimetype').val();
+ if(mtype == 'text/bbcode')
+ $('#profile-jot-submit-left').show();
+ else
+ $('#profile-jot-submit-left').hide();
+ }
$('#invisible-wall-file-upload').fileupload({
url: 'wall_attach/{{$nickname}}',
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index 0f27b1a47..211e8e05b 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -33,6 +33,14 @@
{{if $module != 'hq' && $startpage == 'hq'}}
e.preventDefault();
+ if(typeof notify_id !== 'undefined' && notify_id !== 'undefined') {
+ $.post(
+ "hq",
+ {
+ "notify_id" : notify_id
+ }
+ );
+ }
window.location.href = 'hq/' + b64mid;
return;
{{else}}
diff --git a/view/tpl/settings_display.tpl b/view/tpl/settings_display.tpl
index d1e6e0609..b0751eb5f 100755
--- a/view/tpl/settings_display.tpl
+++ b/view/tpl/settings_display.tpl
@@ -6,7 +6,7 @@
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
<div class="panel-group" id="settings" role="tablist" aria-multiselectable="true">
- {{if $theme || $mobile_theme}}
+ {{if $theme}}
<div class="panel">
<div class="section-subtitle-wrapper" role="tab" id="theme-settings-title">
<h3>
@@ -23,9 +23,6 @@
{{if $schema}}
{{include file="field_select.tpl" field=$schema}}
{{/if}}
- {{if $mobile_theme}}
- {{include file="field_themeselect.tpl" field=$mobile_theme}}
- {{/if}}
<div class="settings-submit-wrapper" >
<button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button>
</div>
@@ -41,7 +38,7 @@
</a>
</h3>
</div>
- <div id="custom-settings-content" class="collapse{{if !$theme && !$mobile_theme}} in{{/if}}" role="tabpanel" aria-labelledby="custom-settings">
+ <div id="custom-settings-content" class="collapse{{if !$theme}} in{{/if}}" role="tabpanel" aria-labelledby="custom-settings">
<div class="section-content-tools-wrapper">
{{if $theme_config}}
{{$theme_config}}
@@ -57,7 +54,7 @@
</a>
</h3>
</div>
- <div id="content-settings-content" class="collapse{{if !$theme && !$mobile_theme && !$theme_config}} in{{/if}}" role="tabpanel" aria-labelledby="content-settings">
+ <div id="content-settings-content" class="collapse{{if !$theme && !$theme_config}} in{{/if}}" role="tabpanel" aria-labelledby="content-settings">
<div class="section-content-wrapper">
{{include file="field_input.tpl" field=$ajaxint}}
{{include file="field_input.tpl" field=$itemspage}}