merge red into hubzilla

This commit is contained in:
Mario Vavti 2017-07-03 21:33:24 +02:00
commit d096106824
322 changed files with 16662 additions and 27717 deletions

21
LICENSE
View File

@ -1,20 +1,9 @@
Copyright (c) 2010-2017 the Hubzilla Community
Copyright (c) 2010-2017 Mike Macgirvin
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,29 +1,7 @@
![Hubzilla](images/hubzilla-banner.png)
Hubzilla - Community Server
===========================
red
===
<p align="center" markdown="1">
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
</p>
This is red.
**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 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.
Migration and live backups of your connections, settings, and everything you publish are built-in, so you never need worry about server failure.
Hubzilla is completely decentralised and open source, for you modify or adapt to your needs and desires. Plugins, themes, and numerous configuration options extend the overall capabilities to do anything you can imagine.
**Who Are We?**
The Hubzilla community consists of passionate volunteers creating an open source commons of decentralised services which are highly integrated and can rival the feature set of large centralised providers. We do our best to provide ethical software which places you in control of your online communications and privacy expectations.
[![Build Status](https://travis-ci.org/redmatrix/hubzilla.svg)](https://travis-ci.org/redmatrix/hubzilla)
![red](https://gitlab.com/macgirvin/red/raw/046e5e239fd28996f8c658900a83c33dbe0011ba/images/red-koala.png)

View File

@ -201,6 +201,7 @@ class Permissions {
* * \e array \b perms Permission array
* * \e int \b automatic 0 or 1
*/
static public function connect_perms($channel_id) {
$my_perms = [];

View File

@ -21,12 +21,18 @@ class Importdoc {
$files = glob("$d/$f");
if($files) {
foreach($files as $fi) {
if($fi === 'doc/html')
if($fi === 'doc/html') {
continue;
if(is_dir($fi))
}
if(is_dir($fi)) {
self::update_docs_dir("$fi/*");
else
store_doc_file($fi);
}
else {
// don't update media content
if(strpos(z_mime_content_type($fi),'text') === 0) {
store_doc_file($fi);
}
}
}
}
}

View File

@ -64,8 +64,6 @@ require_once('include/bbcode.php');
* purge_all channel_id
* expire channel_id
* relay item_id (item was relayed to owner, we will deliver it as owner)
* single_activity item_id (deliver to a singleton network from the appropriate clone)
* single_mail mail_id (deliver to a singleton network from the appropriate clone)
* location channel_id
* request channel_id xchan_hash message_id
* rating xlink_id
@ -105,7 +103,7 @@ class Notifier {
$normal_mode = true;
$packet_type = 'undefined';
if($cmd === 'mail' || $cmd === 'single_mail') {
if($cmd === 'mail') {
$normal_mode = false;
$mail = true;
$private = true;
@ -392,7 +390,6 @@ class Notifier {
return;
}
}
}
$walltowall = (($top_level_post && $channel['xchan_hash'] === $target_item['author_xchan']) ? true : false);
@ -409,7 +406,7 @@ class Notifier {
if(! $recipients)
return;
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
$env_recips = (($private) ? array() : null);
@ -422,40 +419,39 @@ class Notifier {
foreach($details as $d) {
$recip_list[] = $d['xchan_addr'] . ' (' . $d['xchan_hash'] . ')';
if($private)
$env_recips[] = array('guid' => $d['xchan_guid'],'guid_sig' => $d['xchan_guid_sig'],'hash' => $d['xchan_hash']);
if($d['xchan_network'] === 'mail' && $normal_mode) {
$delivery_options = get_xconfig($d['xchan_hash'],'system','delivery_mode');
if(! $delivery_options)
format_and_send_email($channel,$d,$target_item);
if($private) {
$env_recips[] = [
'guid' => $d['xchan_guid'],
'guid_sig' => $d['xchan_guid_sig'],
'hash' => $d['xchan_hash']
];
}
}
}
$narr = array(
'channel' => $channel,
'upstream' => $upstream,
'env_recips' => $env_recips,
'packet_recips' => $packet_recips,
'recipients' => $recipients,
'item' => $item,
'target_item' => $target_item,
$narr = [
'channel' => $channel,
'upstream' => $upstream,
'env_recips' => $env_recips,
'packet_recips' => $packet_recips,
'recipients' => $recipients,
'item' => $item,
'target_item' => $target_item,
'top_level_post' => $top_level_post,
'private' => $private,
'private' => $private,
'relay_to_owner' => $relay_to_owner,
'uplink' => $uplink,
'cmd' => $cmd,
'mail' => $mail,
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
'location' => $location,
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
'walltowall' => $walltowall,
'queued' => array()
);
'uplink' => $uplink,
'cmd' => $cmd,
'mail' => $mail,
'single' => false,
'location' => $location,
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
'walltowall' => $walltowall,
'queued' => []
];
call_hooks('notifier_process', $narr);
if($narr['queued']) {
@ -492,8 +488,6 @@ class Notifier {
$hubs = $r;
/**
* Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey,
* since it may have been a re-install which has not yet been detected and pruned.
@ -524,49 +518,47 @@ class Notifier {
if($hub['hubloc_network'] == 'zot') {
if(! in_array($hub['hubloc_sitekey'],$keys)) {
$hublist[] = $hub['hubloc_host'];
$dhubs[] = $hub;
$keys[] = $hub['hubloc_sitekey'];
$dhubs[] = $hub;
$keys[] = $hub['hubloc_sitekey'];
}
}
else {
if(! in_array($hub['hubloc_url'],$urls)) {
$hublist[] = $hub['hubloc_host'];
$dhubs[] = $hub;
$urls[] = $hub['hubloc_url'];
$dhubs[] = $hub;
$urls[] = $hub['hubloc_url'];
}
}
}
logger('notifier: will notify/deliver to these hubs: ' . print_r($hublist,true), LOGGER_DEBUG, LOG_DEBUG);
foreach($dhubs as $hub) {
if($hub['hubloc_network'] !== 'zot') {
$narr = array(
'channel' => $channel,
'upstream' => $upstream,
'env_recips' => $env_recips,
'packet_recips' => $packet_recips,
'recipients' => $recipients,
'item' => $item,
'target_item' => $target_item,
'hub' => $hub,
$narr = [
'channel' => $channel,
'upstream' => $upstream,
'env_recips' => $env_recips,
'packet_recips' => $packet_recips,
'recipients' => $recipients,
'item' => $item,
'target_item' => $target_item,
'hub' => $hub,
'top_level_post' => $top_level_post,
'private' => $private,
'private' => $private,
'relay_to_owner' => $relay_to_owner,
'uplink' => $uplink,
'cmd' => $cmd,
'mail' => $mail,
'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false),
'location' => $location,
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
'walltowall' => $walltowall,
'queued' => array()
);
'uplink' => $uplink,
'cmd' => $cmd,
'mail' => $mail,
'single' => false,
'location' => $location,
'request' => $request,
'normal_mode' => $normal_mode,
'packet_type' => $packet_type,
'walltowall' => $walltowall,
'queued' => []
];
call_hooks('notifier_hub',$narr);
@ -578,21 +570,6 @@ class Notifier {
}
// singleton deliveries by definition 'not got zot'.
// Single deliveries are other federated networks (plugins) and we're essentially
// delivering only to those that have this site url in their abook_instance
// and only from within a sync operation. This means if you post from a clone,
// and a connection is connected to one of your other clones; assuming that hub
// is running it will receive a sync packet. On receipt of this sync packet it
// will invoke a delivery to those connections which are connected to just that
// hub instance.
if($cmd === 'single_mail' || $cmd === 'single_activity') {
continue;
}
// default: zot protocol
$hash = random_string();
$packet = null;
@ -618,14 +595,16 @@ class Notifier {
else {
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
$packet = zot_build_packet($channel,'notify',$env,(($private) ? $hub['hubloc_sitekey'] : null), $hub['site_crypto'],$hash);
queue_insert(array(
'hash' => $hash,
'account_id' => $target_item['aid'],
'channel_id' => $target_item['uid'],
'posturl' => $hub['hubloc_callback'],
'notify' => $packet,
'msg' => json_encode($encoded_item)
));
queue_insert(
[
'hash' => $hash,
'account_id' => $target_item['aid'],
'channel_id' => $target_item['uid'],
'posturl' => $hub['hubloc_callback'],
'notify' => $packet,
'msg' => json_encode($encoded_item)
]
);
// only create delivery reports for normal undeleted items
if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted']) && (! get_config('system','disable_dreport'))) {
@ -646,9 +625,9 @@ class Notifier {
if($normal_mode) {
$x = q("select * from hook where hook = 'notifier_normal'");
if($x)
Master::Summon(array('Deliver_hooks',$target_item['id']));
if($x) {
Master::Summon( [ 'Deliver_hooks', $target_item['id'] ] );
}
}
if($deliveries)

View File

@ -40,6 +40,15 @@ class Hook {
return $r;
}
static public function register_array($file,$arr) {
if($arr) {
foreach($arr as $k => $v) {
self::register($k,$file,$v);
}
}
}
static public function unregister($hook,$file,$function,$version = 1,$priority = 0) {
if(is_array($function)) {
$function = serialize($function);

View File

@ -209,6 +209,7 @@ class Apps {
static public function translate_system_apps(&$arr) {
$apps = array(
'Apps' => t('Apps'),
'Site Admin' => t('Site Admin'),
'Report Bug' => t('Report Bug'),
'View Bookmarks' => t('View Bookmarks'),
@ -664,11 +665,6 @@ class Apps {
}
static public function app_decode($s) {
$x = base64_decode(str_replace(array('<br />',"\r","\n",' '),array('','','',''),$s));
return json_decode($x,true);

View File

@ -9,10 +9,10 @@ namespace Zotlabs\Lib;
class Cache {
public static function get($key) {
$key = substr($key,0,254);
$hash = hash('whirlpool',$key);
$r = q("SELECT v FROM cache WHERE k = '%s' limit 1",
dbesc($key)
dbesc($hash)
);
if ($r)
@ -22,20 +22,20 @@ class Cache {
public static function set($key,$value) {
$key = substr($key,0,254);
$hash = hash('whirlpool',$key);
$r = q("SELECT * FROM cache WHERE k = '%s' limit 1",
dbesc($key)
dbesc($hash)
);
if($r) {
q("UPDATE cache SET v = '%s', updated = '%s' WHERE k = '%s'",
dbesc($value),
dbesc(datetime_convert()),
dbesc($key));
dbesc($hash));
}
else {
q("INSERT INTO cache ( k, v, updated) VALUES ('%s','%s','%s')",
dbesc($key),
dbesc($hash),
dbesc($value),
dbesc(datetime_convert()));
}

View File

@ -53,7 +53,7 @@ class Config {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_config($family, $key) === false || (! self::get_from_storage($family, $key))) {
if(self::Get($family, $key) === false || (! self::get_from_storage($family, $key))) {
$ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),

View File

@ -170,7 +170,7 @@ class Enotify {
xchan_query($p);
$moderated = (($p[0]['item_blocked'] = ITEM_MODERATED) ? true : false);
$moderated = (($p[0]['item_blocked'] == ITEM_MODERATED) ? true : false);
$item_post_type = item_post_type($p[0]);
// $private = $p[0]['item_private'];

View File

@ -119,7 +119,7 @@ class PConfig {
$dbvalue = ((is_array($value)) ? serialize($value) : $value);
$dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
if(get_pconfig($uid, $family, $key) === false) {
if(self::Get($uid, $family, $key) === false) {
if(! array_key_exists($uid, \App::$config))
\App::$config[$uid] = array();
if(! array_key_exists($family, \App::$config[$uid]))

View File

@ -54,12 +54,8 @@ class System {
return 'https://github.com/redmatrix/hubzilla';
}
static public function get_server_role() {
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['server_role'])
return \App::$config['system']['server_role'];
return 'standard';
return 'pro';
}
static public function get_std_version() {
@ -72,11 +68,8 @@ class System {
if(get_directory_realm() != DIRECTORY_REALM)
return true;
foreach(['hubzilla','zap'] as $t) {
if(stristr($p,$t))
return true;
}
if(in_array(strtolower($p),['hubzilla','zap','red']))
return true;
return false;
}
}

View File

@ -251,8 +251,6 @@ class ThreadItem {
);
}
$server_role = get_config('system','server_role');
$has_bookmarks = false;
if(is_array($item['term'])) {
foreach($item['term'] as $t) {

View File

@ -91,10 +91,10 @@ class Admin extends \Zotlabs\Web\Controller {
intval(ACCOUNT_BLOCKED)
);
if ($r) {
$accounts['total'] = array('label' => t('# Accounts'), 'val' => $r[0]['total']);
$accounts['blocked'] = array('label' => t('# blocked accounts'), 'val' => $r[0]['blocked']);
$accounts['expired'] = array('label' => t('# expired accounts'), 'val' => $r[0]['expired']);
$accounts['expiring'] = array('label' => t('# expiring accounts'), 'val' => $r[0]['expiring']);
$accounts['total'] = array('label' => t('Accounts'), 'val' => $r[0]['total']);
$accounts['blocked'] = array('label' => t('Blocked accounts'), 'val' => $r[0]['blocked']);
$accounts['expired'] = array('label' => t('Expired accounts'), 'val' => $r[0]['expired']);
$accounts['expiring'] = array('label' => t('Expiring accounts'), 'val' => $r[0]['expiring']);
}
// pending registrations
@ -105,9 +105,9 @@ class Admin extends \Zotlabs\Web\Controller {
$channels = array();
$r = q("SELECT COUNT(*) AS total, COUNT(CASE WHEN channel_primary = 1 THEN 1 ELSE NULL END) AS main, COUNT(CASE WHEN channel_primary = 0 THEN 1 ELSE NULL END) AS clones FROM channel WHERE channel_removed = 0");
if ($r) {
$channels['total'] = array('label' => t('# Channels'), 'val' => $r[0]['total']);
$channels['main'] = array('label' => t('# primary'), 'val' => $r[0]['main']);
$channels['clones'] = array('label' => t('# clones'), 'val' => $r[0]['clones']);
$channels['total'] = array('label' => t('Channels'), 'val' => $r[0]['total']);
$channels['main'] = array('label' => t('Primary'), 'val' => $r[0]['main']);
$channels['clones'] = array('label' => t('Clones'), 'val' => $r[0]['clones']);
}
// We can do better, but this is a quick queue status
@ -118,14 +118,11 @@ class Admin extends \Zotlabs\Web\Controller {
// If no plugins active return 0, otherwise list of plugin names
$plugins = (count(\App::$plugins) == 0) ? count(\App::$plugins) : \App::$plugins;
if(is_array($plugins))
sort($plugins);
// Could be extended to provide also other alerts to the admin
$alertmsg = '';
// annoy admin about upcoming unsupported PHP version
if (version_compare(PHP_VERSION, '5.4', '<')) {
$alertmsg = 'Your PHP version ' . PHP_VERSION . ' will not be supported with the next major release of $Projectname. You are strongly urged to upgrade to a current version.'
. '<br>PHP 5.3 has reached its <a href="http://php.net/eol.php" class="alert-link">End of Life (EOL)</a> in August 2014.'
. ' A list about current PHP versions can be found <a href="http://php.net/supported-versions.php" class="alert-link">here</a>.';
}
$vmaster = get_repository_version('master');
$vdev = get_repository_version('dev');

View File

@ -17,7 +17,6 @@ class Site {
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
$server_role = ((x($_POST,'server_role')) ? notags(trim($_POST['server_role'])) : 'standard');
$banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
@ -68,7 +67,6 @@ class Site {
if(array_key_exists('techlevel', $_POST))
$techlevel = intval($_POST['techlevel']);
set_config('system', 'server_role', $server_role);
set_config('system', 'feed_contacts', $feed_contacts);
set_config('system', 'delivery_interval', $delivery_interval);
set_config('system', 'delivery_batch_count', $delivery_batch_count);
@ -254,12 +252,6 @@ class Site {
// now invert the logic for the setting.
$discover_tab = (1 - $discover_tab);
$server_roles = [
'basic' => t('Basic/Minimal Social Networking'),
'standard' => t('Standard Configuration (default)'),
'pro' => t('Professional')
];
$techlevels = [
'0' => t('Beginner/Basic'),
'1' => t('Novice - not skilled but willing to learn'),
@ -286,8 +278,6 @@ class Site {
// name, label, value, help string, extra data...
'$sitename' => array('sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),''),
'$server_role' => array('server_role', t("Server Configuration/Role"), get_config('system','server_role'),'',$server_roles),
'$techlevel' => [ 'techlevel', t('Site default technical skill level'), get_config('system','techlevel'), t('Used to provide a member experience matched to technical comfort level'), $techlevels ],
'$techlock' => [ 'techlock', t('Lock the technical skill level setting'), get_config('system','techlevel_lock'), t('Members can set their own technical comfort level by default') ],

View File

@ -0,0 +1,71 @@
<?php
namespace Zotlabs\Module;
class Authorize extends \Zotlabs\Web\Controller {
function get() {
// workaround for HTTP-auth in CGI mode
if (x($_SERVER, 'REDIRECT_REMOTE_USER')) {
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ;
if(strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
if (x($_SERVER, 'HTTP_AUTHORIZATION')) {
$userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)) ;
if(strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
require_once('include/oauth2.php');
$request = \OAuth2\Request::createFromGlobals();
$response = new \OAuth2\Response();
// validate the authorize request
if (! $oauth2_server->validateAuthorizeRequest($request, $response)) {
$response->send();
killme();
}
// display an authorization form
if (empty($_POST)) {
return '
<form method="post">
<label>Do You Authorize TestClient?</label><br />
<input type="submit" name="authorized" value="yes">
<input type="submit" name="authorized" value="no">
</form>';
}
// print the authorization code if the user has authorized your client
$is_authorized = ($_POST['authorized'] === 'yes');
$oauth2_server->handleAuthorizeRequest($request, $response, $is_authorized);
if ($is_authorized) {
// this is only here so that you get to see your code in the cURL request. Otherwise,
// we'd redirect back to the client
$code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);
echo("SUCCESS! Authorization Code: $code");
}
$response->send();
killme();
}
}

View File

@ -3,8 +3,6 @@ namespace Zotlabs\Module;
require_once('include/items.php');
require_once('include/conversation.php');
require_once('include/page_widgets.php');
class Block extends \Zotlabs\Web\Controller {

1202
Zotlabs/Module/Cdav.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -365,10 +365,10 @@ class Channel extends \Zotlabs\Web\Controller {
if($checkjs->disabled()) {
$o .= conversation($a,$items,'channel',$update,'traditional');
$o .= conversation($items,'channel',$update,'traditional');
}
else {
$o .= conversation($a,$items,'channel',$update,$page_mode);
$o .= conversation($items,'channel',$update,$page_mode);
}
if((! $update) || ($checkjs->disabled())) {

View File

@ -102,27 +102,32 @@ class Chanview extends \Zotlabs\Web\Controller {
}
$is_zot = false;
$connected = false;
if (\App::$poi) {
$url = \App::$poi['xchan_url'];
if(\App::$poi['xchan_network'] === 'zot') {
$is_zot = true;
}
if(local_channel()) {
$c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
intval(local_channel()),
dbesc(\App::$poi['xchan_hash'])
);
if($c)
$connected = true;
}
}
// We will load the chanview template if it's a foreign network,
// just so that we can provide a connect button along with a profile
// photo. Chances are we can't load the remote profile into an iframe
// because of cross-domain security headers. So provide a link to
// the remote profile.
// If we are already connected, just go to the profile.
// Zot channels will usually have a connect link.
// If it isn't zot, 'pro' members won't be able to use the connect
// button as it is a foreign network so just send them to the remote
// profile.
if($is_zot || \Zotlabs\Lib\System::get_server_role() === 'pro') {
if($is_zot || $connected) {
if($is_zot && $observer) {
$url = zid($url);
}

View File

@ -86,12 +86,13 @@ class Cloud extends \Zotlabs\Web\Controller {
// require_once('\Zotlabs\Storage/QuotaPlugin.php');
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
ob_start();
// ob_start();
// All we need to do now, is to fire up the server
$server->exec();
ob_end_flush();
// ob_end_flush();
if($browser->build_page)
construct_page();
killme();
}

View File

@ -19,7 +19,7 @@ class Connections extends \Zotlabs\Web\Controller {
}
function get() {
function get() {
$sort_type = 0;
$o = '';
@ -63,8 +63,8 @@ class Connections extends \Zotlabs\Web\Controller {
$hidden = true;
break;
case 'archived':
$search_flags = " and abook_archived = 1 ";
$head = t('Archived');
$search_flags = " and ( abook_archived = 1 OR abook_not_here = 1) ";
$head = t('Archived/Unreachable');
$archived = true;
break;
case 'pending':
@ -168,10 +168,10 @@ class Connections extends \Zotlabs\Web\Controller {
),
'archived' => array(
'label' => t('Archived'),
'label' => t('Archived/Unreachable'),
'url' => z_root() . '/connections/archived',
'sel' => ($archived) ? 'active' : '',
'title' => t('Only show archived connections'),
'title' => t('Only show archived/unreachable connections'),
),
'hidden' => array(
@ -243,7 +243,8 @@ class Connections extends \Zotlabs\Web\Controller {
((intval($rr['abook_archived'])) ? t('Archived') : ''),
((intval($rr['abook_hidden'])) ? t('Hidden') : ''),
((intval($rr['abook_ignored'])) ? t('Ignored') : ''),
((intval($rr['abook_blocked'])) ? t('Blocked') : '')
((intval($rr['abook_blocked'])) ? t('Blocked') : ''),
((intval($rr['abook_not_here'])) ? t('Not connected at this location') : '')
);
foreach($status as $str) {
@ -257,11 +258,12 @@ class Connections extends \Zotlabs\Web\Controller {
$contacts[] = array(
'img_hover' => sprintf( t('%1$s [%2$s]'),$rr['xchan_name'],$rr['xchan_url']),
'edit_hover' => t('Edit connection'),
'edit' => t('Edit'),
'delete_hover' => t('Delete connection'),
'id' => $rr['abook_id'],
'thumb' => $rr['xchan_photo_m'],
'name' => $rr['xchan_name'],
'classes' => (intval($rr['abook_archived']) ? 'archived' : ''),
'classes' => ((intval($rr['abook_archived']) || intval($rr['abook_not_here'])) ? 'archived' : ''),
'link' => z_root() . '/connedit/' . $rr['abook_id'],
'deletelink' => z_root() . '/connedit/' . intval($rr['abook_id']) . '/drop',
'delete' => t('Delete'),

View File

@ -842,6 +842,22 @@ class Connedit extends \Zotlabs\Web\Controller {
}
else
$locstr = t('none');
$clone_warn = '';
$clonable = (in_array($contact['xchan_network'],['zot','rss']) ? true : false);
if(! $clonable) {
$clone_warn = '<strong>';
$clone_warn .= ((intval($contact['abook_not_here']))
? t('This connection is unreachable from this location.')
: t('This connection may be unreachable from other channel locations.')
);
$clone_warn .= '</strong><br>' . t('Location independence is not supported by their network.');
}
if(intval($contact['abook_not_here']) && $unclonable)
$not_here = t('This connection is unreachable from this location. Location independence is not supported by their network.');
$o .= replace_macros($tpl, [
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
@ -856,6 +872,7 @@ class Connedit extends \Zotlabs\Web\Controller {
'$addr_text' => t('This connection\'s primary address is'),
'$loc_text' => t('Available locations:'),
'$locstr' => $locstr,
'$unclonable' => $clone_warn,
'$notself' => (($self) ? '' : '1'),
'$self' => (($self) ? '1' : ''),
'$autolbl' => t('The permissions indicated on this page will be applied to all new connections.'),

View File

@ -308,12 +308,12 @@ class Display extends \Zotlabs\Web\Controller {
if ($checkjs->disabled()) {
$o .= conversation($a, $items, 'display', $update, 'traditional');
$o .= conversation($items, 'display', $update, 'traditional');
if ($items[0]['title'])
\App::$page['title'] = $items[0]['title'] . " - " . \App::$page['title'];
}
else {
$o .= conversation($a, $items, 'display', $update, 'client');
$o .= conversation($items, 'display', $update, 'client');
}
if($updateable) {

View File

@ -39,6 +39,11 @@ class Editpost extends \Zotlabs\Web\Controller {
return;
}
if($itm[0]['resource_type'] === 'photo' && $itm[0]['resource_id']) {
notice( t('Item is not editable') . EOL);
return;
}
if($itm[0]['resource_type'] === 'event' && $itm[0]['resource_id']) {
goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1');
}

View File

@ -14,6 +14,8 @@ class Hcard extends \Zotlabs\Web\Controller {
return;
}
logger('hcard_request: ' . $which, LOGGER_DEBUG);
$profile = '';
$channel = \App::get_channel();

View File

@ -44,42 +44,42 @@ class Help extends \Zotlabs\Web\Controller {
return $o;
}
if(argc() > 2 && argv(argc()-2) === 'assets') {
$path = '';
for($x = 1; $x < argc(); $x ++) {
if(strlen($path))
$path .= '/';
$path .= argv($x);
}
$realpath = 'doc/' . $path;
//Set the content-type header as appropriate
$imageInfo = getimagesize($realpath);
switch ($imageInfo[2]) {
case IMAGETYPE_JPEG:
header("Content-Type: image/jpeg");
break;
case IMAGETYPE_GIF:
header("Content-Type: image/gif");
break;
case IMAGETYPE_PNG:
header("Content-Type: image/png");
break;
default:
break;
}
header("Content-Length: " . filesize($realpath));
if(argc() > 2 && argv(argc()-2) === 'assets') {
$path = '';
for($x = 1; $x < argc(); $x ++) {
if(strlen($path))
$path .= '/';
$path .= argv($x);
}
$realpath = 'doc/' . $path;
//Set the content-type header as appropriate
$imageInfo = getimagesize($realpath);
switch ($imageInfo[2]) {
case IMAGETYPE_JPEG:
header("Content-Type: image/jpeg");
break;
case IMAGETYPE_GIF:
header("Content-Type: image/gif");
break;
case IMAGETYPE_PNG:
header("Content-Type: image/png");
break;
default:
break;
}
header("Content-Length: " . filesize($realpath));
// dump the picture and stop the script
readfile($realpath);
killme();
}
// dump the picture and stop the script
readfile($realpath);
killme();
}
$headings = [
'about' => t('About'),
'member' => t('Members'),
'admin' => t('Administrators'),
'about' => t('About'),
'member' => t('Members'),
'admin' => t('Administrators'),
'developer' => t('Developers'),
'tutorials' => t('Tutorials')
];
@ -87,13 +87,13 @@ class Help extends \Zotlabs\Web\Controller {
if(array_key_exists(argv(1), $headings))
$heading = $headings[argv(1)];
$content = get_help_content();
$content = get_help_content();
return replace_macros(get_markup_template('help.tpl'), array(
'$title' => t('$Projectname Documentation'),
'$title' => t('$Projectname Documentation'),
'$tocHeading' => t('Contents'),
'$content' => $content,
'$heading' => $heading
'$content' => $content,
'$heading' => $heading
));
}

View File

@ -121,8 +121,7 @@ class Import extends \Zotlabs\Web\Controller {
$t = sprintf( t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1 );
notice($t);
}
if(array_key_exists('server_role',$data['compatibility']) && $data['compatibility']['server_role'] == 'basic')
$moving = true;
}
if($moving)
@ -333,6 +332,10 @@ class Import extends \Zotlabs\Web\Controller {
$abook['abook_feed'] = (($abook['abook_flags'] & 0x0100 ) ? 1 : 0);
}
if(array_key_exists('abook_instance',$abook) && $abook['abook_instance'] && strpos($abook['abook_instance'],z_root()) === false) {
$abook['abook_not_here'] = 1;
}
if($abook['abook_self']) {
$role = get_pconfig($channel['channel_id'],'system','permissions_role');
if(($role === 'forum') || ($abook['abook_my_perms'] & PERMS_W_TAGWALL)) {

View File

@ -49,7 +49,7 @@ class Invite extends \Zotlabs\Web\Controller {
if(! $recip)
continue;
if(! valid_email($recip)) {
if(! validate_email($recip)) {
notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL);
continue;
}

View File

@ -818,7 +818,7 @@ class Item extends \Zotlabs\Web\Controller {
$datarray['owner'] = $owner_xchan;
$datarray['author'] = $observer;
$datarray['attach'] = json_encode($datarray['attach']);
$o = conversation($a,array($datarray),'search',false,'preview');
$o = conversation(array($datarray),'search',false,'preview');
// logger('preview: ' . $o, LOGGER_DEBUG);
echo json_encode(array('preview' => $o));
killme();

View File

@ -68,8 +68,7 @@ class Moderate extends \Zotlabs\Web\Controller {
$items = array();
}
$o = conversation($a,$items,'moderate',false,'traditional');
$o = conversation($items,'moderate',false,'traditional');
return $o;
}

View File

@ -551,7 +551,7 @@ class Network extends \Zotlabs\Web\Controller {
$mode = (($nouveau) ? 'network-new' : 'network');
$o .= conversation($a,$items,$mode,$update,$page_mode);
$o .= conversation($items,$mode,$update,$page_mode);
if(($items) && (! $update))
$o .= alt_pager($a,count($items));

View File

@ -134,7 +134,7 @@ class New_channel extends \Zotlabs\Web\Controller {
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*");
$nickhub = '@' . \App::get_hostname();
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*");
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles);
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/member/member_guide#Account_Permission_Roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles);
$o = replace_macros(get_markup_template('new_channel.tpl'), array(
'$title' => t('Create Channel'),

View File

@ -3,7 +3,6 @@ namespace Zotlabs\Module;
require_once('include/items.php');
require_once('include/conversation.php');
require_once('include/page_widgets.php');
class Page extends \Zotlabs\Web\Controller {

View File

@ -154,7 +154,9 @@ class Photo extends \Zotlabs\Web\Controller {
intval($resolution)
);
if($r && $r[0]['photo_usage'] == PHOTO_COVER)
// viewing cover photos is allowed unless a plugin chooses to block it.
if($r && intval($r[0]['photo_usage']) === PHOTO_COVER && $resolution >= PHOTO_RES_COVER_1200)
$allowed = 1;
$d = [ 'imgscale' => $resolution, 'resource_id' => $photo, 'photo' => $r, 'allowed' => $allowed ];

View File

@ -41,7 +41,10 @@ class Poke extends \Zotlabs\Web\Controller {
$activity = ACTIVITY_POKE . '#' . urlencode($verbs[$verb][0]);
$contact_id = intval($_REQUEST['cid']);
if(! $contact_id)
$xchan = trim($_REQUEST['xchan']);
if(! ($contact_id || $xchan))
return;
$parent = ((x($_REQUEST,'parent')) ? intval($_REQUEST['parent']) : 0);
@ -49,13 +52,20 @@ class Poke extends \Zotlabs\Web\Controller {
logger('poke: verb ' . $verb . ' contact ' . $contact_id, LOGGER_DEBUG);
$r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where abook_id = %d and abook_channel = %d LIMIT 1",
intval($contact_id),
intval($uid)
);
if($contact_id) {
$r = q("SELECT * FROM abook left join xchan on xchan_hash = abook_xchan where abook_id = %d and abook_channel = %d LIMIT 1",
intval($contact_id),
intval($uid)
);
}
if($xchan) {
$r = q("SELECT * FROM xchan where xchan_hash like ( '%s' ) LIMIT 1",
dbesc($xchan . '%')
);
}
if(! $r) {
logger('poke: no target ' . $contact_id);
logger('poke: no target.');
return;
}
@ -79,7 +89,7 @@ class Poke extends \Zotlabs\Web\Controller {
$deny_gid = $r[0]['deny_gid'];
}
}
else {
elseif($contact_id) {
$item_private = ((x($_GET,'private')) ? intval($_GET['private']) : 0);
@ -92,9 +102,11 @@ class Poke extends \Zotlabs\Web\Controller {
$arr = array();
$arr['item_wall'] = 1;
$arr['owner_xchan'] = (($parent_item) ? $parent_item['owner_xchan'] : $channel['channel_hash']);
$arr['parent_mid'] = (($parent_mid) ? $parent_mid : $mid);
$arr['parent_mid'] = (($parent_mid) ? $parent_mid : '');
$arr['title'] = '';
$arr['allow_cid'] = $allow_cid;
$arr['allow_gid'] = $allow_gid;

View File

@ -167,7 +167,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
// fake it
$mode = ('network');
$o .= conversation($a,$items,$mode,$update,$page_mode);
$o .= conversation($items,$mode,$update,$page_mode);
if(($items) && (! $update))
$o .= alt_pager($a,count($items));

View File

@ -151,7 +151,7 @@ class Register extends \Zotlabs\Web\Controller {
$new_channel = false;
$next_page = 'new_channel';
if(get_config('system','auto_channel_create') || get_config('system','server_role') == 'basic') {
if(get_config('system','auto_channel_create')) {
$new_channel = auto_channel_create($result['account']['account_id']);
if($new_channel['success']) {
$channel_id = $new_channel['channel']['channel_id'];
@ -237,14 +237,12 @@ class Register extends \Zotlabs\Web\Controller {
$name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'));
$nickhub = '@' . str_replace(array('http://','https://','/'), '', get_config('system','baseurl'));
$nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub));
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles);
$role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/member/member_guide#Account_Permission_Roles" target="_blank">' . t('Read more about roles') . '</a>',$perm_roles);
$tos = array('tos', $label_tos, '', '', array(t('no'),t('yes')));
$server_role = get_config('system','server_role');
$auto_create = (($server_role == 'basic') || (get_config('system','auto_channel_create')) ? true : false);
$default_role = (($server_role == 'basic') ? 'social' : get_config('system','default_permissions_role'));
$auto_create = (get_config('system','auto_channel_create') ? true : false);
$default_role = get_config('system','default_permissions_role');
require_once('include/bbcode.php');

View File

@ -225,7 +225,7 @@ class Search extends \Zotlabs\Web\Controller {
else
$o .= '<h2>' . sprintf( t('Search results for: %s'),htmlspecialchars($search, ENT_COMPAT,'UTF-8')) . '</h2>';
$o .= conversation($a,$items,'search',$update,'client');
$o .= conversation($items,'search',$update,'client');
$o .= '</div>';

View File

@ -16,7 +16,7 @@ class Account {
$account = \App::get_account();
if($email != $account['account_email']) {
if(! valid_email($email))
if(! validate_email($email))
$errs[] = t('Not valid email.');
$adm = trim(get_config('system','admin_email'));
if(($adm) && (strcasecmp($email,$adm) == 0)) {

View File

@ -489,7 +489,6 @@ class Channel {
'$h_prv' => t('Security and Privacy Settings'),
'$permissions_set' => $permissions_set,
'$server_role' => \Zotlabs\Lib\System::get_server_role(),
'$perms_set_msg' => t('Your permissions are already configured. Click to view/adjust'),
'$hide_presence' => array('hide_presence', t('Hide my online presence'),$hide_presence, t('Prevents displaying in your profile that you are online'), $yes_no),

View File

@ -73,9 +73,6 @@ class Setup extends \Zotlabs\Web\Controller {
$phpath = trim($_POST['phpath']);
$adminmail = trim($_POST['adminmail']);
$siteurl = trim($_POST['siteurl']);
$server_role = trim($_POST['server_role']);
if(! $server_role)
$server_role = 'standard';
// $siteurl should not have a trailing slash
@ -103,9 +100,6 @@ class Setup extends \Zotlabs\Web\Controller {
$timezone = trim($_POST['timezone']);
$adminmail = trim($_POST['adminmail']);
$siteurl = trim($_POST['siteurl']);
$server_role = trim($_POST['server_role']);
if(! $server_role)
$server_role = 'standard';
if($siteurl != z_root()) {
$test = z_fetch_url($siteurl."/setup/testrewrite");
@ -134,7 +128,7 @@ class Setup extends \Zotlabs\Web\Controller {
'$dbpass' => $dbpass,
'$dbdata' => $dbdata,
'$dbtype' => $dbtype,
'$server_role' => $server_role,
'$server_role' => 'pro',
'$timezone' => $timezone,
'$siteurl' => $siteurl,
'$site_id' => random_string(),
@ -324,11 +318,6 @@ class Setup extends \Zotlabs\Web\Controller {
$siteurl = trim($_POST['siteurl']);
$timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
$server_roles = [
'basic' => t('Basic/Minimal Social Networking'),
'standard' => t('Standard Configuration (default)'),
'pro' => t('Professional')
];
$tpl = get_markup_template('install_settings.tpl');
$o .= replace_macros($tpl, array(
@ -348,8 +337,6 @@ class Setup extends \Zotlabs\Web\Controller {
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
'$server_role' => array('server_role', t("Server Configuration/Role"), 'standard','',$server_roles),
'$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()),
'$baseurl' => z_root(),

View File

@ -76,7 +76,7 @@ class Share extends \Zotlabs\Web\Controller {
$observer = \App::get_observer();
$parsed = $observer['xchan_url'];
if($parsed) {
$post_url = $parsed['scheme'] . ':' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '')
$post_url = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '')
. '/rpost';
/**

40
Zotlabs/Module/Token.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace Zotlabs\Module;
class Token extends \Zotlabs\Web\Controller {
function get() {
// workaround for HTTP-auth in CGI mode
if (x($_SERVER, 'REDIRECT_REMOTE_USER')) {
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)) ;
if(strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
if (x($_SERVER, 'HTTP_AUTHORIZATION')) {
$userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)) ;
if(strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
require_once('include/oauth2.php');
$oauth2_server->handleTokenRequest(\OAuth2\Request::createFromGlobals())->send();
killme();
}
}

View File

@ -179,11 +179,8 @@ class Webpages extends \Zotlabs\Web\Controller {
// so just list titles and an edit link.
/** @TODO - this should be replaced with pagelist_widget */
$sql_extra = item_permissions_sql($owner);
$r = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d
$sql_extra order by item.created desc",
@ -191,12 +188,6 @@ class Webpages extends \Zotlabs\Web\Controller {
intval(ITEM_TYPE_WEBPAGE)
);
// $r = q("select * from item_id left join item on item_id.iid = item.id
// where item_id.uid = %d and service = 'WEBPAGE' and item_type = %d $sql_extra order by item.created desc",
// intval($owner),
// intval(ITEM_TYPE_WEBPAGE)
// );
if(! $r)
$x['pagetitle'] = 'home';

View File

@ -355,6 +355,7 @@ class Wiki extends \Zotlabs\Web\Controller {
$html = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))),$wikiURL);
}
else {
$bb = Zlib\NativeWikiPage::bbcode($content);
$x = new ZLib\MarkdownSoap($bb);
$md = $x->clean();

View File

@ -9,6 +9,7 @@ class Xrd extends \Zotlabs\Web\Controller {
function init() {
$uri = urldecode(notags(trim($_GET['uri'])));
$subject = $uri;
logger('xrd: ' . $uri,LOGGER_DEBUG);
$resource = $uri;
@ -30,13 +31,7 @@ class Xrd extends \Zotlabs\Web\Controller {
);
if(! $r)
killme();
$dspr = replace_macros(get_markup_template('xrd_diaspora.tpl'),array(
'$baseurl' => z_root(),
'$dspr_guid' => $r[0]['channel_guid'] . str_replace('.','',\App::get_hostname()),
'$dspr_key' => base64_encode(pemtorsa($r[0]['channel_pubkey']))
));
$salmon_key = salmon_key($r[0]['channel_pubkey']);
header('Access-Control-Allow-Origin: *');
@ -49,11 +44,11 @@ class Xrd extends \Zotlabs\Web\Controller {
if($aliases[$x] === $resource)
unset($aliases[$x]);
}
$o = replace_macros(get_markup_template('xrd_person.tpl'), array(
'$nick' => $r[0]['channel_address'],
'$accturi' => $resource,
'$subject' => $subject,
'$aliases' => $aliases,
'$profile_url' => z_root() . '/channel/' . $r[0]['channel_address'],
'$hcard_url' => z_root() . '/hcard/' . $r[0]['channel_address'],
@ -61,12 +56,8 @@ class Xrd extends \Zotlabs\Web\Controller {
'$zot_post' => z_root() . '/post/' . $r[0]['channel_address'],
'$poco_url' => z_root() . '/poco/' . $r[0]['channel_address'],
'$photo' => z_root() . '/photo/profile/l/' . $r[0]['channel_id'],
'$dspr' => $dspr,
// '$salmon' => z_root() . '/salmon/' . $r[0]['channel_address'],
// '$salmen' => z_root() . '/salmon/' . $r[0]['channel_address'] . '/mention',
'$modexp' => 'data:application/magic-public-key,' . $salmon_key,
'$subscribe' => z_root() . '/follow?url={uri}',
'$bigkey' => salmon_key($r[0]['channel_pubkey'])
));

View File

@ -17,6 +17,7 @@ use Sabre\DAV;
*/
class Browser extends DAV\Browser\Plugin {
public $build_page = false;
/**
* @see set_writeable()
* @see \\Sabre\\DAV\\Auth\\Backend\\BackendInterface
@ -257,7 +258,7 @@ class Browser extends DAV\Browser\Plugin {
}
}
$this->server->httpResponse->setHeader('Content-Security-Policy', "script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'");
construct_page();
$this->build_page = true;
}
/**

176
Zotlabs/Widget/Cdav.php Normal file
View File

@ -0,0 +1,176 @@
<?php
namespace Zotlabs\Widget;
class Cdav {
function widget() {
if(!local_channel())
return;
$channel = \App::get_channel();
$principalUri = 'principals/' . $channel['channel_hash'];
if(!cdav_principal($principalUri))
return;
$pdo = \DBA::$dba->db;
require_once 'vendor/autoload.php';
$o = '';
if(argc() == 2 && argv(1) === 'calendar') {
$caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo);
$sabrecals = $caldavBackend->getCalendarsForUser($principalUri);
//TODO: we should probably also check for permission to send stream here
$local_channels = q("SELECT * FROM channel LEFT JOIN abook ON abook_xchan = channel_hash WHERE channel_system = 0 AND channel_removed = 0 AND channel_hash != '%s' AND abook_channel = %d",
dbesc($channel['channel_hash']),
intval($channel['channel_id'])
);
$sharee_options .= '<option value="">' . t('Select Channel') . '</option>' . "\r\n";
foreach($local_channels as $local_channel) {
$sharee_options .= '<option value="' . $local_channel['channel_hash'] . '">' . $local_channel['channel_name'] . '</option>' . "\r\n";
}
$access_options = '<option value="3">' . t('Read-write') . '</option>' . "\r\n";
$access_options .= '<option value="2">' . t('Read-only') . '</option>' . "\r\n";
//list calendars
foreach($sabrecals as $sabrecal) {
if($sabrecal['share-access'] == 1)
$access = '';
if($sabrecal['share-access'] == 2)
$access = 'read';
if($sabrecal['share-access'] == 3)
$access = 'read-write';
$invites = $caldavBackend->getInvites($sabrecal['id']);
$json_source = '/cdav/calendar/json/' . $sabrecal['id'][0] . '/' . $sabrecal['id'][1];
$switch = get_pconfig(local_channel(), 'cdav_calendar', $sabrecal['id'][0]);
$color = (($sabrecal['{http://apple.com/ns/ical/}calendar-color']) ? $sabrecal['{http://apple.com/ns/ical/}calendar-color'] : '#3a87ad');
$editable = (($sabrecal['share-access'] == 2) ? 'false' : 'true'); // false/true must be string since we're passing it to javascript
$sharees = [];
$share_displayname = [];
foreach($invites as $invite) {
if(strpos($invite->href, 'mailto:') !== false) {
$sharee = channelx_by_hash(substr($invite->href, 7));
$sharees[] = [
'name' => $sharee['channel_name'],
'access' => (($invite->access == 3) ? ' (RW)' : ' (R)'),
'hash' => $sharee['channel_hash']
];
}
}
if(!$access) {
$my_calendars[] = [
'ownernick' => $channel['channel_address'],
'uri' => $sabrecal['uri'],
'displayname' => $sabrecal['{DAV:}displayname'],
'calendarid' => $sabrecal['id'][0],
'instanceid' => $sabrecal['id'][1],
'json_source' => $json_source,
'color' => $color,
'editable' => $editable,
'switch' => $switch,
'sharees' => $sharees
];
}
else {
$shared_calendars[] = [
'ownernick' => $channel['channel_address'],
'uri' => $sabrecal['uri'],
'displayname' => $sabrecal['{DAV:}displayname'],
'calendarid' => $sabrecal['id'][0],
'instanceid' => $sabrecal['id'][1],
'json_source' => $json_source,
'color' => $color,
'editable' => $editable,
'switch' => $switch,
'sharer' => $sabrecal['{urn:ietf:params:xml:ns:caldav}calendar-description'],
'access' => $access
];
}
if(!$access || $access === 'read-write') {
$writable_calendars[] = [
'displayname' => ((!$access) ? $sabrecal['{DAV:}displayname'] : $share_displayname[0]),
'id' => $sabrecal['id']
];
}
}
$o .= replace_macros(get_markup_template('cdav_widget_calendar.tpl'), [
'$my_calendars_label' => t('My Calendars'),
'$my_calendars' => $my_calendars,
'$shared_calendars_label' => t('Shared Calendars'),
'$shared_calendars' => $shared_calendars,
'$sharee_options' => $sharee_options,
'$access_options' => $access_options,
'$share_label' => t('Share this calendar'),
'$share' => t('Share'),
'$edit_label' => t('Calendar name and color'),
'$edit' => t('Edit'),
'$create_label' => t('Create new calendar'),
'$create' => t('Create'),
'$create_placeholder' => t('Calendar Name'),
'$tools_label' => t('Calendar Tools'),
'$import_label' => t('Import calendar'),
'$import_placeholder' => t('Select a calendar to import to'),
'$upload' => t('Upload'),
'$writable_calendars' => $writable_calendars
]);
return $o;
}
if(argc() >= 2 && argv(1) === 'addressbook') {
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
$sabreabooks = $carddavBackend->getAddressBooksForUser($principalUri);
//list addressbooks
foreach($sabreabooks as $sabreabook) {
$addressbooks[] = [
'ownernick' => $channel['channel_address'],
'uri' => $sabreabook['uri'],
'displayname' => $sabreabook['{DAV:}displayname'],
'id' => $sabreabook['id']
];
}
$o .= replace_macros(get_markup_template('cdav_widget_addressbook.tpl'), [
'$addressbooks_label' => t('Addressbooks'),
'$addressbooks' => $addressbooks,
'$edit_label' => t('Addressbook name'),
'$edit' => t('Edit'),
'$create_label' => t('Create new addressbook'),
'$create_placeholder' => t('Addressbook Name'),
'$create' => t('Create'),
'$tools_label' => t('Addressbook Tools'),
'$import_label' => t('Import addressbook'),
'$import_placeholder' => t('Select an addressbook to import to'),
'$upload' => t('Upload')
]);
return $o;
}
}
}

View File

@ -12,10 +12,6 @@ class Conversations {
if(argc() > 1) {
switch(argv(1)) {
case 'combined':
$mailbox = 'combined';
$header = t('Conversations');
break;
case 'inbox':
$mailbox = 'inbox';
$header = t('Received Messages');
@ -58,7 +54,7 @@ class Conversations {
'body' => $rr['body'],
'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'),
'seen' => $rr['seen'],
'selected' => ((argv(2)) ? (argv(2) == $rr['id']) : ($r[0]['id'] == $rr['id']))
'selected' => ((argc() == 2) ? (intval(argv(1)) == intval($rr['id'])) : ($r[0]['id'] == $rr['id']))
);
}
@ -71,4 +67,6 @@ class Conversations {
}
return $o;
}
}

View File

@ -79,11 +79,13 @@ class Settings_menu {
'selected' => ''
);
$tabs[] = array(
'label' => t('Connected apps'),
'url' => z_root() . '/settings/oauth',
'selected' => ((argv(1) === 'oauth') ? 'active' : ''),
);
if(get_account_techlevel() > 0) {
$tabs[] = array(
'label' => t('Connected apps'),
'url' => z_root() . '/settings/oauth',
'selected' => ((argv(1) === 'oauth') ? 'active' : ''),
);
}
if(get_account_techlevel() > 2) {
$tabs[] = array(

View File

@ -8,8 +8,8 @@ class Tasklist {
function widget($arr) {
if (! local_channel())
return;
if (! local_channel())
return;
$o .= '<script>var tasksShowAll = 0; $(document).ready(function() { tasksFetch(); $("#tasklist-new-form").submit(function(event) { event.preventDefault(); $.post( "tasks/new", $("#tasklist-new-form").serialize(), function(data) { tasksFetch(); $("#tasklist-new-summary").val(""); } ); return false; } )});</script>';
$o .= '<script>function taskComplete(id) { $.post("tasks/complete/"+id, function(data) { tasksFetch();}); }

5
app/apps.apd Normal file
View File

@ -0,0 +1,5 @@
version: 2
url: $baseurl/apps
name: Apps
photo: icon:bars
categories: System

115
boot.php
View File

@ -48,7 +48,6 @@ require_once('include/xchan.php');
require_once('include/hubloc.php');
require_once('include/attach.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
define ( 'STD_VERSION', '2.5.6' );
define ( 'ZOT_REVISION', '1.2' );
@ -82,7 +81,6 @@ define ( 'DIRECTORY_REALM', 'RED_GLOBAL');
define ( 'DIRECTORY_FALLBACK_MASTER', 'https://gravizot.de');
$DIRECTORY_FALLBACK_SERVERS = array(
//'https://hubzilla.site',
'https://hubzilla.zottel.net',
'https://my.federated.social',
'https://hubzilla.nl',
@ -161,14 +159,6 @@ define ( 'LOGGER_DATA', 3 );
define ( 'LOGGER_ALL', 4 );
/**
* Server roles
*/
define ( 'SERVER_ROLE_BASIC', 0x0001 );
define ( 'SERVER_ROLE_STANDARD', 0x0002 );
define ( 'SERVER_ROLE_PRO', 0x0004 );
/**
* registration policies
*/
@ -600,29 +590,20 @@ function sys_boot() {
$a->convert();
if(defined('UNO')) {
if(UNO)
App::$config['system']['server_role'] = 'basic';
else
App::$config['system']['server_role'] = 'standard';
}
if(! (array_key_exists('server_role',App::$config['system']) && App::$config['system']['server_role']))
App::$config['system']['server_role'] = 'standard';
App::$config['system']['server_role'] = 'pro';
App::$timezone = ((App::$config['system']['timezone']) ? App::$config['system']['timezone'] : 'UTC');
date_default_timezone_set(App::$timezone);
if(! defined('DEFAULT_PLATFORM_ICON')) {
define( 'DEFAULT_PLATFORM_ICON', '/images/hz-32.png' );
define( 'DEFAULT_PLATFORM_ICON', '/images/rm-32.png' );
}
if(! defined('DEFAULT_NOTIFY_ICON')) {
define( 'DEFAULT_NOTIFY_ICON', '/images/hz-white-32.png' );
define( 'DEFAULT_NOTIFY_ICON', '/images/rm-32.png' );
}
/*
* Try to open the database;
*/
@ -733,7 +714,6 @@ class miniApp {
class App {
public static $install = false; // true if we are installing the software
public static $role = 0; // server role (constant, not the string)
public static $account = null; // account record of the logged-in account
public static $channel = null; // channel record of the current channel of the logged-in account
public static $observer = null; // xchan record of the page observer
@ -1008,36 +988,10 @@ class App {
}
}
public static function get_role() {
if(! self::$role)
return self::set_role();
return self::$role;
}
public static function set_role() {
$role_str = \Zotlabs\Lib\System::get_server_role();
switch($role_str) {
case 'basic':
$role = SERVER_ROLE_BASIC;
break;
case 'pro':
$role = SERVER_ROLE_PRO;
break;
case 'standard':
default:
$role = SERVER_ROLE_STANDARD;
break;
}
self::$role = $role;
return $role;
}
public static function get_scheme() {
return self::$scheme;
}
public static function get_hostname() {
return self::$hostname;
}
@ -1151,24 +1105,25 @@ class App {
* since the code added by the modules frequently depends on it
* being first
*/
$tpl = get_markup_template('head.tpl');
self::$page['htmlhead'] = replace_macros($tpl, array(
'$preload_images' => $preload_images,
'$user_scalable' => $user_scalable,
'$query' => urlencode(self::$query_string),
'$baseurl' => self::get_baseurl(),
'$local_channel' => local_channel(),
'$metas' => self::$meta->get(),
'$plugins' => $x['header'],
'$update_interval' => $interval,
'osearch' => sprintf( t('Search %1$s (%2$s)','opensearch'), Zotlabs\Lib\System::get_site_name(), t('$Projectname','opensearch')),
'$head_css' => head_get_css(),
'$head_js' => head_get_js(),
'$linkrel' => head_get_links(),
'$js_strings' => js_strings(),
'$zid' => get_my_address(),
'$channel_id' => self::$profile['uid'],
)) . self::$page['htmlhead'];
self::$page['htmlhead'] = replace_macros(get_markup_template('head.tpl'),
[
'$preload_images' => $preload_images,
'$user_scalable' => $user_scalable,
'$query' => urlencode(self::$query_string),
'$baseurl' => self::get_baseurl(),
'$local_channel' => local_channel(),
'$metas' => self::$meta->get(),
'$plugins' => $x['header'],
'$update_interval' => $interval,
'$head_css' => head_get_css(),
'$head_js' => head_get_js(),
'$linkrel' => head_get_links(),
'$js_strings' => js_strings(),
'$zid' => get_my_address(),
'$channel_id' => self::$profile['uid']
]
) . self::$page['htmlhead'];
// always put main.js at the end
self::$page['htmlhead'] .= head_get_main_js();
@ -1181,11 +1136,13 @@ class App {
* @param string $name
*/
public static function register_template_engine($class, $name = '') {
if ($name === ""){
$v = get_class_vars( $class );
if(x($v, "name")) $name = $v['name'];
if(! $name) {
$v = get_class_vars($class);
if(x($v, "name")) {
$name = $v['name'];
}
}
if ($name === ""){
if (! $name) {
echo "template engine <tt>$class</tt> cannot be registered without a name.\n";
killme();
}
@ -1201,19 +1158,21 @@ class App {
* @return object Template Engine instance
*/
public static function template_engine($name = ''){
if ($name !== "") {
if($name !== '') {
$template_engine = $name;
} else {
}
else {
$template_engine = 'smarty3';
if (x(self::$theme, 'template_engine')) {
if(x(self::$theme, 'template_engine')) {
$template_engine = self::$theme['template_engine'];
}
}
if (isset(self::$template_engines[$template_engine])){
if(isset(self::$template_engines[$template_engine])){
if(isset(self::$template_engine_instance[$template_engine])){
return self::$template_engine_instance[$template_engine];
} else {
}
else {
$class = self::$template_engines[$template_engine];
$obj = new $class;
self::$template_engine_instance[$template_engine] = $obj;
@ -1221,7 +1180,8 @@ class App {
}
}
echo "template engine <tt>$template_engine</tt> is not registered!\n"; killme();
echo "template engine <tt>$template_engine</tt> is not registered!\n";
killme();
}
/**
@ -2336,6 +2296,7 @@ function cert_bad_email() {
)
]
);
}

View File

@ -1,7 +1,7 @@
[h3]What is Hubzilla?[/h3]
[h3]What is $Projectname?[/h3]
$Projectname is a [b]free and open source[/b] set of web applications and services running on a special kind of web server, called a "hub", that can connect to other hubs in a decentralised network we like to call "the grid", providing sophisticated communications, identity, and access control services which work together seamlessly across domains and independent websites. It allows anybody to publicly or [b]privately[/b] publish content via "channels", which are the fundamental, cryptographically secured identities that provide authentication independently of the hubs which host them. This revolutionary liberation of online identity from individual servers and domains is called "nomadic identity", and it is powered by the Zot protocol, a new framework for decentralised access control with fine-grained, extensible permissions.
[h3]Right... so what is Hubzilla?[/h3]
[h3]Right... so what is $Projectname?[/h3]
From the practical perspective of hub members who use the software, $Projectname offers a variety of familiar, integrated web apps and services, including:
[ul]
[li]social networking discussion threads[/li]
@ -15,14 +15,9 @@ While all of these apps and services can be found in other software packages, on
[h3]Software Stack[/h3]
The $Projectname software stack is a relatively standard webserver application written primarily in PHP/MySQL and [url=https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt]requiring little more than a web server, a MySQL-compatible database, and the PHP scripting language[/url]. It is designed to be easily installable by those with basic website administration skills on typical shared hosting platforms with a broad range of computing hardware. It is also easily extended via plugins and themes and other third-party tools.
[h3]Additional Resources and Links[/h3]
[list][*][url=http://hubzilla.org]Hubzilla project website[/url]
[*][url=https://github.com/redmatrix/hubzilla]Hubzilla core code repository[/url]
[*][url=https://github.com/redmatrix/hubzilla-addons]Hubzilla official addons repository[/url][/list]
[h3]Glossary[/h3]
[dl terms="b"]
[*= hub] An instance of the Hubzilla software running on a standard web server
[*= hub] An instance of this software running on a standard web server
[*= grid] The global network of hubs that exchange information with each other using the Zot protocol.

View File

@ -23,7 +23,7 @@
[*] friendica - Friendica (DFRN) protocol. Under development.
[*] frphotos - import photo albums from Friendica
[*] gnusoc - GNU-Social (OStatus) protocol. Under development.
[*] hexit - headecimal conversion tool
[*] hexit - hexadecimal conversion tool
[*] hubwall - send an admin email to all hub accounts
[*] ijpost - crosspost to Insanejournal
[*] irc - connect to IRC chatrooms

View File

@ -150,7 +150,7 @@ web-based administrative tools to function:
#### Official addons
##### Installation
Navigate to your webThen you should clone the addon repository (separately). We'll give this repository a nickname of 'hzaddons'. You can pull in other hubzilla addon repositories by giving them different nicknames::
Navigate to your website. Then you should clone the addon repository (separately). We'll give this repository a nickname of 'hzaddons'. You can pull in other hubzilla addon repositories by giving them different nicknames::
cd mywebsite
util/add_addon_repo https://github.com/redmatrix/hubzilla-addons.git hzaddons
@ -162,7 +162,7 @@ For keeping the addon tree updated, you should be on your top level website dire
util/update_addon_repo hzaddons
Create searchable representations of the online documentation. You may do this
any time that the documentation is updated :
any time that the documentation is updated :
cd mywebsite
util/importdoc
@ -196,59 +196,35 @@ The installation script was originally designed for a small hardware server behi
1. `service apache2 reload`
1. Open your domain with a browser and step throught the initial configuration of $Projectname.
### Server Roles
### Recommended Addons
$Projectname can be configured in many different ways. One of the configurations available at installation is to select a 'server role'. There are currently three server roles. We highly recommend that you use 'standard' unless you have special needs.
We recommend the following addons be installed on all public sites:
nsfw - hide inappropriate posts/comments
superblock - block content from offensive channels
### Federation Addons
Several web communities have begun to converge using common protocols. The protocols involved are somewhat limited in their abilities. The GNU-Social protocol for instance offers no privacy modes, and the Diaspora protocol is somewhat restrictive in what kinds of communications are allowed. All comments must be signed in a very unique manner by the original author. The ActivityPub protocol is also being considered and may be supported at a future date. No other existing protocol supports nomadic location as used by this project. This presents some support challenges as some features work with some networks and don't work with others. Nevertheless the federation protocols allow connections to be made to a much larger community of people worldwide. They are provided as addons.
> diaspora - The Diaspora Protocol used by Diaspora and Friendica. You should enable 'Diaspora Statistics' (statistics_json) first to enable all the available features.
> gnusoc - The GNU-Social Protocol, used by GNU-Social, Mastodon and several other communities. This addon requires you first install the 'pubsubhubbub' service (also an addon).
Each member of your site must choose whether or not to allow these protocols individually as they may conflict with several desirable core features and abilities of this software (such as channel migration and cloning). They do this from their 'Settings -> Feature/Addon Settings' page. The administrator may also set the following:
util/config system.diaspora_allowed 1
util/config system.gnusoc_allowed 1
and enable these protocols automatically for all newly created channels.
#### Basic
The 'basic' server role is designed to be relatively simple, and it doesn't present options
or complicated features. The hub admin may configure additional features at a site level.
This role is designed for simple social networking and social network federation. Many features
which do not federate easily have been removed, including (and this is somewhat important)
"nomadic identity". You may move a channel to or from a basic server, but you may not clone
it. Once moved, it becomes read-only on the origination site. No updates of any kind will be
provided. It is recommended that after the move, the original channel be deleted - as it is
no longer useable. The data remains only in case there are issues making a copy of the data.
This role is supported by the hubzilla community.
#### Standard
The 'standard' server role is recommended for most sites. All features of the software are
available to everybody unless locked by the hub administrator. Some features will not federate
easily with other networks, so there is often an increased support burden explaining why
sharing events with Diaspora (for instance) presents a different experience on that network.
Additionally any member can enable "advanced" or "expert" features, and these may be beyond
their technical skill level. This may also result in an increased support burden.
This role is supported by the hubzilla community.
#### Pro
The 'pro' server role is primarily designed for communities which want to present a uniform
experience and be relieved of many federation support issues. In this role there is
**no federation with other networks**. Additional features **may** be provided, such
as channel ratings, premium channels, and e-commerce.
By default a channel may set a "techlevel" appropriate to their technical skill. Higher
levels provide more features. Everybody starts with techlevel 0 (similar to the 'basic'
role) where all complicated features are hidden from view. Increasing the techlevel provides
more advanced or complex features.
The hub admin may also lock individual channels or their entire site at a defined techlevel
which provides an installation with a selection of advanced features consistent with the
perceived technical skills of the members. For instance, a community for horse racing might
have a different techlevel than a community for Linux kernel developers.
This role is not supported by the hubzilla community.
### Techlevels
Techlevels is a unique feature of Hubzilla 'pro'. It is not available in other server_roles, although it expands on the concepts introduced in $Projectname 'basic'.
We've implemented several different mechanisms in order to reduce the apparent complexity and learning curve presented to new members. At the same time, we do not wish to limit any functionality for people who are able to grasp some slightly advanced technical technical features. The first mechanism was to move several features to an optional 'Features' page where they could be enabled at will; with the default interface kept somewhat lean.
The problem we had now is that the number of features began to grow dramatically, and the Feature page is daunting in possibilities. There are also features present which probably should not be available to all members, but may be extremely useful to those with technical backgrounds.
@ -257,8 +233,7 @@ The techlevels seeeks to remedy this by grouping features within different level
When a new member registers, their account is provided a techlevel setting of 0. On the account settings page they may change this to any available level. A higher level opens more advanced features and possible interactions.
The account administrator may also lock a particular level, lock a maximum level, or change/re-arrange the features available to any level. Those with the minimum level are typically not very exploratory and are unlikely to discover the advanced modes. This is by design. Those that look around and desire more interactions will find them. In the absence of administrator defaults they may choose any level. As they look at the features available to the level in question, it is generally expected that they will discover some features are beyond their comprehension and it is hoped they will back off to a level where the interface and features are comfortable to their skill level. This is somewhat experimental at present and for that reason is not part of the 'standard' server role. The standard server role is preset to level '5', and the basic server role is preset to level '0', with no possibility of change. Members in these roles may find themselves overwhelmed or underwhelmed by the feature set and complexity.
The account administrator may also lock a particular level, lock a maximum level, or change/re-arrange the features available to any level. Those with the minimum level are typically not very exploratory and are unlikely to discover the advanced modes. This is by design. Those that look around and desire more interactions will find them. In the absence of administrator defaults they may choose any level. As they look at the features available to the level in question, it is generally expected that they will discover some features are beyond their comprehension and it is hoped they will back off to a level where the interface and features are comfortable to their skill level.
### Service Classes

10
doc/hook/legal_webbie.bb Normal file
View File

@ -0,0 +1,10 @@
[h2]legal_webbie[/h2]
Called when validating a channel address. By default the valid characters are
a-z,0-9,-,_, and . Uppercase ASCII characters are folded to lower and any invalid characters are stripped.
Some federated networks require more restrictive rules.
The hook is called with an array [ 'input' => (supplied text), 'output' => (validated text) ]
A plugin will generally perform a regex filter or text operation on 'input' and provide the results in 'output'.

View File

@ -0,0 +1,7 @@
[h2]legal_webbie_text[/h2]
Returns a string describing the text rules applied to legal_webbie().
Called with an array [ 'text' => (descriptive text describing text character limitations) ]
A plugin should return the description of the allowed characters and operation performed in the 'legal_webbie' hook to assist people when creating a new channel.

View File

@ -323,6 +323,12 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/jot_tool]jot_tool[/zrl]
Deprecated and possibly obsolete. Allows one to add action buttons to the post editor.
[zrl=[baseurl]/help/hook/legal_webbie]legal_webbie[/zrl]
Called to validate a channel address
[zrl=[baseurl]/help/hook/legal_webbie_text]legal_webbie_text[/zrl]
Provides an explanation of text/character restrictions for legal_webbie()
[zrl=[baseurl]/help/hook/load_pdl]load_pdl[/zrl]
Called when we load a PDL file or description

View File

@ -697,14 +697,8 @@ This places a block named &quot;contributors&quot; in this region. Additionally
The variable [var=wrap]none[/var] in a block removes the wrapping div element from the block.
[h4]Widgets[/h4]
Widgets are executable apps provided by the system which you can place on your page. Some widgets take arguments which allows you to tailor the widget to your purpose. (TODO: list available widgets and arguments). The base system provides
Widgets are executable apps provided by the system which you can place on your page. Some widgets take arguments which allows you to tailor the widget to your purpose. System widgets are listed [url=help/Widgets]here[/url]. Widgets can also ve created by plugins, themes, or your site administrator to provide additional functionality.
[code]
profile - widget which duplicates the profile sidebar of your channel page. This widget takes no arguments
tagcloud - provides a tag cloud of categories
count - maximum number of category tags to list
[/code]
Widgets and arguments are specified with the 'widget' and 'var' tags.
[code]

View File

@ -7,8 +7,8 @@
</div>
<div id="about" class="doco-section">
<div class="flex-column">
<a class="nav-link" href="/help/about/about_hubzilla">About Hubzilla</a>
<a class="nav-link" href="/help/about/hubzilla_project">Hubzilla project</a>
<a class="nav-link" href="/help/about/about">About</a>
<a class="nav-link" href="/help/about/project">Project</a>
<a class="nav-link" href="/help/about/about_hub">About this hub</a>
</div>
</div>

View File

@ -6,7 +6,7 @@ to a personal channel in a natural way.</p>
<h3 id="Create_a_new_channel">Create a new channel</h3>
<p>When you log in for the first time after registering, you must create a channel.
(Alternatively you can load https://grid.reticu.li/new_channel)</p>
(Alternatively you can visit https://your_website/new_channel)</p>
<p><img class="img-responsive" src="/help/tutorials/assets/c9a880cc82ffa1f7c2f460397bb083bf7dc2a2b8f065e64da598b45b4a2b.png" alt="image"></p>
@ -76,7 +76,7 @@ so you can specify exactly who can access this post.</p>
<h3 id="Use_an_uploaded_image_as_a_channel_cover_photo">Use an uploaded image as a channel cover photo</h3>
<p>One way to add some pizzazz your channel is to add a cover photo that visitors will
see when they load your channel page. Hubzilla's integrated cloud file system
see when they load your channel page. The integrated cloud file system
allows you to choose an existing photo for this purpose.</p>
<p>Visit your photos in the <strong>Photos</strong> app</p>
@ -99,9 +99,9 @@ channel page will fade in as you scroll down.</p>
<h3 id="Make_a_connection">Make a connection</h3>
<p>Making connections between channels to share things is what Hubzilla is all about.
<p>Making connections between channels to share things is what social communications are all about.
Making a connection is simple. If you do not already know how to reach a channel's home
page, you might try a directory search by opening the <strong>Directory</strong> link on the right
page, you might try a directory search by opening the <strong>Directory</strong> link from the menu on the right
side of the top navbar.</p>
<p><img class="img-responsive" src="/help/tutorials/assets/ef78bc6aa3fafebd46f353514c907b3fdfe019918fc5553bb3f31388a36f.png" alt="image"></p>
@ -160,4 +160,4 @@ editor by pressing the edit button beside the <strong>Delete</strong> button.</p
<p><img class="img-responsive" src="/help/tutorials/assets/c4cad3e4c356dd2a227df79bd4dc6d47edf1b66ea243f005b6b452ec366b.png" alt="image"></p>

BIN
images/red-koala.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/red-koala.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

151
images/red-koala.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

BIN
images/red-koala.xcf Normal file

Binary file not shown.

View File

@ -31,7 +31,7 @@ function check_account_email($email) {
if(! strlen($email))
return $result;
if((! valid_email($email)) || (! validate_email($email)))
if(! validate_email($email))
$result['message'] .= t('Not a valid email address') . EOL;
elseif(! allowed_email($email))
$result['message'] = t('Your email domain is not among those allowed on this site');
@ -105,6 +105,33 @@ function account_total() {
}
function account_store_lowlevel($arr) {
$store = [
'account_parent' => ((array_key_exists('account_parent',$arr)) ? $arr['account_parent'] : '0'),
'account_default_channel' => ((array_key_exists('account_default_channel',$arr)) ? $arr['account_default_channel'] : '0'),
'account_salt' => ((array_key_exists('account_salt',$arr)) ? $arr['account_salt'] : ''),
'account_password' => ((array_key_exists('account_password',$arr)) ? $arr['account_password'] : ''),
'account_email' => ((array_key_exists('account_email',$arr)) ? $arr['account_email'] : ''),
'account_external' => ((array_key_exists('account_external',$arr)) ? $arr['account_external'] : ''),
'account_language' => ((array_key_exists('account_language',$arr)) ? $arr['account_language'] : 'en'),
'account_created' => ((array_key_exists('account_created',$arr)) ? $arr['account_created'] : '0001-01-01 00:00:00'),
'account_lastlog' => ((array_key_exists('account_lastlog',$arr)) ? $arr['account_lastlog'] : '0001-01-01 00:00:00'),
'account_flags' => ((array_key_exists('account_flags',$arr)) ? $arr['account_flags'] : '0'),
'account_roles' => ((array_key_exists('account_roles',$arr)) ? $arr['account_roles'] : '0'),
'account_reset' => ((array_key_exists('account_reset',$arr)) ? $arr['account_reset'] : ''),
'account_expires' => ((array_key_exists('account_expires',$arr)) ? $arr['account_expires'] : '0001-01-01 00:00:00'),
'account_expire_notified' => ((array_key_exists('account_expire_notified',$arr)) ? $arr['account_expire_notified'] : '0001-01-01 00:00:00'),
'account_service_class' => ((array_key_exists('account_service_class',$arr)) ? $arr['account_service_class'] : ''),
'account_level' => ((array_key_exists('account_level',$arr)) ? $arr['account_level'] : '0'),
'account_password_changed' => ((array_key_exists('account_password_changed',$arr)) ? $arr['account_password_changed'] : '0001-01-01 00:00:00')
];
return create_table_from_array('account',$store);
}
function create_account($arr) {
// Required: { email, password }
@ -177,21 +204,20 @@ function create_account($arr) {
$salt = random_string(32);
$password_encoded = hash('whirlpool', $salt . $password);
$r = q("INSERT INTO account
( account_parent, account_salt, account_password, account_email, account_language,
account_created, account_flags, account_roles, account_level, account_expires, account_service_class )
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', '%s' )",
intval($parent),
dbesc($salt),
dbesc($password_encoded),
dbesc($email),
dbesc(get_best_language()),
dbesc(datetime_convert()),
intval($flags),
intval($roles),
intval($techlevel),
dbesc($expires),
dbesc($default_service_class)
$r = account_store_lowlevel(
[
'account_parent' => intval($parent),
'account_salt' => $salt,
'account_password' => $password_encoded,
'account_email' => $email,
'account_language' => get_best_language(),
'account_created' => datetime_convert(),
'account_flags' => intval($flags),
'account_roles' => intval($roles),
'account_level' => intval($techlevel),
'account_expires' => $expires,
'account_service_class' => $default_service_class
]
);
if(! $r) {
logger('create_account: DB INSERT failed.');
@ -246,16 +272,18 @@ function verify_email_address($arr) {
dbesc($arr['account']['account_language'])
);
//@fixme - get correct language template
push_lang(($arr['account']['account_language']) ? $arr['account']['account_language'] : 'en');
$email_msg = replace_macros(get_intltext_template('register_verify_member.tpl'), array(
'$sitename' => get_config('system','sitename'),
'$siteurl' => z_root(),
'$email' => $arr['email'],
'$uid' => $arr['account']['account_id'],
'$hash' => $hash,
'$details' => $details
));
$email_msg = replace_macros(get_intltext_template('register_verify_member.tpl'),
[
'$sitename' => get_config('system','sitename'),
'$siteurl' => z_root(),
'$email' => $arr['email'],
'$uid' => $arr['account']['account_id'],
'$hash' => $hash,
'$details' => $details
]
);
$res = z_mail(
[
@ -265,10 +293,12 @@ function verify_email_address($arr) {
]
);
pop_lang();
if($res)
$delivered ++;
else
logger('send_reg_approval_email: failed to ' . $admin['email'] . 'account_id: ' . $arr['account']['account_id']);
logger('send_reg_approval_email: failed to account_id: ' . $arr['account']['account_id']);
return $res;
}
@ -354,9 +384,9 @@ function send_register_success_email($email,$password) {
$res = z_mail(
[
'toEmail' => $email,
'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')),
'textVersion' => $email_msg,
'toEmail' => $email,
'messageSubject' => sprintf( t('Registration details for %s'), get_config('system','sitename')),
'textVersion' => $email_msg,
]
);
@ -424,7 +454,7 @@ function account_allow($hash) {
pop_lang();
if(get_config('system','auto_channel_create') || get_config('system','server_role') === 'basic')
if(get_config('system','auto_channel_create'))
auto_channel_create($register[0]['uid']);
if ($res) {
@ -525,19 +555,13 @@ function account_approve($hash) {
if(! $account)
return $ret;
if(get_config('system','auto_channel_create') || get_config('system','server_role') === 'basic')
if(get_config('system','auto_channel_create'))
auto_channel_create($register[0]['uid']);
else {
$_SESSION['login_return_url'] = 'new_channel';
authenticate_success($account[0],null,true,true,false,true);
}
// info( t('Account verified. Please login.') . EOL );
return true;
}
@ -772,12 +796,6 @@ function upgrade_bool_message($bbcode = false) {
function get_account_techlevel($account_id = 0) {
$role = \Zotlabs\Lib\System::get_server_role();
if($role == 'basic')
return 0;
if($role == 'standard')
return 5;
if(! $account_id) {
$x = \App::get_account();
}

View File

@ -194,15 +194,25 @@ require_once('include/api_zot.php');
else
$redirect = trim($_REQUEST['redirect_uris']);
$icon = trim($_REQUEST['logo_uri']);
$r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)
VALUES ('%s','%s','%s','%s','%s',%d)",
dbesc($key),
dbesc($secret),
dbesc($name),
dbesc($redirect),
dbesc($icon),
intval(0)
);
if($oauth2) {
$r = q("INSERT INTO oauth_clients (client_id, client_secret, redirect_uri, grant_types, scope, user_id)
VALUES ( '%s', '%s', '%s', null, null, null ) ",
dbesc($key),
dbesc($secret),
dbesc($redirect)
);
}
else {
$r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)
VALUES ('%s','%s','%s','%s','%s',%d)",
dbesc($key),
dbesc($secret),
dbesc($name),
dbesc($redirect),
dbesc($icon),
intval(0)
);
}
$ret['client_id'] = $key;
$ret['client_secret'] = $secret;

View File

@ -1231,6 +1231,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",$sub,$Text);
$Text = preg_replace("/\[event\](.*?)\[\/event\]/ism",'',$Text);
$Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);

View File

@ -258,6 +258,7 @@ function create_identity($arr) {
'channel_system' => intval($system),
'channel_expire_days' => intval($expire),
'channel_timezone' => App::$timezone
]
);
@ -1161,31 +1162,16 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
$location = $reddress = $pdesc = $gender = $marital = $homepage = False;
}
if($profile['gender']) {
$profile['gender_icon'] = gender_icon($profile['gender']);
}
$firstname = ((strpos($profile['channel_name'],' '))
? trim(substr($profile['channel_name'],0,strpos($profile['channel_name'],' '))) : $profile['channel_name']);
$lastname = (($firstname === $profile['channel_name']) ? '' : trim(substr($profile['channel_name'],strlen($firstname))));
// @fixme move this to the diaspora plugin itself
if(plugin_is_installed('diaspora')) {
$diaspora = array(
'podloc' => z_root(),
'guid' => $profile['channel_guid'] . str_replace('.','',App::get_hostname()),
'pubkey' => pemtorsa($profile['channel_pubkey']),
'searchable' => (($block) ? 'false' : 'true'),
'nickname' => $profile['channel_address'],
'fullname' => $profile['channel_name'],
'firstname' => $firstname,
'lastname' => $lastname,
'photo300' => z_root() . '/photo/profile/300/' . $profile['uid'] . '.jpg',
'photo100' => z_root() . '/photo/profile/100/' . $profile['uid'] . '.jpg',
'photo50' => z_root() . '/photo/profile/50/' . $profile['uid'] . '.jpg',
);
}
else
$diaspora = '';
$contact_block = contact_block();
$channel_menu = false;
@ -1218,7 +1204,6 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
'$marital' => $marital,
'$homepage' => $homepage,
'$chanmenu' => $channel_menu,
'$diaspora' => $diaspora,
'$reddress' => $reddress,
'$rating' => '',
'$contact_block' => $contact_block,
@ -1229,7 +1214,29 @@ function profile_sidebar($profile, $block = 0, $show_connect = true, $zcard = fa
call_hooks('profile_sidebar', $arr);
return $o;
return $arr['entry'];
}
function gender_icon($gender) {
// logger('gender: ' . $gender);
// This can easily get throw off if the observer language is different
// than the channel owner language.
if(strpos(strtolower($gender),strtolower(t('Female'))) !== false)
return 'venus';
if(strpos(strtolower($gender),strtolower(t('Male'))) !== false)
return 'mars';
if(strpos(strtolower($gender),strtolower(t('Trans'))) !== false)
return 'transgender';
if(strpos(strtolower($gender),strtolower(t('Neuter'))) !== false)
return 'neuter';
if(strpos(strtolower($gender),strtolower(t('Non-specific'))) !== false)
return 'genderless';
return '';
}
@ -1998,49 +2005,48 @@ function remote_login() {
}
function channel_store_lowlevel($arr) {
$store = [
'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'),
'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'),
'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''),
'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''),
'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''),
'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''),
'channel_hash' => ((array_key_exists('channel_hash',$arr)) ? $arr['channel_hash'] : ''),
'channel_timezone' => ((array_key_exists('channel_timezone',$arr)) ? $arr['channel_timezone'] : 'UTC'),
'channel_location' => ((array_key_exists('channel_location',$arr)) ? $arr['channel_location'] : ''),
'channel_theme' => ((array_key_exists('channel_theme',$arr)) ? $arr['channel_theme'] : ''),
'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''),
'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''),
'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''),
'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'),
'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'),
'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE),
'channel_lastpost' => ((array_key_exists('channel_lastpost',$arr)) ? $arr['channel_lastpost'] : NULL_DATE),
'channel_deleted' => ((array_key_exists('channel_deleted',$arr)) ? $arr['channel_deleted'] : NULL_DATE),
'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail',$arr)) ? $arr['channel_max_anon_mail'] : '10'),
'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req',$arr)) ? $arr['channel_max_friend_req'] : '10'),
'channel_expire_days' => ((array_key_exists('channel_expire_days',$arr)) ? $arr['channel_expire_days'] : '0'),
'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset',$arr)) ? $arr['channel_passwd_reset'] : ''),
'channel_default_group' => ((array_key_exists('channel_default_group',$arr)) ? $arr['channel_default_group'] : ''),
'channel_allow_cid' => ((array_key_exists('channel_allow_cid',$arr)) ? $arr['channel_allow_cid'] : ''),
'channel_allow_gid' => ((array_key_exists('channel_allow_gid',$arr)) ? $arr['channel_allow_gid'] : ''),
'channel_deny_cid' => ((array_key_exists('channel_deny_cid',$arr)) ? $arr['channel_deny_cid'] : ''),
'channel_deny_gid' => ((array_key_exists('channel_deny_gid',$arr)) ? $arr['channel_deny_gid'] : ''),
'channel_removed' => ((array_key_exists('channel_removed',$arr)) ? $arr['channel_removed'] : '0'),
'channel_system' => ((array_key_exists('channel_system',$arr)) ? $arr['channel_system'] : '0'),
$store = [
'channel_account_id' => ((array_key_exists('channel_account_id',$arr)) ? $arr['channel_account_id'] : '0'),
'channel_primary' => ((array_key_exists('channel_primary',$arr)) ? $arr['channel_primary'] : '0'),
'channel_name' => ((array_key_exists('channel_name',$arr)) ? $arr['channel_name'] : ''),
'channel_address' => ((array_key_exists('channel_address',$arr)) ? $arr['channel_address'] : ''),
'channel_guid' => ((array_key_exists('channel_guid',$arr)) ? $arr['channel_guid'] : ''),
'channel_guid_sig' => ((array_key_exists('channel_guid_sig',$arr)) ? $arr['channel_guid_sig'] : ''),
'channel_hash' => ((array_key_exists('channel_hash',$arr)) ? $arr['channel_hash'] : ''),
'channel_timezone' => ((array_key_exists('channel_timezone',$arr)) ? $arr['channel_timezone'] : 'UTC'),
'channel_location' => ((array_key_exists('channel_location',$arr)) ? $arr['channel_location'] : ''),
'channel_theme' => ((array_key_exists('channel_theme',$arr)) ? $arr['channel_theme'] : ''),
'channel_startpage' => ((array_key_exists('channel_startpage',$arr)) ? $arr['channel_startpage'] : ''),
'channel_pubkey' => ((array_key_exists('channel_pubkey',$arr)) ? $arr['channel_pubkey'] : ''),
'channel_prvkey' => ((array_key_exists('channel_prvkey',$arr)) ? $arr['channel_prvkey'] : ''),
'channel_notifyflags' => ((array_key_exists('channel_notifyflags',$arr)) ? $arr['channel_notifyflags'] : '65535'),
'channel_pageflags' => ((array_key_exists('channel_pageflags',$arr)) ? $arr['channel_pageflags'] : '0'),
'channel_dirdate' => ((array_key_exists('channel_dirdate',$arr)) ? $arr['channel_dirdate'] : NULL_DATE),
'channel_lastpost' => ((array_key_exists('channel_lastpost',$arr)) ? $arr['channel_lastpost'] : NULL_DATE),
'channel_deleted' => ((array_key_exists('channel_deleted',$arr)) ? $arr['channel_deleted'] : NULL_DATE),
'channel_max_anon_mail' => ((array_key_exists('channel_max_anon_mail',$arr)) ? $arr['channel_max_anon_mail'] : '10'),
'channel_max_friend_req' => ((array_key_exists('channel_max_friend_req',$arr)) ? $arr['channel_max_friend_req'] : '10'),
'channel_expire_days' => ((array_key_exists('channel_expire_days',$arr)) ? $arr['channel_expire_days'] : '0'),
'channel_passwd_reset' => ((array_key_exists('channel_passwd_reset',$arr)) ? $arr['channel_passwd_reset'] : ''),
'channel_default_group' => ((array_key_exists('channel_default_group',$arr)) ? $arr['channel_default_group'] : ''),
'channel_allow_cid' => ((array_key_exists('channel_allow_cid',$arr)) ? $arr['channel_allow_cid'] : ''),
'channel_allow_gid' => ((array_key_exists('channel_allow_gid',$arr)) ? $arr['channel_allow_gid'] : ''),
'channel_deny_cid' => ((array_key_exists('channel_deny_cid',$arr)) ? $arr['channel_deny_cid'] : ''),
'channel_deny_gid' => ((array_key_exists('channel_deny_gid',$arr)) ? $arr['channel_deny_gid'] : ''),
'channel_removed' => ((array_key_exists('channel_removed',$arr)) ? $arr['channel_removed'] : '0'),
'channel_system' => ((array_key_exists('channel_system',$arr)) ? $arr['channel_system'] : '0'),
'channel_moved' => ((array_key_exists('channel_moved',$arr)) ? $arr['channel_moved'] : ''),
'channel_password' => ((array_key_exists('channel_password',$arr)) ? $arr['channel_password'] : ''),
'channel_salt' => ((array_key_exists('channel_salt',$arr)) ? $arr['channel_salt'] : '')
];
return create_table_from_array('channel',$store);
}
function profile_store_lowlevel($arr) {
$store = [
@ -2322,6 +2328,7 @@ function channel_codeallowed($channel_id) {
return true;
return false;
}
function anon_identity_init($reqvars) {
@ -2391,5 +2398,6 @@ function anon_identity_init($reqvars) {
}
return $x[0];
}

View File

@ -634,8 +634,8 @@ function get_vcard_array($vc,$id) {
'address' => $adr->getParts()
];
$last_entry = end($adrs);
if($last_entry['address'])
array_walk($last_entry['address'],'array_escape_tags');
if($last_entry && is_array($adrs[$last_entry]['address']))
array_walk($adrs[$last_entry]['address'],'array_escape_tags');
}
}

View File

@ -442,7 +442,6 @@ function is_edit_activity($item) {
* figures out how to determine page owner and other contextual items
* that are based on unique features of the calling module.
*
* @param App &$a
* @param array $items
* @param string $mode
* @param boolean $update
@ -450,7 +449,7 @@ function is_edit_activity($item) {
* @param string $prepared_item
* @return string
*/
function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $prepared_item = '') {
function conversation($items, $mode, $update, $page_mode = 'traditional', $prepared_item = '') {
$content_html = '';
$o = '';

View File

@ -344,11 +344,8 @@ function q($sql) {
if(\DBA::$dba && \DBA::$dba->connected) {
$stmt = vsprintf($sql, $args);
if($stmt === false) {
if(version_compare(PHP_VERSION, '5.4.0') >= 0)
db_logger('dba: vsprintf error: ' .
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true),LOGGER_NORMAL,LOG_CRIT);
else
db_logger('dba: vsprintf error: ' . print_r(debug_backtrace(), true),LOGGER_NORMAL,LOG_CRIT);
db_logger('dba: vsprintf error: ' .
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1), true),LOGGER_NORMAL,LOG_CRIT);
}
if(\DBA::$dba->debug)
db_logger('Sql: ' . $stmt, LOGGER_DEBUG, LOG_INFO);
@ -445,6 +442,20 @@ function db_getfunc($f) {
return $f;
}
function db_load_file($f) {
// db errors should get logged to the logfile
$str = @file_get_contents($f);
$arr = explode(';', $str);
if($arr) {
foreach($arr as $a) {
if(strlen(trim($a))) {
$r = dbq(trim($a));
}
}
}
}
// The logger function may make DB calls internally to query the system logging parameters.
// This can cause a recursion if database debugging is enabled.
// So this function preserves the current database debugging state and then turns it off

View File

@ -74,19 +74,19 @@ class dba_pdo extends dba_driver {
return $result;
}
if($this->debug) {
db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($result) . ' results.', LOGGER_NORMAL, LOG_INFO);
}
$r = array();
if($result) {
foreach($result as $x) {
$r[] = $x;
}
if($this->debug) {
db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
}
}
if($this->debug) {
db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO);
db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO);
}
return (($this->error) ? false : $r);
}

View File

@ -210,6 +210,10 @@ function format_event_bbcode($ev) {
$o = '';
if($ev['event_vdata']) {
$o .= '[event]' . $ev['event_vdata'] . '[/event]';
}
if($ev['summary'])
$o .= '[event-summary]' . $ev['summary'] . '[/event-summary]';
@ -1232,3 +1236,71 @@ function tasks_fetch($arr) {
return $ret;
}
function cdav_principal($uri) {
$r = q("SELECT uri FROM principals WHERE uri = '%s' LIMIT 1",
dbesc($uri)
);
if($r[0]['uri'] === $uri)
return true;
else
return false;
}
function cdav_perms($needle, $haystack, $check_rw = false) {
foreach ($haystack as $item) {
if($check_rw) {
if(is_array($item['id'])) {
if ($item['id'][0] == $needle && $item['share-access'] != 2) {
return $item['{DAV:}displayname'];
}
}
else {
if ($item['id'] == $needle && $item['share-access'] != 2) {
return $item['{DAV:}displayname'];
}
}
}
else {
if(is_array($item['id'])) {
if ($item['id'][0] == $needle) {
return $item['{DAV:}displayname'];
}
}
else {
if ($item['id'] == $needle) {
return $item['{DAV:}displayname'];
}
}
}
}
return false;
}
function translate_type($type) {
if(!$type)
return;
$type = strtoupper($type);
$map = [
'CELL' => t('Mobile'),
'HOME' => t('Home'),
'HOME,VOICE' => t('Home, Voice'),
'HOME,FAX' => t('Home, Fax'),
'WORK' => t('Work'),
'WORK,VOICE' => t('Work, Voice'),
'WORK,FAX' => t('Work, Fax'),
'OTHER' => t('Other')
];
if (array_key_exists($type, $map)) {
return [$type, $map[$type]];
}
else {
return [$type, t('Other') . ' (' . $type . ')'];
}
}

View File

@ -45,10 +45,6 @@ function feature_level($feature,$def) {
function get_features($filtered = true) {
$server_role = \Zotlabs\Lib\System::get_server_role();
if($server_role === 'basic' && $filtered)
return array();
$arr = [
@ -424,16 +420,15 @@ function get_features($filtered = true) {
];
if($server_role === 'pro') {
$arr['general'][] = [
'premium_channel',
t('Premium Channel'),
t('Allows you to set restrictions and terms on those that connect with your channel'),
false,
get_config('feature_lock','premium_channel'),
feature_level('premium_channel',4),
];
}
$arr['general'][] = [
'premium_channel',
t('Premium Channel'),
t('Allows you to set restrictions and terms on those that connect with your channel'),
false,
get_config('feature_lock','premium_channel'),
feature_level('premium_channel',4),
];
$techlevel = get_account_techlevel();

View File

@ -246,9 +246,17 @@ function get_atom_elements($feed, $item, &$author) {
$found_author = $item->get_author();
if($found_author) {
if($rawauthor) {
if($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data'])
$author['full_name'] = unxmlify($rawauthor[0]['child'][NAMESPACE_POCO]['displayName'][0]['data']);
}
$author['author_name'] = unxmlify($found_author->get_name());
$author['author_link'] = unxmlify($found_author->get_link());
$author['author_is_feed'] = false;
$rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
logger('rawauthor: ' . print_r($rawauthor, true));
}
else {
$author['author_name'] = unxmlify($feed->get_title());
@ -305,12 +313,6 @@ function get_atom_elements($feed, $item, &$author) {
$res['verb'] = unxmlify($rawverb[0]['data']);
}
// translate OStatus unfollow to activity streams if it happened to get selected
if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) {
$res['verb'] = ACTIVITY_UNFOLLOW;
}
// look for a photo. We should check media size and find the best one,
// but for now let's just find any author photo
@ -393,6 +395,7 @@ function get_atom_elements($feed, $item, &$author) {
if($rawcnv) {
$ostatus_conversation = normalise_id(unxmlify($rawcnv[0]['attribs']['']['ref']));
set_iconfig($res,'ostatus','conversation',$ostatus_conversation,true);
logger('ostatus_conversation: ' . $ostatus_conversation, LOGGER_DATA, LOG_INFO);
}
$ostatus_protocol = (($ostatus_conversation) ? true : false);
@ -406,6 +409,21 @@ function get_atom_elements($feed, $item, &$author) {
$res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source']));
}
if($ostatus_protocol) {
// translate OStatus unfollow to activity streams if it happened to get selected
if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow')) {
$res['verb'] = ACTIVITY_UNFOLLOW;
}
// And OStatus 'favorite' is pretty much what we call 'like' on other networks
if((x($res,'verb')) && ($res['verb'] === ACTIVITY_FAVORITE)) {
$res['verb'] = ACTIVITY_LIKE;
}
}
/*
* If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it.
*/
@ -603,10 +621,17 @@ function get_atom_elements($feed, $item, &$author) {
if(! $type)
$type = 'application/octet-stream';
if(($ostatus_protocol) && (strpos($type,'image') === 0) && (strpos($res['body'],$link) === false) && (strpos($link,'http') === 0)) {
$res['body'] .= "\n\n" . '[img]' . $link . '[/img]';
if($ostatus_protocol) {
if((strpos($type,'image') === 0) && (strpos($res['body'], ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) {
$res['body'] .= "\n\n" . '[img]' . $link . '[/img]';
}
if((strpos($type,'video') === 0) && (strpos($res['body'], ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) {
$res['body'] .= "\n\n" . '[video]' . $link . '[/video]';
}
if((strpos($type,'audio') === 0) && (strpos($res['body'], ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) {
$res['body'] .= "\n\n" . '[audio]' . $link . '[/audio]';
}
}
$res['attach'][] = array('href' => $link, 'length' => $len, 'type' => $type, 'title' => $title );
}
}
@ -691,7 +716,7 @@ function get_atom_elements($feed, $item, &$author) {
if(array_key_exists('verb',$res) && $res['verb'] === ACTIVITY_SHARE
&& array_key_exists('obj_type',$res) && $res['obj_type'] === ACTIVITY_OBJ_NOTE) {
&& array_key_exists('obj_type',$res) && in_array($res['obj_type'], [ ACTIVITY_OBJ_NOTE, ACTIVITY_OBJ_COMMENT, ACTIVITY_OBJ_ACTIVITY ] )) {
feed_get_reshare($res,$item);
}
@ -798,9 +823,15 @@ function feed_get_reshare(&$res,$item) {
if(! $type)
$type = 'application/octet-stream';
if((strpos($type,'image') === 0) && (strpos($body,$link) === false) && (strpos($link,'http') === 0)) {
if((strpos($type,'image') === 0) && (strpos($body, ']' . $link . '[/img]') === false) && (strpos($link,'http') === 0)) {
$body .= "\n\n" . '[img]' . $link . '[/img]';
}
if((strpos($type,'video') === 0) && (strpos($body, ']' . $link . '[/video]') === false) && (strpos($link,'http') === 0)) {
$body .= "\n\n" . '[video]' . $link . '[/video]';
}
if((strpos($type,'audio') === 0) && (strpos($body, ']' . $link . '[/audio]') === false) && (strpos($link,'http') === 0)) {
$body .= "\n\n" . '[audio]' . $link . '[/audio]';
}
}
}
@ -958,6 +989,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
foreach($items as $item) {
$is_reply = false;
$parent_link = '';
logger('processing ' . $item->get_id(), LOGGER_DEBUG);
@ -966,6 +998,9 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
$is_reply = true;
$parent_mid = normalise_id($rawthread[0]['attribs']['']['ref']);
}
if(isset($rawthread[0]['attribs']['']['href'])) {
$parent_link = $rawthread[0]['attribs']['']['href'];
}
if($is_reply) {
@ -995,7 +1030,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
$datarray['author_xchan'] = '';
if($author['author_link'] != $contact['xchan_url']) {
$x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
$name = '';
if($author['full_name']) {
$name = $author['full_name'];
if($author['author_name'])
$name .= ' (' . $author['author_name'] . ')';
}
else {
$name = $author['author_name'];
}
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
if($x)
$datarray['author_xchan'] = $x;
}
@ -1037,7 +1081,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
intval($importer['channel_id'])
);
if($c) {
$pmid = $x[0]['parent_mid'];
$pmid = $c[0]['parent_mid'];
$datarray['parent_mid'] = $pmid;
}
}
@ -1052,6 +1096,44 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
$datarray['parent_mid'] = $pmid;
}
}
if((! $pmid) && $parent_link !== '') {
$f = feed_conversation_fetch($importer,$contact,$parent_link);
if($f) {
// check both potential conversation parents again
if($conv_id) {
$c = q("select parent_mid from item left join iconfig on item.id = iconfig.iid where iconfig.cat = 'ostatus' and iconfig.k = 'conversation' and iconfig.v = '%s' and item.uid = %d order by item.id limit 1",
dbesc($conv_id),
intval($importer['channel_id'])
);
if($c) {
$pmid = $c[0]['parent_mid'];
$datarray['parent_mid'] = $pmid;
}
}
if(! $pmid) {
$x = q("select parent_mid from item where mid = '%s' and uid = %d limit 1",
dbesc($parent_mid),
intval($importer['channel_id'])
);
if($x) {
$pmid = $x[0]['parent_mid'];
$datarray['parent_mid'] = $pmid;
}
}
}
// the conversation parent might just be the post we are trying to import.
// check existence again in case it was just delivered.
$r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d LIMIT 1",
dbesc($datarray['mid']),
intval($importer['channel_id'])
);
if($r) {
continue;
}
}
if(! $pmid) {
@ -1116,7 +1198,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
}
if($author['author_link'] != $contact['xchan_url']) {
$x = import_author_unknown(array('name' => $author['author_name'],'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
$name = '';
if($author['full_name']) {
$name = $author['full_name'];
if($author['author_name'])
$name .= ' (' . $author['author_name'] . ')';
}
else {
$name = $author['author_name'];
}
$x = import_author_unknown(array('name' => $name,'url' => $author['author_link'],'photo' => array('src' => $author['author_photo'])));
if($x)
$datarray['author_xchan'] = $x;
}
@ -1182,6 +1273,51 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
}
}
function feed_conversation_fetch($importer,$contact,$parent_link) {
logger('parent_link: ' . $parent_link, LOGGER_DEBUG, LOG_INFO);
$link = '';
// GNU-Social flavoured feeds
if(strpos($parent_link,'/notice/')) {
$link = str_replace('/notice/','/api/statuses/show/',$parent_link) . '.atom';
}
// Mastodon flavoured feeds
if(strpos($parent_link,'/users/') && strpos($parent_link,'/updates/')) {
$link = $parent_link . '.atom';
}
if(! $link)
return false;
logger('fetching: ' . $link, LOGGER_DEBUG, LOG_INFO);
$fetch = z_fetch_url($link);
if(! $fetch['success'])
return false;
$data = $fetch['body'];
// We will probably receive an atom 'entry' and not an atom 'feed'. Unfortunately
// our parser is a bit strict about compliance so we'll insert just enough of a feed
// tag to trick it into believing it's a compliant feed.
if(! strstr($data,'<feed')) {
$data = str_replace('<entry ','<feed xmlns="http://www.w3.org/2005/Atom"><entry ',$data);
$data .= '</feed>';
}
consume_feed($data,$importer,$contact,1);
consume_feed($data,$importer,$contact,2);
return true;
}
/**
* @brief Normalise an id.
*

View File

@ -226,12 +226,12 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
if($abook_instance)
$abook_instance .= ',';
$abook_instance .= z_root();
}
$x = q("update abook set abook_instance = '%s' where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
);
$x = q("update abook set abook_instance = '%s', abook_not_here = 0 where abook_id = %d",
dbesc($abook_instance),
intval($r[0]['abook_id'])
);
}
if(intval($r[0]['abook_pending'])) {
$x = q("update abook set abook_pending = 0 where abook_id = %d",

View File

@ -57,7 +57,7 @@ function get_help_content($tocpath = false) {
if(! $text) {
$doctype = 'bbcode';
$text = load_doc_file('doc/main.bb');
goaway('/help/about/about_hubzilla');
goaway('/help/about/about');
\App::$page['title'] = t('Help');
}
@ -116,9 +116,11 @@ function load_doc_file($s) {
$b = basename($s);
$d = dirname($s);
$c = find_doc_file("$d/$lang/$b");
if($c)
return $c;
if($dirname !== '-') {
$c = find_doc_file("$d/$lang/$b");
if($c)
return $c;
}
$c = find_doc_file($s);
if($c)
return $c;
@ -140,8 +142,8 @@ function find_doc_file($s) {
*/
function search_doc_files($s) {
$itemspage = get_pconfig(local_channel(),'system','itemspage');
\App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20));
\App::set_pager_itemspage(60);
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start']));
$regexop = db_getfunc('REGEXP');
@ -198,6 +200,7 @@ function doc_rank_sort($s1, $s2) {
*
* @return string
*/
function load_context_help() {
$path = App::$cmd;

View File

@ -631,12 +631,6 @@ function import_items($channel, $items, $sync = false, $relocate = null) {
fix_attached_file_permissions($channel,$item['author_xchan'],$item['body'],$item['allow_cid'],$item['allow_gid'],$item['deny_cid'],$item['deny_gid']);
if($sync && $item['item_wall']) {
// deliver singletons if we have any
if($item_result && $item_result['success']) {
Zotlabs\Daemon\Master::Summon( [ 'Notifier','single_activity',$item_result['item_id'] ]);
}
}
}
}
}
@ -1010,9 +1004,6 @@ function import_mail($channel, $mails, $sync = false) {
$m['aid'] = $channel['channel_account_id'];
$m['uid'] = $channel['channel_id'];
$mail_id = mail_store($m);
if($sync && $mail_id) {
Zotlabs\Daemon\Master::Summon(array('Notifier','single_mail',$mail_id));
}
}
}
}

View File

@ -8,6 +8,7 @@ use Zotlabs\Lib as Zlib;
require_once('include/bbcode.php');
require_once('include/oembed.php');
require_once('include/crypto.php');
require_once('include/message.php');
require_once('include/feedutils.php');
require_once('include/photo/photo_driver.php');
require_once('include/permissions.php');
@ -260,8 +261,6 @@ function can_comment_on_post($observer_xchan, $item) {
}
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red'))
return true;
if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'diaspora'))
return true;
if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],App::get_hostname()))
return true;
@ -599,11 +598,6 @@ function get_item_elements($x,$allow_code = false) {
$arr['sig'] = (($x['signature']) ? htmlspecialchars($x['signature'], ENT_COMPAT,'UTF-8',false) : '');
if(array_key_exists('diaspora_signature',$x) && is_array($x['diaspora_signature']))
$x['diaspora_signature'] = json_encode($x['diaspora_signature']);
$arr['diaspora_meta'] = (($x['diaspora_signature']) ? $x['diaspora_signature'] : '');
$arr['obj'] = activity_sanitise($x['object']);
$arr['target'] = activity_sanitise($x['target']);
@ -809,8 +803,10 @@ function import_author_xchan($x) {
if((! array_key_exists('network', $x)) || ($x['network'] === 'zot')) {
$y = import_author_zot($x);
}
if(! $y)
$y = import_author_diaspora($x);
// if we were told that it's a zot connection, don't probe/import anything else
if(array_key_exists('network',$x) && $x['network'] === 'zot')
return $y;
if($x['network'] === 'rss') {
$y = import_author_rss($x);
@ -821,36 +817,7 @@ function import_author_xchan($x) {
}
return($y);
}
/**
* @brief Imports an author from Diaspora.
*
* @param array $x an associative array with
* * \e string \b address
* @return boolean|string false on error, otherwise xchan_hash of the new entry
*/
function import_author_diaspora($x) {
if(! $x['address'])
return false;
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
dbesc($x['address'])
);
if($r) {
logger('in_cache: ' . $x['address'], LOGGER_DATA);
return $r[0]['xchan_hash'];
}
if(discover_by_webbie($x['address'])) {
$r = q("select xchan_hash from xchan where xchan_addr = '%s' limit 1",
dbesc($x['address'])
);
if($r)
return $r[0]['xchan_hash'];
}
return false;
}
/**
@ -862,6 +829,7 @@ function import_author_diaspora($x) {
* * \e string \b guid
* @return boolean|string
*/
function import_author_rss($x) {
if(! $x['url'])
return false;
@ -909,6 +877,11 @@ function import_author_rss($x) {
function import_author_unknown($x) {
$arr = [ 'author' => $x, 'result' => false ];
call_hooks('import_author', $arr);
if($arr['result'])
return $arr['result'];
if(! $x['url'])
return false;
@ -1068,17 +1041,7 @@ function encode_item($item,$mirror = false) {
if($item['iconfig'])
$x['meta'] = encode_item_meta($item['iconfig'],$mirror);
if($item['diaspora_meta']) {
$z = json_decode($item['diaspora_meta'],true);
if($z) {
if(is_array($z) && array_key_exists('iv',$z))
$x['diaspora_signature'] = crypto_unencapsulate($z,$key);
else
$x['diaspora_signature'] = $z;
if(! is_array($z))
logger('encode_item: diaspora meta is not an array: ' . print_r($z,true));
}
}
logger('encode_item: ' . print_r($x,true), LOGGER_DATA);
return $x;
@ -1359,7 +1322,6 @@ function encode_mail($item,$extended = false) {
$x['message_parent'] = $item['parent_mid'];
$x['created'] = $item['created'];
$x['expires'] = $item['expires'];
$x['diaspora_meta'] = $item['diaspora_meta'];
$x['title'] = $item['title'];
$x['body'] = $item['body'];
$x['from'] = encode_item_xchan($item['from']);
@ -1581,7 +1543,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['title'] = ((array_key_exists('title',$arr) && strlen($arr['title'])) ? trim($arr['title']) : '');
$arr['body'] = ((array_key_exists('body',$arr) && strlen($arr['body'])) ? trim($arr['body']) : '');
$arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : '');
$arr['allow_cid'] = ((x($arr,'allow_cid')) ? trim($arr['allow_cid']) : '');
$arr['allow_gid'] = ((x($arr,'allow_gid')) ? trim($arr['allow_gid']) : '');
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : '');
@ -2081,7 +2042,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
$arr['changed'] = $orig[0]['changed'];
$arr['route'] = ((array_key_exists('route',$arr)) ? trim($arr['route']) : $orig[0]['route']);
$arr['diaspora_meta'] = ((x($arr,'diaspora_meta')) ? $arr['diaspora_meta'] : $orig[0]['diaspora_meta']);
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : $orig[0]['location']);
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : $orig[0]['coord']);
$arr['verb'] = ((x($arr,'verb')) ? notags(trim($arr['verb'])) : $orig[0]['verb']);
@ -2240,55 +2201,6 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id, $walltowall = false) {
// We won't be able to sign Diaspora comments for authenticated visitors
// - we don't have their private key
// since Diaspora doesn't handle edits we can only do this for the original text and not update it.
require_once('include/markdown.php');
$signed_body = bb2diaspora_itembody($datarray,$walltowall);
if($walltowall) {
logger('wall to wall comment',LOGGER_DEBUG);
// post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
$signed_body = "\n\n"
. '![' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_photo_m'] . ')'
. '[' . $datarray['author']['xchan_name'] . '](' . $datarray['author']['xchan_url'] . ')' . "\n\n"
. $signed_body;
}
logger('storing diaspora comment signature',LOGGER_DEBUG);
$diaspora_handle = channel_reddress($channel);
$signed_text = $datarray['mid'] . ';' . $parent_item['mid'] . ';' . $signed_body . ';' . $diaspora_handle;
if( $channel && $channel['channel_prvkey'] )
$authorsig = base64_encode(rsa_sign($signed_text, $channel['channel_prvkey'], 'sha256'));
else
$authorsig = '';
$x = array('signer' => $diaspora_handle, 'body' => $signed_body, 'signed_text' => $signed_text, 'signature' => $authorsig);
$y = json_encode($x);
$r = q("update item set diaspora_meta = '%s' where id = %d",
dbesc($y),
intval($post_id)
);
if(! $r)
logger('store_diaspora_comment_sig: DB write failed');
return;
}
function send_status_notifications($post_id,$item) {
// only send notifications for comments
@ -3021,6 +2933,8 @@ function mail_store($arr) {
return 0;
}
$channel = channelx_by_n($arr['channel_id']);
if(! $arr['mail_obscured']) {
if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
$arr['body'] = escape_tags($arr['body']);
@ -3051,11 +2965,34 @@ function mail_store($arr) {
$arr['mail_flags'] = ((x($arr,'mail_flags')) ? intval($arr['mail_flags']) : 0 );
$arr['mail_raw'] = ((x($arr,'mail_raw')) ? intval($arr['mail_raw']) : 0 );
if(! $arr['parent_mid']) {
if($arr['parent_mid']) {
$parent_item = q("select * from mail where mid = '%s' and channel_id = %d limit 1",
dbesc($arr['parent_mid']),
intval($arr['channel_id'])
);
if(($parent_item) && (! $arr['conv_guid'])) {
$arr['conv_guid'] = $parent_item[0]['conv_guid'];
}
}
else {
logger('mail_store: missing parent');
$arr['parent_mid'] = $arr['mid'];
}
if($arr['from_xchan'] === $channel['channel_hash'])
$conversant = $arr['to_xchan'];
else
$conversant = $arr['from_xchan'];
if(! $arr['conv_guid']) {
$x = create_conversation($channel,$conversant,(($arr['title']) ? base64url_decode(str_rot47($arr['title'])) : ''));
$arr['conv_guid'] = (($x) ? $x['guid'] : '');
}
$r = q("SELECT id FROM mail WHERE mid = '%s' AND channel_id = %d LIMIT 1",
dbesc($arr['mid']),
intval($arr['channel_id'])
@ -3120,6 +3057,14 @@ function mail_store($arr) {
Zlib\Enotify::submit($notif_params);
}
if($arr['conv_guid']) {
$c = q("update conv set updated = '%s' where guid = '%s' and uid = %d",
dbesc(datetime_convert()),
dbesc($arr['conv_guid']),
intval($arr['channel_id'])
);
}
call_hooks('post_mail_end',$arr);
return $current_post;
}

View File

@ -13,71 +13,6 @@ require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
function diaspora_mention_callback($matches) {
$webbie = $matches[2] . '@' . $matches[3];
$link = '';
if($webbie) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1",
dbesc($webbie)
);
if(! $r) {
$x = discover_by_webbie($webbie);
if($x) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1",
dbesc($webbie)
);
}
}
if($r)
$link = $r[0]['xchan_url'];
}
if(! $link)
$link = 'https://' . $matches[3] . '/u/' . $matches[2];
if($r && $r[0]['hubloc_network'] === 'zot')
return '@[zrl=' . $link . ']' . trim($matches[1]) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/zrl]' ;
else
return '@[url=' . $link . ']' . trim($matches[1]) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/url]' ;
}
function diaspora_mention_callback2($matches) {
$webbie = $matches[1] . '@' . $matches[2];
$link = '';
if($webbie) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1",
dbesc($webbie)
);
if(! $r) {
$x = discover_by_webbie($webbie);
if($x) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash where hubloc_addr = '%s' limit 1",
dbesc($webbie)
);
}
}
if($r)
$link = $r[0]['xchan_url'];
}
$name = (($r) ? $r[0]['xchan_name'] : $matches[1]);
if(! $link)
$link = 'https://' . $matches[2] . '/u/' . $matches[1];
if($r && $r[0]['hubloc_network'] === 'zot')
return '@[zrl=' . $link . ']' . trim($name) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/zrl]' ;
else
return '@[url=' . $link . ']' . trim($name) . ((substr($matches[0],-1,1) === '+') ? '+' : '') . '[/url]' ;
}
/**
* @brief
*
@ -90,28 +25,29 @@ function diaspora_mention_callback2($matches) {
* @param boolean $use_zrl default false
* @return string
*/
function markdown_to_bb($s, $use_zrl = false) {
$s = str_replace("&#xD;","\r",$s);
$s = str_replace("&#xD;\n&gt;","",$s);
function markdown_to_bb($s, $use_zrl = false, $options = []) {
if(is_array($s)) {
btlogger('markdown_to_bb called with array. ' . print_r($s,true), LOGGER_NORMAL, LOG_WARNING);
return '';
}
$s = str_replace("&#xD;","\r",$s);
$s = str_replace("&#xD;\n&gt;","",$s);
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
// if empty link text replace with the url
$s = preg_replace("/\[\]\((.*?)\)/ism",'[$1]($1)',$s);
// first try plustags
$x = [ 'text' => $s , 'zrl' => $use_zrl, 'options' => $options ];
$s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s);
$s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}/','diaspora_mention_callback',$s);
call_hooks('markdown_to_bb_init',$x);
$s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}\+/','diaspora_mention_callback2',$s);
$s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}/','diaspora_mention_callback2',$s);
$s = $x['text'];
// Escaping the hash tags - doesn't always seem to work
// $s = preg_replace('/\#([^\s\#])/','\\#$1',$s);
@ -126,9 +62,6 @@ function markdown_to_bb($s, $use_zrl = false) {
$s = html2bbcode($s);
// protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands
$s = str_replace('&#x2672;',html_entity_decode('&#x2672;',ENT_QUOTES,'UTF-8'),$s);
// Convert everything that looks like a link to a link
if($use_zrl) {
$s = str_replace(array('[img','/img]'),array('[zmg','/zmg]'),$s);
@ -150,283 +83,25 @@ function markdown_to_bb($s, $use_zrl = false) {
}
function stripdcode_br_cb($s) {
return '[code]' . str_replace('<br />', "\n\t", $s[1]) . '[/code]';
}
//////////////////////
// The following "diaspora_ul" and "diaspora_ol" are only appropriate for the
// pre-Markdownify conversion. If Markdownify isn't used, use the non-Markdownify
// versions below
//////////////////////
/*
function diaspora_ul($s) {
// Replace "[*]" followed by any number (including zero) of
// spaces by "* " to match Diaspora's list format
if( strpos($s[0], "[list]") === 0 )
return '<ul class="listbullet" style="list-style-type: circle;">' . preg_replace("/\[\*\]( *)/", "* ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[ul]") === 0 )
return '<ul class="listbullet" style="list-style-type: circle;">' . preg_replace("/\[\*\]( *)/", "* ", $s[1]) . '</ul>';
else
return $s[0];
}
function bb_to_markdown($Text) {
/*
* Transform #tags, strip off the [url] and replace spaces with underscore
*/
function diaspora_ol($s) {
// A hack: Diaspora will create a properly-numbered ordered list even
// if you use '1.' for each element of the list, like:
// 1. First element
// 1. Second element
// 1. Third element
if( strpos($s[0], "[list=1]") === 0 )
return '<ul class="listdecimal" style="list-style-type: decimal;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[list=i]") === 0 )
return '<ul class="listlowerroman" style="list-style-type: lower-roman;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[list=I]") === 0 )
return '<ul class="listupperroman" style="list-style-type: upper-roman;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[list=a]") === 0 )
return '<ul class="listloweralpha" style="list-style-type: lower-alpha;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[list=A]") === 0 )
return '<ul class="listupperalpha" style="list-style-type: upper-alpha;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
elseif( strpos($s[0], "[ol]") === 0 )
return '<ul class="listdecimal" style="list-style-type: decimal;">' . preg_replace("/\[\*\]( *)/", "1. ", $s[1]) . '</ul>';
else
return $s[0];
}
*/
$Text = preg_replace_callback('/#\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/[(zu)]rl\]/i',
create_function('$match', 'return \'#\'. str_replace(\' \', \'_\', $match[3]);'), $Text);
//////////////////////
// Non-Markdownify versions of "diaspora_ol" and "diaspora_ul"
//////////////////////
/**
* @brief
*
* Replace "[\\*]" followed by any number (including zero) of
* spaces by "* " to match Diaspora's list format.
*
* @param string $s
* @return string
*/
function diaspora_ul($s) {
return preg_replace("/\[\\\\\*\]( *)/", "* ", $s[1]);
}
/**
* @brief
*
* A hack: Diaspora will create a properly-numbered ordered list even
* if you use '1.' for each element of the list, like:
* \code
* 1. First element
* 1. Second element
* 1. Third element
* \endcode
* @param string $s
* @return string
*/
function diaspora_ol($s) {
return preg_replace("/\[\\\\\*\]( *)/", "1. ", $s[1]);
}
function bb2dmention_callback($match) {
$r = q("select xchan_addr from xchan where xchan_url = '%s'",
dbesc($match[2])
);
if($r)
return '@{' . $match[3] . ' ; ' . $r[0]['xchan_addr'] . '}';
return '@' . $match[3];
}
function bb2diaspora_itemwallwall(&$item,$uplink = false) {
// We will provide wallwall (embedded author on the Diaspora side) if
// 1. It is a wall-to-wall post
// 2. A comment arrived which has no Diaspora signature info
$wallwall = false;
$author_exists = true;
if(! array_key_exists('author',$item)) {
$author_exists = false;
logger('bb2diaspora_itemwallwall: no author');
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($item['author_xchan'])
);
if($r)
$item['author'] = $r[0];
}
$has_meta = false;
if($item['diaspora_meta'] || get_iconfig($item,'diaspora','fields'))
$has_meta = true;
if($item['author_xchan'] != $item['owner_xchan']) {
if($item['mid'] == $item['parent_mid'])
$wallwall = true;
else {
if(! $has_meta) {
$wallwall = true;
}
}
}
if($uplink)
$wallwall = true;
if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_s']) {
logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG);
// post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author.
$item['body'] = "\n\n"
. '[quote]'
. '[img]' . $item['author']['xchan_photo_s'] . '[/img]'
. ' '
. '[url=' . $item['author']['xchan_url'] . '][b]' . $item['author']['xchan_name'] . '[/b][/url]' . "\n\n"
. $item['body']
. '[/quote]';
}
// $item['author'] might cause a surprise further down the line if it wasn't expected to be here.
if(! $author_exists)
unset($item['author']);
}
function bb2diaspora_itembody($item, $force_update = false, $have_channel = false, $uplink = false) {
if(! get_iconfig($item,'diaspora','fields')) {
$force_update = true;
}
$matches = array();
if(($item['diaspora_meta']) && (! $force_update)) {
$diaspora_meta = json_decode($item['diaspora_meta'],true);
if($diaspora_meta) {
if(array_key_exists('iv',$diaspora_meta)) {
$key = get_config('system','prvkey');
$meta = json_decode(crypto_unencapsulate($diaspora_meta,$key),true);
}
else {
$meta = $diaspora_meta;
}
if($meta) {
logger('bb2diaspora_itembody: cached ');
$newitem = $item;
$newitem['body'] = $meta['body'];
return $newitem['body'];
}
}
}
create_export_photo_body($item);
$newitem = $item;
if(array_key_exists('item_obscured',$item) && intval($item['item_obscured'])) {
$key = get_config('system','prvkey');
$b = json_decode($item['body'],true);
// if called from diaspora_process_outbound, this decoding has already been done.
// Everything else that calls us will not yet be decoded.
if($b && is_array($b) && array_key_exists('iv',$b)) {
$newitem['title'] = (($item['title']) ? crypto_unencapsulate(json_decode($item['title'],true),$key) : '');
$newitem['body'] = (($item['body']) ? crypto_unencapsulate(json_decode($item['body'],true),$key) : '');
}
}
if(! $have_channel)
bb2diaspora_itemwallwall($newitem,$uplink);
$title = $newitem['title'];
$body = preg_replace('/\#\^http/i', 'http', $newitem['body']);
// protect tags and mentions from hijacking
if(intval(get_pconfig($item['uid'],'system','prevent_tag_hijacking'))) {
$new_tag = html_entity_decode('&#x22d5;',ENT_COMPAT,'UTF-8');
$new_mention = html_entity_decode('&#xff20;',ENT_COMPAT,'UTF-8');
// #-tags
$body = preg_replace('/\#\[url/i', $new_tag . '[url', $body);
$body = preg_replace('/\#\[zrl/i', $new_tag . '[zrl', $body);
// @-mentions
$body = preg_replace('/\@\!?\[url/i', $new_mention . '[url', $body);
$body = preg_replace('/\@\!?\[zrl/i', $new_mention . '[zrl', $body);
}
// remove multiple newlines
do {
$oldbody = $body;
$body = str_replace("\n\n\n", "\n\n", $body);
} while ($oldbody != $body);
$body = bb2diaspora($body);
if(strlen($title))
$body = "## " . $title . "\n\n" . $body;
if($item['attach']) {
$cnt = preg_match_all('/href=\"(.*?)\"(.*?)title=\"(.*?)\"/ism', $item['attach'], $matches, PREG_SET_ORDER);
if($cnt) {
$body .= "\n" . t('Attachments:') . "\n";
foreach($matches as $mtch) {
$body .= '[' . $mtch[3] . '](' . $mtch[1] . ')' . "\n";
}
}
}
// logger('bb2diaspora_itembody : ' . $body, LOGGER_DATA);
return html_entity_decode($body);
}
/**
* @brief Prepare bbcode for Diaspora.
*
* @hooks bb2diaspora
* * \e string The prepared text for diaspora.
*
* @param string $Text bbcode
* @param boolean $preserve_nl (default false) preserve new lines
* @param boolean $fordiaspora (default true, but unused)
* @return string
*/
function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
// Re-enabling the converter again.
// The bbcode parser now handles youtube-links (and the other stuff) correctly.
// Additionally the html code is now fixed so that lists are now working.
// Transform #tags, strip off the [url] and replace spaces with underscore
$Text = preg_replace_callback('/#\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/[(zu)]rl\]/i', create_function('$match',
'return \'#\'. str_replace(\' \', \'_\', $match[3]);'
), $Text);
$Text = preg_replace('/#\^\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', '[$1rl=$2]$3[/$4rl]', $Text);
$Text = preg_replace_callback('/\@\!?\[([zu])rl\=(\w+.*?)\](\w+.*?)\[\/([zu])rl\]/i', 'bb2dmention_callback', $Text);
// strip map tags, as the rendering is performed in bbcode() and the resulting output
// is not compatible with Diaspora (at least in the case of openstreetmap and probably
// due to the inclusion of an html iframe)
$Text = preg_replace("/\[map\=(.*?)\]/ism", '$1', $Text);
$Text = preg_replace("/\[map\](.*?)\[\/map\]/ism", '$1', $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
// the following was added on 10-January-2012 due to an inability of Diaspora's
// new javascript markdown processor to handle links with images as the link "text"
// It is not optimal and may be removed if this ability is restored in the future
//if ($fordiaspora)
// $Text = preg_replace("/\[url\=([^\[\]]*)\]\s*\[img\](.*?)\[\/img\]\s*\[\/url\]/ism",
// "[url]$1[/url]\n[img]$2[/img]", $Text);
call_hooks('bb_to_markdown_bb',$Text);
// Convert it to HTML - don't try oembed
$Text = bbcode($Text, $preserve_nl, false);
@ -435,9 +110,11 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$Text = str_replace(array('&lt;','&gt;','&amp;'),array('&_lt_;','&_gt_;','&_amp_;'),$Text);
// Now convert HTML to Markdown
$Text = html2markdown($Text);
// It also adds backslashes to our attempt at getting around the html entity preservation for some weird reason.
$Text = str_replace(array('&\\_lt\\_;','&\\_gt\\_;','&\\_amp\\_;'),array('&lt;','&gt;','&amp;'),$Text);
// If the text going into bbcode() has a plain URL in it, i.e.
@ -449,57 +126,18 @@ function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
// Remove empty zrl links
$Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
// Remove all unconverted tags
$Text = strip_tags($Text);
// escape all unconverted tags
$Text = escape_tags($Text);
// Remove any leading or trailing whitespace, as this will mess up
// the Diaspora signature verification and cause the item to disappear
$Text = trim($Text);
call_hooks('bb2diaspora', $Text);
call_hooks('bb_to_markdown', $Text);
return $Text;
}
function unescape_underscores_in_links($m) {
$y = str_replace('\\_','_', $m[2]);
return('[' . $m[1] . '](' . $y . ')');
}
function format_event_diaspora($ev) {
if(! ((is_array($ev)) && count($ev)))
return '';
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
$o = t('$Projectname event notification:') . "\n";
$o .= '**' . (($ev['summary']) ? bb2diaspora($ev['summary']) : bb2diaspora($ev['desc'])) . '**' . "\n";
$o .= t('Starts:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
if(! $ev['nofinish'])
$o .= t('Finishes:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
if(strlen($ev['location']))
$o .= t('Location:') . bb2diaspora($ev['location'])
. "\n";
$o .= "\n";
return $o;
}
/**
* @brief Convert a HTML text into Markdown.

View File

@ -104,38 +104,9 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
// create a new conversation
$conv_guid = random_string();
$recip = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($recipient)
);
if($recip)
$recip_handle = $recip[0]['xchan_addr'];
$sender_handle = channel_reddress($channel);
$handles = $recip_handle . ';' . $sender_handle;
if($subject)
$nsubject = str_rot47(base64url_encode($subject));
$r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ",
intval(local_channel()),
dbesc($conv_guid),
dbesc($sender_handle),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($nsubject),
dbesc($handles)
);
$r = q("select * from conv where guid = '%s' and uid = %d limit 1",
dbesc($conv_guid),
intval(local_channel())
);
if($r) {
$retconv = $r[0];
$retconv['subject'] = base64url_decode(str_rot47($retconv['subject']));
$retconv = create_conversation($channel,$recipient,$subject);
if($retconv) {
$conv_guid = $retconv['guid'];
}
}
@ -146,7 +117,6 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
);
if($r) {
$retconv = $r[0];
$retconv['subject'] = base64url_decode(str_rot47($retconv['subject']));
}
}
@ -155,6 +125,12 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
return $ret;
}
$c = q("update conv set updated = '%s' where guid = '%s' and uid = %d",
dbesc(datetime_convert()),
dbesc($conv_guid),
intval(local_channel())
);
// generate a unique message_id
do {
@ -284,6 +260,49 @@ function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $rep
}
function create_conversation($channel,$recipient,$subject) {
// create a new conversation
$conv_guid = random_string();
$recip = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($recipient)
);
if($recip)
$recip_handle = $recip[0]['xchan_addr'];
$sender_handle = channel_reddress($channel);
$handles = $recip_handle . ';' . $sender_handle;
if($subject)
$nsubject = str_rot47(base64url_encode($subject));
$r = q("insert into conv (uid,guid,creator,created,updated,subject,recips) values(%d, '%s', '%s', '%s', '%s', '%s', '%s') ",
intval($channel['channel_id']),
dbesc($conv_guid),
dbesc($sender_handle),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($nsubject),
dbesc($handles)
);
$r = q("select * from conv where guid = '%s' and uid = %d limit 1",
dbesc($conv_guid),
intval($channel['channel_id'])
);
return $r[0];
}
function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
$where = '';
@ -315,6 +334,8 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
break;
case 'combined':
default:
$parents = q("SELECT parent_mid FROM mail WHERE mid = parent_mid AND channel_id = %d ORDER BY created DESC",
dbesc($local_channel)
);
@ -326,15 +347,21 @@ function private_messages_list($uid, $mailbox = '', $start = 0, $numitems = 0) {
}
$r = null;
if($parents) {
foreach($parents as $parent) {
$all[] = q("SELECT * FROM mail WHERE parent_mid = '%s' AND channel_id = %d ORDER BY created DESC",
$all = q("SELECT * FROM mail WHERE parent_mid = '%s' AND channel_id = %d ORDER BY created DESC limit 1",
dbesc($parent['parent_mid']),
dbesc($local_channel)
);
if($all) {
foreach($all as $single) {
$r[] = $single;
}
}
}
foreach($all as $single)
$r[] = $single[0];
}
else {
$r = q($sql);

View File

@ -65,8 +65,6 @@ EOT;
//we could additionally use this to display important system notifications e.g. for updates
));
$server_role = get_config('system','server_role');
$basic = (($server_role === 'basic') ? true : false);
$techlevel = get_account_techlevel();
// nav links: array of array('href', 'text', 'extra css classes', 'title')
@ -97,7 +95,7 @@ EOT;
if(local_channel()) {
if($chans && count($chans) > 1 && feature_enabled(local_channel(),'nav_channel_select') && (! $basic))
if($chans && count($chans) > 1 && feature_enabled(local_channel(),'nav_channel_select'))
$nav['channels'] = $chans;
$nav['logout'] = ['logout',t('Logout'), "", t('End this session'),'logout_nav_btn'];
@ -105,7 +103,7 @@ EOT;
// user menu
$nav['usermenu'][] = ['profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'),'profile_nav_btn'];
if(feature_enabled(local_channel(),'multi_profiles') && (! $basic))
if(feature_enabled(local_channel(),'multi_profiles'))
$nav['usermenu'][] = ['profiles', t('Edit Profiles'),"", t('Manage/Edit profiles'),'profiles_nav_btn'];
else
$nav['usermenu'][] = ['profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile'),'profiles_nav_btn'];
@ -201,8 +199,7 @@ EOT;
$nav['all_events']['all']=array('events', t('View events'), "", "");
$nav['all_events']['mark'] = array('', t('Mark all events seen'), '','');
if(! $basic)
$nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels'),'manage_nav_btn');
$nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels'),'manage_nav_btn');
$nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn');

View File

@ -343,7 +343,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
if (isset($url_parsed)) {
curl_close($ch);
if($http_code == 303) {
return z_fetch_url($newurl,false,$redirects++,$opts);
return z_fetch_url($newurl,false,++$redirects,$opts);
} else {
return z_post_url($newurl,$params,++$redirects,$opts);
}
@ -397,31 +397,6 @@ function json_return_and_die($x, $content_type = 'application/json') {
killme();
}
/**
* @brief Generic XML return.
*
* Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable
* of $st and an optional text <message> of $message and terminates the current
* process.
*
* @param string $st
* @param string $message
*/
function xml_status($st, $message = '') {
$xml_message = ((strlen($message)) ? "\t<message>" . xmlify($message) . "</message>\r\n" : '');
if($st)
logger('Returning non_zero: ' . $st . " message=" . $message);
header( "Content-type: text/xml" );
echo '<?xml version="1.0" encoding="UTF-8"?>'."\r\n";
echo "<result>\r\n\t<status>$st</status>\r\n$xml_message</result>\r\n";
killme();
}
/**
* @brief Send HTTP status header.
*
@ -1007,39 +982,6 @@ function email_header_encode($in_str, $charset = 'UTF-8') {
return $out_str;
}
function email_send($addr, $subject, $headers, $item) {
//$headers .= 'MIME-Version: 1.0' . "\n";
//$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
//$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
//$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
$part = uniqid("", true);
$html = prepare_body($item);
$headers .= "Mime-Version: 1.0\n";
$headers .= 'Content-Type: multipart/alternative; boundary="=_'.$part.'"'."\n\n";
$body = "\n--=_".$part."\n";
$body .= "Content-Transfer-Encoding: 8bit\n";
$body .= "Content-Type: text/plain; charset=utf-8; format=flowed\n\n";
$body .= html2plain($html)."\n";
$body .= "--=_".$part."\n";
$body .= "Content-Transfer-Encoding: 8bit\n";
$body .= "Content-Type: text/html; charset=utf-8\n\n";
$body .= '<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">'.$html."</body></html>\n";
$body .= "--=_".$part."--";
//$message = '<html><body>' . $html . '</body></html>';
//$message = html2plain($html);
logger('notifier: email delivery to ' . $addr);
mail($addr, $subject, $body, $headers);
}
/**
* @brief Creates an xchan entry for URL.
*
@ -1056,10 +998,10 @@ function discover_by_url($url, $arr = null) {
return false;
$network = (($arr['network']) ? $arr['network'] : 'unknown');
$name = (($arr['name']) ? $arr['name'] : 'unknown');
$photo = (($arr['photo']) ? $arr['photo'] : '');
$addr = (($arr['addr']) ? $arr['addr'] : '');
$guid = $url;
$name = (($arr['name']) ? $arr['name'] : 'unknown');
$photo = (($arr['photo']) ? $arr['photo'] : '');
$addr = (($arr['addr']) ? $arr['addr'] : '');
$guid = $url;
}
$profile = $url;
@ -1095,8 +1037,8 @@ function discover_by_url($url, $arr = null) {
if($feed->error())
logger('scrape_feed: Error parsing XML: ' . $feed->error());
$name = unxmlify(trim($feed->get_title()));
$photo = $feed->get_image_url();
$name = unxmlify(trim($feed->get_title()));
$photo = $feed->get_image_url();
$author = $feed->get_author();
if($author) {
@ -1195,23 +1137,11 @@ function discover_by_url($url, $arr = null) {
}
function discover_by_webbie($webbie) {
require_once('library/HTML5/Parser.php');
$result = array();
$result = [];
$network = null;
$diaspora = false;
$gnusoc = false;
$dfrn = false;
$has_salmon = false;
$salmon_key = false;
$atom_feed = false;
$diaspora_base = '';
$diaspora_guid = '';
$diaspora_key = '';
$webbie = strtolower($webbie);
$x = webfinger_rfc7033($webbie,true);
@ -1237,21 +1167,6 @@ function discover_by_webbie($webbie) {
}
}
}
if($link['rel'] == NAMESPACE_DFRN) {
$dfrn = $link['href'];
}
if($link['rel'] == 'magic-public-key') {
if(substr($link['href'],0,5) === 'data:') {
$salmon_key = convert_salmon_key($link['href']);
}
}
if($link['rel'] == 'salmon') {
$has_salmon = true;
$salmon = $link['href'];
}
if($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
$atom_feed = $link['href'];
}
}
}
}
@ -1263,276 +1178,10 @@ function discover_by_webbie($webbie) {
if($arr['success'])
return true;
$aliases = array();
// Now let's make some decisions on what we may need
// to obtain further info
$probe_atom = false;
$probe_old = false;
$probe_hcard = false;
$address = '';
$location = '';
$nickname = '';
$fullname = '';
$avatar = '';
$pubkey = '';
if(is_array($x)) {
if(array_key_exists('address',$x))
$address = $x['address'];
if(array_key_exists('location',$x))
$location = $x['location'];
if(array_key_exists('nickname',$x))
$nickname = $x['nickname'];
}
if(! $x)
$probe_old = true;
if((! $dfrn) && (! $has_salmon))
$probe_old = true;
if($probe_old) {
$y = old_webfinger($webbie);
if($y) {
logger('old_webfinger: ' . print_r($x,true));
foreach($y as $link) {
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
$dfrn = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'salmon')
$notify = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === NAMESPACE_FEED)
$poll = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
$hcard = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
$profile = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0')
$poco = unamp($link['@attributes']['href']);
if($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
$diaspora_base = unamp($link['@attributes']['href']);
$diaspora = true;
}
if($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
$diaspora_guid = unamp($link['@attributes']['href']);
$diaspora = true;
}
if($link['@attributes']['rel'] === 'diaspora-public-key') {
$diaspora_key = base64_decode(unamp($link['@attributes']['href']));
if(strstr($diaspora_key,'RSA '))
$pubkey = rsatopem($diaspora_key);
else
$pubkey = $diaspora_key;
$diaspora = true;
}
if($link['@attributes']['rel'] == 'magic-public-key') {
if(substr($link['@attributes']['href'],0,5) === 'data:') {
$salmon_key = convert_salmon_key($link['@attributes']['href']);
}
}
if($link['@attributes']['rel'] == 'salmon') {
$has_salmon = true;
$salmon = $link['@attributes']['href'];
}
if($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
$atom_feed = $link['@attributes']['href'];
}
if($link['@attributes']['rel'] === 'alias') {
$aliases[] = $link['@attributes']['href'];
}
if($link['@attributes']['rel'] === 'subject') {
$subject = $link['@attributes']['href'];
}
}
}
}
if($subject || $aliases) {
if(strpos($webbie,'@')) {
$rhs = substr($webbie,strpos($webbie,'@')+1);
}
else {
$m = parse_url($webbie);
if($m) {
$rhs = $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
}
}
$v = array('subject' => $subject,'aliases' => $aliases);
$address = find_webfinger_address($v,$rhs);
$location = find_webfinger_location($v,$rhs);
if($address)
$nickname = substr($address,0,strpos($address,'@'));
}
if($salmon_key && $has_salmon && $atom_feed && (! $dfrn) && (! $diaspora)) {
$gnusoc = true;
$probe_atom = true;
}
if(! $pubkey)
$pubkey = $salmon_key;
if(($dfrn || $diaspora) && $hcard)
$probe_hcard = true;
if(! $fullname)
$fullname = $nickname;
if($probe_atom) {
$k = z_fetch_url($atom_feed);
if($k['success'])
$feed_meta = feed_meta($k['body']);
if($feed_meta) {
// stash any discovered pubsubhubbub hubs in case we need to follow them
// this will save an expensive lookup later
if($feed_meta['hubs'] && $address) {
set_xconfig($address,'system','push_hubs',$feed_meta['hubs']);
set_xconfig($address,'system','feed_url',$atom_feed);
}
if($feed_meta['author']['author_name']) {
$fullname = $feed_meta['author']['author_name'];
}
if(! $avatar) {
if($feed_meta['author']['author_photo'])
$avatar = $feed_meta['author']['author_photo'];
}
// for GNU-social over-ride any url aliases we may have picked up in webfinger
// The author.uri element in the feed is likely to be more accurate
if($gnusoc && $feed_meta['author']['author_uri'])
$location = $feed_meta['author']['author_uri'];
}
}
else {
if($probe_hcard) {
$vcard = scrape_vcard($hcard);
if($vcard) {
logger('vcard: ' . print_r($vcard,true), LOGGER_DATA);
if($vcard['fn'])
$fullname = $vcard['fn'];
if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0))
$vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
if(($vcard['public_key']) && (! $pubkey)) {
$diaspora_key = $vcard['public_key'];
if(strstr($diaspora_key,'RSA '))
$pubkey = rsatopem($diaspora_key);
else
$pubkey = $diaspora_key;
}
if(! $avatar)
$avatar = $vcard['photo'];
if($diaspora) {
if(($vcard['uid']) && (! $diaspora_guid))
$diaspora_guid = $vcard['uid'];
if(($vcard['url']) && (! $diaspora_base))
$diaspora_base = $vcard['url'];
}
}
}
}
if(($profile) && (! $location))
$location = $profile;
if($location) {
$m = parse_url($location);
$base = $m['scheme'] . '://' . $m['host'];
$host = $m['host'];
}
if($diaspora && $diaspora_base && $diaspora_guid) {
if($dfrn)
$network = 'friendica-over-diaspora';
else
$network = 'diaspora';
$base = trim($diaspora_base, '/');
$notify = $base . '/receive';
}
else {
if($gnusoc) {
$network = 'gnusoc';
$notify = $salmon;
}
}
logger('network: ' . $network);
logger('address: ' . $address);
logger('fullname: ' . $fullname);
logger('pubkey: ' . $pubkey);
logger('location: ' . $location);
// if we have everything we need, let's create the records
if($network && $address && $fullname && $pubkey && $location) {
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($address)
);
if($r) {
$r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
dbesc($fullname),
dbesc($network),
dbesc(datetime_convert()),
dbesc($address)
);
}
else {
$r = xchan_store_lowlevel(
[
'xchan_hash' => $address,
'xchan_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
'xchan_pubkey' => $pubkey,
'xchan_addr' => $address,
'xchan_url' => $location,
'xchan_name' => $fullname,
'xchan_name_date' => datetime_convert(),
'xchan_network' => $network
]
);
}
$r = q("select * from hubloc where hubloc_hash = '%s' limit 1",
dbesc($address)
);
if(! $r) {
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => (($diaspora_guid) ? $diaspora_guid : $location),
'hubloc_hash' => $address,
'hubloc_addr' => $address,
'hubloc_network' => $network,
'hubloc_url' => $base,
'hubloc_host' => $host,
'hubloc_callback' => $notify,
'hubloc_updated' => datetime_convert(),
'hubloc_primary' => 1
]
);
}
$photos = import_xchan_photo($avatar,$address);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbescdate(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($address)
);
return true;
}
return false;
}
function webfinger_rfc7033($webbie,$zot = false) {
if(strpos($webbie,'@')) {
@ -1557,105 +1206,22 @@ function webfinger_rfc7033($webbie,$zot = false) {
// and results in a 406 (Not Acceptable) response, and will also incorrectly produce an XML
// document if you use 'application/jrd+json, */*'. We could set this to application/jrd+json,
// but some test webfinger servers may not explicitly set the content type and they would be
// blocked. The best compromise until Mastodon is fixed is to remove the Accept header which is
// accomplished by setting it to nothing.
// blocked. The best compromise until Mastodon is fixed is to remove the Accept header which is
// accomplished by setting it to nothing.
$counter = 0;
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''),
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''),
false, $counter, [ 'headers' => [ 'Accept:' ] ]);
if($s['success']) {
$j = json_decode($s['body'],true);
// We could have a number of URL aliases and webbies
// make an executive decision about the most likely "best" of each
// by comparing against some examples from known networks we're likely to encounter.
// Otherwise we have to store every alias that we may ever encounter and
// validate every URL we ever find against every possible alias
/**
* @FIXME pump.io is going to be a real bugger since it doesn't return
* subject or aliases or provide lookup by url
*/
$j['address'] = find_webfinger_address($j,$rhs);
$j['location'] = find_webfinger_location($j,$rhs);
if($j['address'])
$j['nickname'] = substr($j['address'],0,strpos($j['address'],'@'));
return($j);
}
else
return false;
return($j);
return false;
}
function find_webfinger_address($j,$rhs) {
if(is_array($j) && ($j)) {
if(strpos($j['subject'],'acct:') !== false && strpos($j['subject'],'@' . $rhs))
return str_replace('acct:','',$j['subject']);
if($j['aliases']) {
foreach($j['aliases'] as $alias) {
if(strpos($alias,'acct:') !== false && strpos($alias,'@' . $rhs)) {
return str_replace('acct:','',$alias);
}
}
}
}
return '';
}
function find_webfinger_location($j,$rhs) {
if(is_array($j) && ($j)) {
if(strpos($j['subject'],'http') === 0) {
$x = match_webfinger_location($j['subject'],$rhs);
if($x)
return $x;
}
if($j['aliases']) {
foreach($j['aliases'] as $alias) {
if(strpos($alias,'http') === 0) {
$x = match_webfinger_location($alias,$rhs);
if($x)
return($x);
}
}
}
}
return '';
}
/**
* @brief Match the webfinger location for the different networks.
*
* @param string $s The string to search in
* @param string $h The host
* @return string
*/
function match_webfinger_location($s, $h) {
// GNU-social and the older StatusNet - the $host/user/123 form doesn't work
if(preg_match('|' . $h . '/index.php/user/([0-9]*?)$|', $s))
return $s;
// Redmatrix / hubzilla
if(preg_match('|' . $h . '/channel/|', $s))
return $s;
// Friendica
if(preg_match('|' . $h . '/profile/|', $s))
return $s;
$arr = array('test' => $s, 'host' => $h, 'success' => false);
call_hooks('match_webfinger_location', $arr);
if($arr['success'])
return $s;
return '';
}
function old_webfinger($webbie) {
$host = '';
@ -1723,9 +1289,6 @@ function fetch_xrd_links($url) {
if ((! $xml) || (! stristr($xml,'<xrd')))
return array();
// fix diaspora's bad xml
$xml = str_replace(array('href=&quot;','&quot;/>'),array('href="','"/>'),$xml);
$h = parse_xml_string($xml);
if(! $h)
return array();
@ -1765,89 +1328,13 @@ function fetch_xrd_links($url) {
}
function scrape_vcard($url) {
$ret = array();
logger('url=' . $url);
$x = z_fetch_url($url);
if(! $x['success'])
return $ret;
$s = $x['body'];
if(! $s)
return $ret;
$headers = $x['header'];
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('Parse error: ' . $e);
}
if(! $dom)
return $ret;
// Pull out hCard profile elements
$largest_photo = 0;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('id'),'pod_location'))
$ret['pod_location'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'fn'))
$ret['fn'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'uid'))
$ret['uid'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'nickname'))
$ret['nick'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'searchable'))
$ret['searchable'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'key'))
$ret['public_key'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'given_name'))
$ret['given_name'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'family_name'))
$ret['family_name'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'url'))
$ret['url'] = $x->textContent;
if((attribute_contains($x->getAttribute('class'),'photo'))
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
$size = intval($x->getAttribute('width'));
if(($size > $largest_photo) || (! $largest_photo)) {
$ret['photo'] = $x->getAttribute('src');
$largest_photo = $size;
}
}
}
}
}
return $ret;
}
/**
* @brief
*
* @param string $url The URL to scrape
* @return array
*/
function scrape_feed($url) {
require_once('library/HTML5/Parser.php');
@ -1941,112 +1428,6 @@ function scrape_feed($url) {
function service_plink($contact, $guid) {
$plink = '';
$m = parse_url($contact['xchan_url']);
if($m) {
$url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
}
else
$url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1);
$handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@'));
if($contact['xchan_network'] === 'diaspora')
$plink = $url . '/posts/' . $guid;
if($contact['xchan_network'] === 'friendica-over-diaspora')
$plink = $url . '/display/' . $handle . '/' . $guid;
if($contact['xchan_network'] === 'zot')
$plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid;
return $plink;
}
function format_and_send_email($sender,$xchan,$item) {
$title = $item['title'];
$body = $item['body'];
$textversion = strip_tags(html_entity_decode(bbcode(str_replace(array("\\r", "\\n"), array( "", "\n"), $body)),ENT_QUOTES,'UTF-8'));
$htmlversion = bbcode(str_replace(array("\\r","\\n"), array("","<br />\n"),$body));
$banner = t('$Projectname Notification');
$product = t('$projectname'); // PLATFORM_NAME;
$siteurl = z_root();
$thanks = t('Thank You,');
$sitename = get_config('system', 'sitename');
$site_admin = sprintf( t('%s Administrator'), $sitename);
// load the template for private message notifications
$tpl = get_markup_template('email_notify_html.tpl');
$email_html_body = replace_macros($tpl, array(
'$banner' => $banner,
'$notify_icon' => Zotlabs\Lib\System::get_notify_icon(),
'$product' => $product,
'$preamble' => '',
'$sitename' => $sitename,
'$siteurl' => $siteurl,
'$source_name' => $sender['xchan_name'],
'$source_link' => $sender['xchan_url'],
'$source_photo' => $sender['xchan_photo_m'],
'$username' => $xchan['xchan_name'],
'$hsitelink' => $datarray['hsitelink'], /// @FIXME $datarray is undefined
'$hitemlink' => $datarray['hitemlink'], /// @FIXME $datarray is undefined
'$thanks' => $thanks,
'$site_admin' => $site_admin,
'$title' => $title,
'$htmlversion' => $htmlversion,
));
// load the template for private message notifications
$tpl = get_markup_template('email_notify_text.tpl');
$email_text_body = replace_macros($tpl, array(
'$banner' => $banner,
'$product' => $product,
'$preamble' => '',
'$sitename' => $sitename,
'$siteurl' => $siteurl,
'$source_name' => $sender['xchan_name'],
'$source_link' => $sender['xchan_url'],
'$source_photo' => $sender['xchan_photo_m'],
'$username' => $xchan['xchan_name'],
'$hsitelink' => $datarray['hsitelink'],
'$hitemlink' => $datarray['hitemlink'],
'$thanks' => $thanks,
'$site_admin' => $site_admin,
'$title' => $title,
'$textversion' => $textversion
));
$sender_name = t('Administrator');
$hostname = App::get_hostname();
if(strpos($hostname, ':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
$sender_email = get_config('system', 'reply_address');
if(! $sender_email)
$sender_email = 'noreply' . '@' . $hostname;
// use the EmailNotification library to send the message
Zotlabs\Lib\Enotify::send(array(
'fromName' => $product,
'fromEmail' => $sender_email,
'replyTo' => $sender_email,
'toEmail' => str_replace('mailto:','',$xchan['xchan_addr']),
'messageSubject' => (($title) ? $title : t('No Subject')),
'htmlVersion' => $email_html_body,
'textVersion' => $email_text_body,
'additionalMailHeader' => '',
));
}
function do_delivery($deliveries) {
if(! (is_array($deliveries) && count($deliveries)))
@ -2160,33 +1541,33 @@ function get_site_info() {
}
$data = Array(
'version' => $version,
'version_tag' => $tag,
'server_role' => Zotlabs\Lib\System::get_server_role(),
'commit' => $commit,
'url' => z_root(),
'plugins' => $visible_plugins,
'register_policy' => $register_policy[get_config('system','register_policy')],
'invitation_only' => intval(get_config('system','invitation_only')),
'directory_mode' => $directory_mode[get_config('system','directory_mode')],
'language' => get_config('system','language'),
'rss_connections' => intval(get_config('system','feed_contacts')),
'expiration' => $site_expire,
$data = [
'url' => z_root(),
'platform' => Zotlabs\Lib\System::get_platform_name(),
'site_name' => (($site_name) ? $site_name : ''),
'version' => $version,
'version_tag' => $tag,
'server_role' => Zotlabs\Lib\System::get_server_role(),
'commit' => $commit,
'plugins' => $visible_plugins,
'register_policy' => $register_policy[get_config('system','register_policy')],
'invitation_only' => intval(get_config('system','invitation_only')),
'directory_mode' => $directory_mode[get_config('system','directory_mode')],
'language' => get_config('system','language'),
'rss_connections' => intval(get_config('system','feed_contacts')),
'expiration' => $site_expire,
'default_service_restrictions' => $service_class,
'locked_features' => $locked_features,
'admin' => $admin,
'site_name' => (($site_name) ? $site_name : ''),
'platform' => Zotlabs\Lib\System::get_platform_name(),
'dbdriver' => DBA::$dba->getdriver(),
'lastpoll' => get_config('system','lastpoll'),
'info' => (($site_info) ? $site_info : ''),
'channels_total' => $channels_total_stat,
'channels_active_halfyear' => $channels_active_halfyear_stat,
'channels_active_monthly' => $channels_active_monthly_stat,
'local_posts' => $local_posts_stat,
'hide_in_statistics' => $hide_in_statistics
);
'locked_features' => $locked_features,
'admin' => $admin,
'dbdriver' => DBA::$dba->getdriver(),
'lastpoll' => get_config('system','lastpoll'),
'info' => (($site_info) ? $site_info : ''),
'channels_total' => $channels_total_stat,
'channels_active_halfyear' => $channels_active_halfyear_stat,
'channels_active_monthly' => $channels_active_monthly_stat,
'local_posts' => $local_posts_stat,
'hide_in_statistics' => $hide_in_statistics
];
return $data;
}
@ -2412,3 +1793,106 @@ function probe_api_path($host) {
return '';
}
function scrape_vcard($url) {
require_once('library/HTML5/Parser.php');
$ret = array();
logger('url=' . $url);
$x = z_fetch_url($url);
if(! $x['success'])
return $ret;
$s = $x['body'];
if(! $s)
return $ret;
$headers = $x['header'];
$lines = explode("\n",$headers);
if(count($lines)) {
foreach($lines as $line) {
// don't try and run feeds through the html5 parser
if(stristr($line,'content-type:') && ((stristr($line,'application/atom+xml')) || (stristr($line,'application/rss+xml'))))
return ret;
}
}
try {
$dom = HTML5_Parser::parse($s);
} catch (DOMException $e) {
logger('Parse error: ' . $e);
}
if(! $dom)
return $ret;
// Pull out hCard profile elements
$largest_photo = 0;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vcard')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('id'),'pod_location'))
$ret['pod_location'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'fn'))
$ret['fn'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'uid'))
$ret['uid'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'nickname'))
$ret['nick'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'searchable'))
$ret['searchable'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'key'))
$ret['public_key'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'given_name'))
$ret['given_name'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'family_name'))
$ret['family_name'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'url'))
$ret['url'] = $x->textContent;
if((attribute_contains($x->getAttribute('class'),'photo'))
|| (attribute_contains($x->getAttribute('class'),'avatar'))) {
$size = intval($x->getAttribute('width'));
if(($size > $largest_photo) || (! $largest_photo)) {
$ret['photo'] = $x->getAttribute('src');
$largest_photo = $size;
}
}
}
}
}
return $ret;
}
function service_plink($contact, $guid) {
$plink = '';
$m = parse_url($contact['xchan_url']);
if($m) {
$url = $m['scheme'] . '://' . $m['host'] . (($m['port']) ? ':' . $m['port'] : '');
}
else {
$url = 'https://' . substr($contact['xchan_addr'],strpos($contact['xchan_addr'],'@')+1);
}
$handle = substr($contact['xchan_addr'], 0, strpos($contact['xchan_addr'],'@'));
$plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid;
$x = [ 'xchan' => $contact, 'guid' => $guid, '$url' => $url, 'plink' => $plink ];
call_hooks('service_plink', $x);
return $x['plink'];
}

23
include/oauth2.php Normal file
View File

@ -0,0 +1,23 @@
<?php
/*
$storage = new OAuth2\Storage\Pdo(\DBA::$dba->db);
$config = [
'use_openid_connect' => true,
'issuer' => \Zotlabs\Lib\System::get_site_name()
];
$oauth2_server = new OAuth2\Server($storage,$config);
$oauth2_server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
$oauth2_server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));
$keyStorage = new OAuth2\Storage\Memory( [
'keys' => [
'public_key' => get_config('system','pubkey'),
'private_key' => get_config('system','prvkey')
]
]);
$oauth2_server->addStorage($keyStorage,'public_key');
*/

View File

@ -1,52 +0,0 @@
<?php
// A basic toolbar for observers with write_pages permissions
function writepages_widget ($who,$which) {
return replace_macros(get_markup_template('write_pages.tpl'), array(
'$new' => t('New Page'),
'$newurl' => "webpages/$who",
'$edit' => t('Edit'),
'$editurl' => "editwebpage/$who/$which"
));
}
// Chan is channel_id, $which is channel_address - we'll need to pass observer later too.
function pagelist_widget ($owner,$which) {
$r = q("select * from iconfig left join item on iconfig.iid = item.id where item_id.uid = %d
and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' order by item.created desc",
intval($owner)
);
$pages = null;
if($r) {
$pages = array();
foreach($r as $rr) {
$pages[$rr['iid']][] = array('url' => $rr['iid'],'pagetitle' => $rr['v'],'title' => $rr['title'],'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']));
}
}
//Build the base URL for edit links
$url = z_root() . "/editwebpage/" . $which;
// This isn't pretty, but it works. Until I figure out what to do with the UI, it's Good Enough(TM).
return $o . replace_macros(get_markup_template("webpagelist.tpl"), array(
'$baseurl' => $url,
'$edit' => t('Edit'),
'$pages' => $pages,
'$channel' => $which,
'$view' => t('View'),
'$preview' => t('Preview'),
'$actions_txt' => t('Actions'),
'$pagelink_txt' => t('Page Link'),
'$title_txt' => t('Title'),
'$created_txt' => t('Created'),
'$edited_txt' => t('Edited')
));
}

View File

@ -7,60 +7,10 @@ require_once('include/security.php');
*
* This file conntains functions to check and work with permissions.
*
* Most of this file is obsolete and has been superceded by extensible permissions in v1.12; it is left here
* for reference and because we haven't yet checked that all functions have been replaced and are available
* elsewhere (typically Zotlabs/Access/*).
*/
/**
* @brief Return an array with all available permissions.
*
* These are channel specific permissions.
* The list of available permissions can get manipulated by the <i>hook</i>
* <b>global_permissions</b>.
*
* @return array associative array containing all permissions
*/
function get_perms() {
// thinking about making element[2] a bitmask instead of boolean so that we can provide a list of applicable selections
// for any given permission. Currently we use the boolean to disallow write access to "everybody", but we also want to be
// able to handle troublesome settings such as allowing channel_w_stream to anybody in the network. You can allow it, but
// there's no way to implement sending it.
$global_perms = array(
// Read only permissions
'view_stream' => array('channel_r_stream', intval(PERMS_R_STREAM), true, t('Can view my normal stream and posts'), ''),
'view_profile' => array('channel_r_profile', intval(PERMS_R_PROFILE), true, t('Can view my default channel profile'), ''),
'view_contacts' => array('channel_r_abook', intval(PERMS_R_ABOOK), true, t('Can view my connections'), ''),
'view_storage' => array('channel_r_storage', intval(PERMS_R_STORAGE), true, t('Can view my file storage and photos'), ''),
'view_pages' => array('channel_r_pages', intval(PERMS_R_PAGES), true, t('Can view my webpages'), ''),
// Write permissions
'send_stream' => array('channel_w_stream', intval(PERMS_W_STREAM), false, t('Can send me their channel stream and posts'), ''),
'post_wall' => array('channel_w_wall', intval(PERMS_W_WALL), false, t('Can post on my channel page ("wall")'), ''),
'post_comments' => array('channel_w_comment', intval(PERMS_W_COMMENT), false, t('Can comment on or like my posts'), ''),
'post_mail' => array('channel_w_mail', intval(PERMS_W_MAIL), false, t('Can send me private mail messages'), ''),
'post_like' => array('channel_w_like', intval(PERMS_W_LIKE), false, t('Can like/dislike stuff'), t('Profiles and things other than posts/comments')),
'tag_deliver' => array('channel_w_tagwall', intval(PERMS_W_TAGWALL), false, t('Can forward to all my channel contacts via post @mentions'), t('Advanced - useful for creating group forum channels')),
'chat' => array('channel_w_chat', intval(PERMS_W_CHAT), false, t('Can chat with me (when available)'), t('')),
'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my file storage and photos'), ''),
'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my webpages'), ''),
'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my public posts in derived channels'), t('Somewhat advanced - very useful in open communities')),
'delegate' => array('channel_a_delegate', intval(PERMS_A_DELEGATE), false, t('Can administer my channel resources'), t('Extremely advanced. Leave this alone unless you know what you are doing')),
);
$ret = array('global_permissions' => $global_perms);
call_hooks('global_permissions', $ret);
return $ret['global_permissions'];
}
/**
* get_all_perms($uid,$observer_xchan)
*
@ -297,7 +247,6 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
*
* Checks if the given observer with the hash $observer_xchan has permission
* $permission on channel_id $uid.
* $permission is one defined in get_perms();
*
* @param int $uid The channel_id associated with the resource owner
* @param string $observer_xchan The xchan_hash representing the observer
@ -465,7 +414,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
function get_all_api_perms($uid,$api) {
$global_perms = get_perms();
$global_perms = \Zotlabs\Access\Permissions::Perms();
$ret = array();
@ -568,6 +517,7 @@ function site_default_perms() {
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'view_wiki' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
@ -576,16 +526,15 @@ function site_default_perms() {
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'write_wiki' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC,
'post_like' => PERMS_NETWORK
);
$global_perms = get_perms();
$global_perms = \Zotlabs\Access\Permissions::Perms();
foreach($global_perms as $perm => $v) {
$x = get_config('default_perms', $perm);
if($x === false)
$x = $typical[$perm];
$x = get_config('default_perms', $perm, $typical[$perm]);
$ret[$perm] = $x;
}
@ -593,362 +542,3 @@ function site_default_perms() {
}
/**
* @brief Return an array of all permissions for this role.
*
* Given a string for the channel role ('social','forum', etc)
* return an array of all permission fields pre-filled for this role.
* This includes the channel permission scope indicators (anything beginning with 'channel_') as well as
* * perms_auto: true or false to create auto-permissions for this channel
* * perms_follow: The permissions to apply when initiating a connection request to another channel
* * perms_accept: The permissions to apply when accepting a connection request from another channel (not automatic)
* * default_collection: true or false to make the default ACL include the channel's default collection
* * directory_publish: true or false to publish this channel in the directory
* Any attributes may be extended (new roles defined) and modified (specific permissions altered) by plugins
*
* @param string $role
* @return array
*/
function get_role_perms($role) {
$ret = array();
$ret['role'] = $role;
switch($role) {
case 'social':
$ret['perms_auto'] = false;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like', 'republish' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'social_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = true;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'chat', 'post_like' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'social_private':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_SPECIFIC,
'view_storage' => PERMS_SPECIFIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'forum':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'forum_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'forum_private':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'chat' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_SPECIFIC,
'view_contacts' => PERMS_SPECIFIC,
'view_storage' => PERMS_SPECIFIC,
'view_pages' => PERMS_SPECIFIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'feed':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'feed_restricted':
$ret['perms_auto'] = false;
$ret['default_collection'] = true;
$ret['directory_publish'] = false;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'send_stream', 'post_wall', 'post_comments',
'post_mail', 'post_like' , 'republish' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'soapbox':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'post_like' , 'republish' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
case 'repository':
$ret['perms_auto'] = true;
$ret['default_collection'] = false;
$ret['directory_publish'] = true;
$ret['online'] = false;
$ret['perms_connect'] = [
'view_stream', 'view_profile', 'view_contacts', 'view_storage',
'view_pages', 'write_storage', 'write_pages', 'post_wall', 'post_comments', 'tag_deliver',
'post_mail', 'post_like' , 'republish', 'chat' ];
$ret['limits'] = [
'view_stream' => PERMS_PUBLIC,
'view_profile' => PERMS_PUBLIC,
'view_contacts' => PERMS_PUBLIC,
'view_storage' => PERMS_PUBLIC,
'view_pages' => PERMS_PUBLIC,
'send_stream' => PERMS_SPECIFIC,
'post_wall' => PERMS_SPECIFIC,
'post_comments' => PERMS_SPECIFIC,
'post_mail' => PERMS_SPECIFIC,
'post_like' => PERMS_SPECIFIC,
'tag_deliver' => PERMS_SPECIFIC,
'chat' => PERMS_SPECIFIC,
'write_storage' => PERMS_SPECIFIC,
'write_pages' => PERMS_SPECIFIC,
'republish' => PERMS_SPECIFIC,
'delegate' => PERMS_SPECIFIC
];
break;
default:
break;
}
$x = get_config('system','role_perms');
// let system settings over-ride any or all
if($x && is_array($x) && array_key_exists($role,$x))
$ret = array_merge($ret,$x[$role]);
call_hooks('get_role_perms',$ret);
return $ret;
}
/**
* @brief Returns a list or roles, grouped by type.
*
* @return string Returns an array of roles, grouped by type
*/
function get_roles() {
$roles = array(
t('Social Networking') => array('social' => t('Social - Mostly Public'), 'social_restricted' => t('Social - Restricted'), 'social_private' => t('Social - Private')),
t('Community Forum') => array('forum' => t('Forum - Mostly Public'), 'forum_restricted' => t('Forum - Restricted'), 'forum_private' => t('Forum - Private')),
t('Feed Republish') => array('feed' => t('Feed - Mostly Public'), 'feed_restricted' => t('Feed - Restricted')),
t('Special Purpose') => array('soapbox' => t('Special - Celebrity/Soapbox'), 'repository' => t('Special - Group Repository')),
t('Other') => array('custom' => t('Custom/Expert Mode'))
);
return $roles;
}

View File

@ -495,12 +495,22 @@ function guess_image_type($filename, $headers = '') {
}
}
if(is_null($type)) {
if(is_null($type) && (strpos($filename,'http') === false)) {
$size = getimagesize($filename);
$ph = photo_factory('');
$types = $ph->supportedTypes();
$type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg');
}
if(is_null($type)) {
if(strpos(strtolower($filename),'jpg') !== false)
$type = 'image/jpeg';
elseif(strpos(strtolower($filename),'jpeg') !== false)
$type = 'image/jpeg';
elseif(strpos(strtolower($filename),'gif') !== false)
$type = 'image/gif';
elseif(strpos(strtolower($filename),'png') !== false)
$type = 'image/png';
}
}
logger('Photo: guess_image_type: type = ' . $type, LOGGER_DEBUG);

View File

@ -17,6 +17,7 @@ require_once('include/text.php');
* @param array $args
* @return array
*/
function photo_upload($channel, $observer, $args) {
$ret = array('success' => false);
@ -28,9 +29,6 @@ function photo_upload($channel, $observer, $args) {
return $ret;
}
//call_hooks('photo_upload_begin', $args);
/*
* Determine the album to use
*/
@ -90,8 +88,6 @@ function photo_upload($channel, $observer, $args) {
} else {
$f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
// call_hooks('photo_upload_file',$f);
if (x($f,'src') && x($f,'filesize')) {
$src = $f['src'];
$filename = $f['filename'];
@ -369,38 +365,38 @@ function photo_upload($channel, $observer, $args) {
else {
$mid = item_message_id();
$arr = array();
$arr = [
'aid' => $account_id,
'uid' => $channel_id,
'mid' => $mid,
'parent_mid' => $mid,
'item_hidden' => $item_hidden,
'resource_type' => 'photo',
'resource_id' => $photo_hash,
'owner_xchan' => $channel['channel_hash'],
'author_xchan' => $observer['xchan_hash'],
'title' => $title,
'allow_cid' => $ac['allow_cid'],
'allow_gid' => $ac['allow_gid'],
'deny_cid' => $ac['deny_cid'],
'deny_gid' => $ac['deny_gid'],
'verb' => ACTIVITY_POST,
'obj_type' => ACTIVITY_OBJ_PHOTO,
'obj' => json_encode($object),
'tgt_type' => ACTIVITY_OBJ_ALBUM,
'target' => json_encode($target),
'item_wall' => $visible,
'item_origin' => 1,
'item_thread_top' => 1,
'item_private' => intval($acl->is_private()),
'body' => $summary
];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
if($lat && $lon)
$arr['coord'] = $lat . ' ' . $lon;
$arr['aid'] = $account_id;
$arr['uid'] = $channel_id;
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
$arr['item_hidden'] = $item_hidden;
$arr['resource_type'] = 'photo';
$arr['resource_id'] = $photo_hash;
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['author_xchan'] = $observer['xchan_hash'];
$arr['title'] = $title;
$arr['allow_cid'] = $ac['allow_cid'];
$arr['allow_gid'] = $ac['allow_gid'];
$arr['deny_cid'] = $ac['deny_cid'];
$arr['deny_gid'] = $ac['deny_gid'];
$arr['verb'] = ACTIVITY_POST;
$arr['obj_type'] = ACTIVITY_OBJ_PHOTO;
$arr['obj'] = json_encode($object);
$arr['tgt_type'] = ACTIVITY_OBJ_ALBUM;
$arr['target'] = json_encode($target);
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$arr['body'] = $summary;
// this one is tricky because the item and the photo have the same permissions, those of the photo.
// Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
// private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
@ -446,6 +442,7 @@ function photo_upload($channel, $observer, $args) {
* * \e boolean \b success
* * \e array \b albums
*/
function photos_albums_list($channel, $observer, $sort_key = 'display_path', $direction = 'asc') {
$channel_id = $channel['channel_id'];
@ -545,6 +542,7 @@ function photos_album_widget($channelx,$observer,$sortkey = 'display_path',$dire
* @param string $album default empty
* @return boolean|array
*/
function photos_list_photos($channel, $observer, $album = '') {
$channel_id = $channel['channel_id'];
@ -584,7 +582,10 @@ function photos_list_photos($channel, $observer, $album = '') {
* @param string $album name of the album
* @return boolean
*/
function photos_album_exists($channel_id, $observer_hash, $album) {
$sql_extra = permissions_sql($channel_id,$observer_hash);
$r = q("SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE hash = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1",
@ -605,6 +606,7 @@ function photos_album_exists($channel_id, $observer_hash, $album) {
* @param string $newname The new name of the album
* @return bool|array
*/
function photos_album_rename($channel_id, $oldname, $newname) {
return q("UPDATE photo SET album = '%s' WHERE album = '%s' AND uid = %d",
dbesc($newname),
@ -623,6 +625,7 @@ function photos_album_rename($channel_id, $oldname, $newname) {
* @param string $remote_xchan
* @return string|boolean
*/
function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
if($remote_xchan) {
@ -659,6 +662,7 @@ function photos_album_get_db_idstr($channel_id, $album, $remote_xchan = '') {
* @param boolean $visible default false
* @return int item_id
*/
function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
// Create item container
@ -714,7 +718,7 @@ function getGps($exifCoord, $hemi) {
function getGpstimestamp($exifCoord) {
$hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
$hours = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
$minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
$seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;

View File

@ -122,7 +122,7 @@ function poco_load($xchan = '', $url = null) {
$profile_url = $url['value'];
continue;
}
if($url['type'] == 'zot' || $url['type'] == 'diaspora' || $url['type'] == 'friendica') {
if($url['type'] == 'zot') {
$network = $url['type'];
$address = str_replace('acct:' , '', $url['value']);
continue;
@ -163,12 +163,6 @@ function poco_load($xchan = '', $url = null) {
continue;
}
}
else {
$x = import_author_diaspora(array('address' => $address));
if(! $x) {
continue;
}
}
}
else {
continue;
@ -493,8 +487,6 @@ function poco($a,$extended = false) {
if($fields_ret['urls']) {
$entry['urls'] = array(array('value' => $rr['xchan_url'], 'type' => 'profile'));
$network = $rr['xchan_network'];
if(strpos($network,'friendica') !== false)
$network = 'friendica';
if($rr['xchan_addr'])
$entry['urls'][] = array('value' => 'acct:' . $rr['xchan_addr'], 'type' => $network);
}

View File

@ -648,12 +648,8 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
$where = '';
// We require > 5.4 but leave the version check so that install issues (including version) can be logged
if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
}
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
$s = datetime_convert() . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL;
$pluginfo = array('filename' => $logfile, 'loglevel' => $level, 'message' => $s,'priority' => $priority, 'logged' => false);
@ -687,16 +683,14 @@ function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
@file_put_contents(BTLOGGER_DEBUG_FILE, $s, FILE_APPEND);
}
if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
if($stack) {
for($x = 1; $x < count($stack); $x ++) {
$s = 'stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()';
logger($s,$level, $priority);
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
if($stack) {
for($x = 1; $x < count($stack); $x ++) {
$s = 'stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()';
logger($s,$level, $priority);
if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) {
@file_put_contents(BTLOGGER_DEBUG_FILE, $s . PHP_EOL, FILE_APPEND);
}
if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) {
@file_put_contents(BTLOGGER_DEBUG_FILE, $s . PHP_EOL, FILE_APPEND);
}
}
}
@ -751,10 +745,10 @@ function dlogger($msg, $level = 0) {
return;
$where = '';
if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
}
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
@file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND);
}
@ -1042,19 +1036,6 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) {
));
}
function valid_email_regex($x){
if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x))
return true;
return false;
}
function valid_email($x){
if(get_config('system','disable_email_validation'))
return true;
return valid_email_regex($x);
}
/**
* @brief Replace naked text hyperlink with HTML formatted hyperlink.
*
@ -1199,8 +1180,7 @@ function list_smilies($default_only = false) {
':coffee',
':facepalm',
':like',
':dislike',
':hubzilla'
':dislike'
);
$icons = array(
@ -1234,8 +1214,7 @@ function list_smilies($default_only = false) {
'<img class="smiley" src="' . z_root() . '/images/emoticons/coffee.gif" alt=":coffee" />',
'<img class="smiley" src="' . z_root() . '/images/emoticons/smiley-facepalm.gif" alt=":facepalm" />',
'<img class="smiley" src="' . z_root() . '/images/emoticons/like.gif" alt=":like" />',
'<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />',
'<img class="smiley" src="' . z_root() . '/images/hz-16.png" alt=":hubzilla" />',
'<img class="smiley" src="' . z_root() . '/images/emoticons/dislike.gif" alt=":dislike" />'
);
@ -2008,23 +1987,44 @@ function legal_webbie($s) {
if(! strlen($s))
return '';
$x = $s;
do {
$s = $x;
$x = preg_replace('/^([^a-z])(.*?)/',"$2",$s);
} while($x != $s);
// WARNING: This regex will not work in a federated environment.
// You will probably want something like
// preg_replace('/([^a-z0-9\_])/','',strtolower($s));
$r = preg_replace('/([^a-z0-9\-\_\.])/','',strtolower($s));
$x = [ 'input' => $s, 'output' => $r ];
call_hooks('legal_webbie',$x);
return $x['output'];
return preg_replace('/([^a-z0-9\-\_])/','',$x);
}
function legal_webbie_text() {
// WARNING: This will not work in a federated environment.
$s = t('a-z, 0-9, -, _, and . only');
$x = [ 'text' => $s ];
call_hooks('legal_webbie_text',$x);
return $x['text'];
}
function check_webbie($arr) {
// These names conflict with the CalDAV server
$taken = [ 'principals', 'addressbooks', 'calendars' ];
$reservechan = get_config('system','reserved_channels');
if(strlen($reservechan))
$taken = explode(',', $reservechan);
else
$taken = array('principals','addressbooks','calendars');
if(strlen($reservechan)) {
$taken = array_merge($taken,explode(',', $reservechan));
}
$str = '';
if(count($arr)) {
@ -2274,13 +2274,13 @@ function design_tools() {
$who = $channel['channel_address'];
return replace_macros(get_markup_template('design_tools.tpl'), array(
'$title' => t('Design Tools'),
'$who' => $who,
'$sys' => $sys,
'$title' => t('Design Tools'),
'$who' => $who,
'$sys' => $sys,
'$blocks' => t('Blocks'),
'$menus' => t('Menus'),
'$menus' => t('Menus'),
'$layout' => t('Layouts'),
'$pages' => t('Pages')
'$pages' => t('Pages')
));
}
@ -2301,21 +2301,21 @@ function website_portation_tools() {
}
return replace_macros(get_markup_template('website_portation_tools.tpl'), array(
'$title' => t('Import'),
'$import_label' => t('Import website...'),
'$import_placeholder' => t('Select folder to import'),
'$file_upload_text' => t('Import from a zipped folder:'),
'$file_import_text' => t('Import from cloud files:'),
'$desc' => t('/cloud/channel/path/to/folder'),
'$hint' => t('Enter path to website files'),
'$select' => t('Select folder'),
'$export_label' => t('Export website...'),
'$file_download_text' => t('Export to a zip file'),
'$filename_desc' => t('website.zip'),
'$filename_hint' => t('Enter a name for the zip file.'),
'$cloud_export_text' => t('Export to cloud files'),
'$cloud_export_desc' => t('/path/to/export/folder'),
'$cloud_export_hint' => t('Enter a path to a cloud files destination.'),
'$title' => t('Import'),
'$import_label' => t('Import website...'),
'$import_placeholder' => t('Select folder to import'),
'$file_upload_text' => t('Import from a zipped folder:'),
'$file_import_text' => t('Import from cloud files:'),
'$desc' => t('/cloud/channel/path/to/folder'),
'$hint' => t('Enter path to website files'),
'$select' => t('Select folder'),
'$export_label' => t('Export website...'),
'$file_download_text' => t('Export to a zip file'),
'$filename_desc' => t('website.zip'),
'$filename_hint' => t('Enter a name for the zip file.'),
'$cloud_export_text' => t('Export to cloud files'),
'$cloud_export_desc' => t('/path/to/export/folder'),
'$cloud_export_hint' => t('Enter a path to a cloud files destination.'),
'$cloud_export_select' => t('Specify folder'),
));
}
@ -3022,7 +3022,8 @@ function array2XML($obj, $array) {
if(is_array($value)) {
$node = $obj->addChild($key);
array2XML($node, $value);
} else {
}
else {
$obj->addChild($key, htmlspecialchars($value));
}
}

View File

@ -2237,9 +2237,6 @@ function check_location_move($sender_hash,$locations) {
if(! $locations)
return;
if(get_config('system','server_role') !== 'basic')
return;
if(count($locations) != 1)
return;
@ -2935,8 +2932,6 @@ function import_site($arr, $pubkey) {
function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
if(get_config('system','server_role') === 'basic')
return;
logger('build_sync_packet');
@ -3086,8 +3081,6 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(get_config('system','server_role') === 'basic')
return;
require_once('include/import.php');
@ -3289,6 +3282,11 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(! array_key_exists('abook_xchan',$clean))
continue;
if(array_key_exists('abook_instance',$clean) && $clean['abook_instance'] && strpos($clean['abook_instance'],z_root()) === false) {
$clean['abook_not_here'] = 1;
}
$r = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($clean['abook_xchan']),
intval($channel['channel_id'])
@ -3586,6 +3584,14 @@ function import_author_zot($x) {
$hash = make_xchan_hash($x['guid'],$x['guid_sig']);
// also - this function may get passed a profile url as 'url' and zot_refresh wants a hubloc_url (site baseurl),
// so deconstruct the url (if we have one) and rebuild it with just the baseurl components.
if(array_key_exists('url',$x)) {
$m = parse_url($x['url']);
$desturl = $m['scheme'] . '://' . $m['host'];
}
$r1 = q("select hubloc_url, hubloc_updated, site_dead from hubloc left join site on
hubloc_url = site_url where hubloc_guid = '%s' and hubloc_guid_sig = '%s' and hubloc_primary = 1 limit 1",
dbesc($x['guid']),
@ -3627,14 +3633,16 @@ function import_author_zot($x) {
);
if($r) {
logger('found another site that is not dead: ' . $r[0]['hubloc_url'], LOGGER_DEBUG,LOG_INFO);
$x['url'] = $r[0]['hubloc_url'];
$desturl = $r[0]['hubloc_url'];
}
else {
return $hash;
}
}
$them = array('hubloc_url' => $x['url'], 'xchan_guid' => $x['guid'], 'xchan_guid_sig' => $x['guid_sig']);
$them = array('hubloc_url' => $desturl, 'xchan_guid' => $x['guid'], 'xchan_guid_sig' => $x['guid_sig']);
if(zot_refresh($them))
return $hash;
@ -3921,6 +3929,7 @@ function zotinfo($arr) {
$ret['photo_updated'] = $e['xchan_photo_date'];
$ret['url'] = $e['xchan_url'];
$ret['connections_url']= (($e['xchan_connurl']) ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']);
$ret['follow_url'] = $e['xchan_follow'];
$ret['target'] = $ztarget;
$ret['target_sig'] = $zsig;
$ret['searchable'] = $searchable;
@ -3928,19 +3937,22 @@ function zotinfo($arr) {
$ret['public_forum'] = $public_forum;
if($deleted)
$ret['deleted'] = $deleted;
if(intval($e['channel_removed']))
$ret['deleted_locally'] = true;
// premium or other channel desiring some contact with potential followers before connecting.
// This is a template - %s will be replaced with the follow_url we discover for the return channel.
if($special_channel)
$ret['connect_url'] = z_root() . '/connect/' . $e['channel_address'];
if($special_channel) {
$ret['connect_url'] = (($e['xchan_connpage']) ? $e['xchan_connpage'] : z_root() . '/connect/' . $e['channel_address']);
}
// This is a template for our follow url, %s will be replaced with a webbie
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
if(! $ret['follow_url'])
$ret['follow_url'] = z_root() . '/follow?f=&url=%s';
$permissions = get_all_perms($e['channel_id'],$ztarget_hash,false);

View File

@ -44,14 +44,6 @@ App::$config['system']['sitename'] = "Hubzilla";
App::$config['system']['location_hash'] = 'if the auto install failed, put a unique random string here';
// Choices are 'basic', 'standard', and 'pro'.
// basic sets up the sevrer for basic social networking and removes "complicated" features
// standard provides most desired features except e-commerce
// pro gives you access to everything, but removes cross-platform federation/emulation
App::$config['system']['server_role'] = 'standard';
// These lines set additional security headers to be sent with all responses
// You may wish to set transport_security_header to 0 if your server already sends
// this header. content_security_policy may need to be disabled if you wish to

View File

@ -43,8 +43,6 @@ CREATE TABLE IF NOT EXISTS `abook` (
KEY `abook_account` (`abook_account`),
KEY `abook_channel` (`abook_channel`),
KEY `abook_xchan` (`abook_xchan`),
KEY `abook_my_perms` (`abook_my_perms`),
KEY `abook_their_perms` (`abook_their_perms`),
KEY `abook_closeness` (`abook_closeness`),
KEY `abook_created` (`abook_created`),
KEY `abook_updated` (`abook_updated`),
@ -147,8 +145,8 @@ CREATE TABLE IF NOT EXISTS `app` (
CREATE TABLE IF NOT EXISTS `atoken` (
`atoken_id` int(11) NOT NULL AUTO_INCREMENT,
`atoken_aid` int(11) NOT NULL DEFAULT 0,
`atoken_uid` int(11) NOT NULL DEFAULT 0,
`atoken_aid` int(11) NOT NULL DEFAULT 0 ,
`atoken_uid` int(11) NOT NULL DEFAULT 0 ,
`atoken_name` char(191) NOT NULL DEFAULT '',
`atoken_token` char(191) NOT NULL DEFAULT '',
`atoken_expires` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -165,13 +163,13 @@ CREATE TABLE IF NOT EXISTS `attach` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`aid` int(10) unsigned NOT NULL DEFAULT 0 ,
`uid` int(10) unsigned NOT NULL DEFAULT 0 ,
`hash` char(64) NOT NULL DEFAULT '',
`creator` char(128) NOT NULL DEFAULT '',
`hash` char(191) NOT NULL DEFAULT '',
`creator` char(191) NOT NULL DEFAULT '',
`filename` char(191) NOT NULL DEFAULT '',
`filetype` char(64) NOT NULL DEFAULT '',
`filetype` char(191) NOT NULL DEFAULT '',
`filesize` int(10) unsigned NOT NULL DEFAULT 0 ,
`revision` int(10) unsigned NOT NULL DEFAULT 0 ,
`folder` char(64) NOT NULL DEFAULT '',
`folder` char(191) NOT NULL DEFAULT '',
`flags` int(10) unsigned NOT NULL DEFAULT 0 ,
`is_dir` tinyint(1) NOT NULL DEFAULT 0 ,
`is_photo` tinyint(1) NOT NULL DEFAULT 0 ,
@ -223,14 +221,14 @@ CREATE TABLE IF NOT EXISTS `cal` (
`cal_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`cal_aid` int(10) unsigned NOT NULL DEFAULT 0 ,
`cal_uid` int(10) unsigned NOT NULL DEFAULT 0 ,
`cal_hash` varchar(255) NOT NULL DEFAULT '',
`cal_name` varchar(255) NOT NULL DEFAULT '',
`uri` varchar(255) NOT NULL DEFAULT '',
`logname` varchar(255) NOT NULL DEFAULT '',
`pass` varchar(255) NOT NULL DEFAULT '',
`ctag` varchar(255) NOT NULL DEFAULT '',
`synctoken` varchar(255) NOT NULL DEFAULT '',
`cal_types` varchar(255) NOT NULL DEFAULT '',
`cal_hash` varchar(191) NOT NULL DEFAULT '',
`cal_name` varchar(191) NOT NULL DEFAULT '',
`uri` varchar(191) NOT NULL DEFAULT '',
`logname` varchar(191) NOT NULL DEFAULT '',
`pass` varchar(191) NOT NULL DEFAULT '',
`ctag` varchar(191) NOT NULL DEFAULT '',
`synctoken` varchar(191) NOT NULL DEFAULT '',
`cal_types` varchar(191) NOT NULL DEFAULT '',
PRIMARY KEY (`cal_id`),
KEY `cal_aid` (`cal_aid`),
KEY `cal_uid` (`cal_uid`),
@ -289,8 +287,8 @@ CREATE TABLE IF NOT EXISTS `channel` (
`channel_removed` tinyint(1) NOT NULL DEFAULT 0 ,
`channel_system` tinyint(1) NOT NULL DEFAULT 0 ,
`channel_moved` char(191) NOT NULL DEFAULT '',
`channel_password` varchar(255) NOT NULL,
`channel_salt` varchar(255) NOT NULL,
`channel_password` varchar(191) NOT NULL,
`channel_salt` varchar(191) NOT NULL,
PRIMARY KEY (`channel_id`),
KEY `channel_address` (`channel_address`),
KEY `channel_account_id` (`channel_account_id`),
@ -304,29 +302,11 @@ CREATE TABLE IF NOT EXISTS `channel` (
KEY `channel_max_anon_mail` (`channel_max_anon_mail`),
KEY `channel_max_friend_req` (`channel_max_friend_req`),
KEY `channel_default_gid` (`channel_default_group`),
KEY `channel_r_stream` (`channel_r_stream`),
KEY `channel_r_profile` (`channel_r_profile`),
KEY `channel_r_photos` (`channel_r_photos`),
KEY `channel_r_abook` (`channel_r_abook`),
KEY `channel_w_stream` (`channel_w_stream`),
KEY `channel_w_wall` (`channel_w_wall`),
KEY `channel_w_tagwall` (`channel_w_tagwall`),
KEY `channel_w_comment` (`channel_w_comment`),
KEY `channel_w_mail` (`channel_w_mail`),
KEY `channel_w_photos` (`channel_w_photos`),
KEY `channel_w_chat` (`channel_w_chat`),
KEY `channel_guid` (`channel_guid`),
KEY `channel_hash` (`channel_hash`),
KEY `channel_expire_days` (`channel_expire_days`),
KEY `channel_a_delegate` (`channel_a_delegate`),
KEY `channel_r_storage` (`channel_r_storage`),
KEY `channel_w_storage` (`channel_w_storage`),
KEY `channel_r_pages` (`channel_r_pages`),
KEY `channel_w_pages` (`channel_w_pages`),
KEY `channel_deleted` (`channel_deleted`),
KEY `channel_a_republish` (`channel_a_republish`),
KEY `channel_dirdate` (`channel_dirdate`),
KEY `channel_w_like` (`channel_w_like`),
KEY `channel_removed` (`channel_removed`),
KEY `channel_system` (`channel_system`),
KEY `channel_lastpost` (`channel_lastpost`),
@ -381,8 +361,8 @@ CREATE TABLE IF NOT EXISTS `chatroom` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `clients` (
`client_id` varchar(20) NOT NULL DEFAULT '',
`pw` varchar(20) NOT NULL DEFAULT '',
`client_id` varchar(191) NOT NULL DEFAULT '',
`pw` varchar(191) NOT NULL DEFAULT '',
`redirect_uri` varchar(200) NOT NULL DEFAULT '',
`clname` text,
`icon` text,
@ -541,6 +521,7 @@ CREATE TABLE IF NOT EXISTS `hubloc` (
PRIMARY KEY (`hubloc_id`),
KEY `hubloc_url` (`hubloc_url`),
KEY `hubloc_guid` (`hubloc_guid`),
KEY `hubloc_hash` (`hubloc_hash`),
KEY `hubloc_flags` (`hubloc_flags`),
KEY `hubloc_connect` (`hubloc_connect`),
KEY `hubloc_host` (`hubloc_host`),
@ -731,13 +712,13 @@ CREATE TABLE IF NOT EXISTS `item_id` (
CREATE TABLE IF NOT EXISTS `likes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`channel_id` int(10) unsigned NOT NULL DEFAULT 0 ,
`liker` char(128) NOT NULL DEFAULT '',
`likee` char(128) NOT NULL DEFAULT '',
`liker` char(191) NOT NULL DEFAULT '',
`likee` char(191) NOT NULL DEFAULT '',
`iid` int(11) unsigned NOT NULL DEFAULT 0 ,
`i_mid` char(191) NOT NULL DEFAULT '',
`verb` char(191) NOT NULL DEFAULT '',
`target_type` char(191) NOT NULL DEFAULT '',
`target_id` char(128) NOT NULL DEFAULT '',
`target_id` char(191) NOT NULL DEFAULT '',
`target` mediumtext NOT NULL,
PRIMARY KEY (`id`),
KEY `liker` (`liker`),
@ -831,7 +812,7 @@ CREATE TABLE IF NOT EXISTS `menu_item` (
CREATE TABLE IF NOT EXISTS `notify` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hash` char(64) NOT NULL DEFAULT '',
`hash` char(191) NOT NULL DEFAULT '',
`xname` char(191) NOT NULL DEFAULT '',
`url` char(191) NOT NULL DEFAULT '',
`photo` char(191) NOT NULL DEFAULT '',
@ -1219,9 +1200,9 @@ CREATE TABLE IF NOT EXISTS `term` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `tokens` (
`id` varchar(40) NOT NULL DEFAULT '',
`id` varchar(191) NOT NULL DEFAULT '',
`secret` text NOT NULL,
`client_id` varchar(20) NOT NULL DEFAULT '',
`client_id` varchar(191) NOT NULL DEFAULT '',
`expires` bigint(20) unsigned NOT NULL DEFAULT 0 ,
`auth_scope` varchar(512) NOT NULL DEFAULT '',
`uid` int(11) NOT NULL DEFAULT 0 ,
@ -1233,7 +1214,7 @@ CREATE TABLE IF NOT EXISTS `tokens` (
CREATE TABLE IF NOT EXISTS `updates` (
`ud_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ud_hash` char(128) NOT NULL DEFAULT '',
`ud_hash` char(191) NOT NULL DEFAULT '',
`ud_guid` char(191) NOT NULL DEFAULT '',
`ud_date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`ud_last` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -1423,3 +1404,174 @@ CREATE TABLE IF NOT EXISTS `xtag` (
KEY `xtag_hash` (`xtag_hash`),
KEY `xtag_flags` (`xtag_flags`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists addressbooks (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
principaluri VARBINARY(255),
displayname VARCHAR(255),
uri VARBINARY(200),
description TEXT,
synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
UNIQUE(principaluri(100), uri(100))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists cards (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
addressbookid INT(11) UNSIGNED NOT NULL,
carddata MEDIUMBLOB,
uri VARBINARY(200),
lastmodified INT(11) UNSIGNED,
etag VARBINARY(32),
size INT(11) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists addressbookchanges (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
synctoken INT(11) UNSIGNED NOT NULL,
addressbookid INT(11) UNSIGNED NOT NULL,
operation TINYINT(1) NOT NULL,
INDEX addressbookid_synctoken (addressbookid, synctoken)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendarobjects (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
calendardata MEDIUMBLOB,
uri VARBINARY(200),
calendarid INTEGER UNSIGNED NOT NULL,
lastmodified INT(11) UNSIGNED,
etag VARBINARY(32),
size INT(11) UNSIGNED NOT NULL,
componenttype VARBINARY(8),
firstoccurence INT(11) UNSIGNED,
lastoccurence INT(11) UNSIGNED,
uid VARBINARY(200),
UNIQUE(calendarid, uri),
INDEX calendarid_time (calendarid, firstoccurence)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendars (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
components VARBINARY(21)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendarinstances (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
calendarid INTEGER UNSIGNED NOT NULL,
principaluri VARBINARY(100),
access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = read, 3 = readwrite',
displayname VARCHAR(100),
uri VARBINARY(200),
description TEXT,
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
timezone TEXT,
transparent TINYINT(1) NOT NULL DEFAULT '0',
share_href VARBINARY(100),
share_displayname VARCHAR(100),
share_invitestatus TINYINT(1) NOT NULL DEFAULT '2' COMMENT '1 = noresponse, 2 = accepted, 3 = declined, 4 = invalid',
UNIQUE(principaluri, uri),
UNIQUE(calendarid, principaluri),
UNIQUE(calendarid, share_href)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendarchanges (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
synctoken INT(11) UNSIGNED NOT NULL,
calendarid INT(11) UNSIGNED NOT NULL,
operation TINYINT(1) NOT NULL,
INDEX calendarid_synctoken (calendarid, synctoken)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendarsubscriptions (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
principaluri VARBINARY(100) NOT NULL,
source TEXT,
displayname VARCHAR(100),
refreshrate VARCHAR(10),
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
striptodos TINYINT(1) NULL,
stripalarms TINYINT(1) NULL,
stripattachments TINYINT(1) NULL,
lastmodified INT(11) UNSIGNED,
UNIQUE(principaluri, uri)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists schedulingobjects (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
principaluri VARBINARY(255),
calendardata MEDIUMBLOB,
uri VARBINARY(200),
lastmodified INT(11) UNSIGNED,
etag VARBINARY(32),
size INT(11) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists locks (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
owner VARCHAR(100),
timeout INTEGER UNSIGNED,
created INTEGER,
token VARBINARY(100),
scope TINYINT,
depth TINYINT,
uri VARBINARY(1000),
INDEX(token),
INDEX(uri(100))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists principals (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
uri VARBINARY(200) NOT NULL,
email VARBINARY(80),
displayname VARCHAR(80),
UNIQUE(uri)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists groupmembers (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
principal_id INTEGER UNSIGNED NOT NULL,
member_id INTEGER UNSIGNED NOT NULL,
UNIQUE(principal_id, member_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists propertystorage (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
path VARBINARY(1024) NOT NULL,
name VARBINARY(100) NOT NULL,
valuetype INT UNSIGNED,
value MEDIUMBLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE UNIQUE INDEX path_property ON propertystorage (path(600), name(100));
CREATE TABLE if not exists users (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARBINARY(50),
digesta1 VARBINARY(32),
UNIQUE(username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE if not exists calendarinstances (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
calendarid INTEGER UNSIGNED NOT NULL,
principaluri VARBINARY(100),
access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = read, 3 = readwrite',
displayname VARCHAR(100),
uri VARBINARY(200),
description TEXT,
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
timezone TEXT,
transparent TINYINT(1) NOT NULL DEFAULT '0',
share_href VARBINARY(100),
share_displayname VARCHAR(100),
share_invitestatus TINYINT(1) NOT NULL DEFAULT '2' COMMENT '1 = noresponse, 2 = accepted, 3 = declined, 4 = invalid',
UNIQUE(principaluri, uri),
UNIQUE(calendarid, principaluri),
UNIQUE(calendarid, share_href)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -1,6 +1,6 @@
CREATE TABLE "abconfig" (
"id" serial NOT NULL,
"chan" bigint NOT NULL DEFAULT 0,
"chan" bigint NOT NULL DEFAULT '0',
"xchan" text NOT NULL,
"cat" text NOT NULL,
"k" text NOT NULL,
@ -16,23 +16,21 @@ CREATE TABLE "abook" (
"abook_account" bigint NOT NULL,
"abook_channel" bigint NOT NULL,
"abook_xchan" text NOT NULL DEFAULT '',
"abook_my_perms" bigint NOT NULL DEFAULT 0,
"abook_their_perms" bigint NOT NULL DEFAULT 0,
"abook_closeness" numeric(3) NOT NULL DEFAULT 99,
"abook_closeness" numeric(3) NOT NULL DEFAULT '99',
"abook_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"abook_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"abook_connected" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"abook_dob" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"abook_flags" bigint NOT NULL DEFAULT 0 ,
"abook_blocked" smallint NOT NULL DEFAULT 0 ,
"abook_ignored" smallint NOT NULL DEFAULT 0 ,
"abook_hidden" smallint NOT NULL DEFAULT 0 ,
"abook_archived" smallint NOT NULL DEFAULT 0 ,
"abook_pending" smallint NOT NULL DEFAULT 0 ,
"abook_unconnected" smallint NOT NULL DEFAULT 0 ,
"abook_self" smallint NOT NULL DEFAULT 0 ,
"abook_feed" smallint NOT NULL DEFAULT 0 ,
"abook_not_here" smallint NOT NULL DEFAULT 0 ,
"abook_flags" bigint NOT NULL DEFAULT '0',
"abook_blocked" smallint NOT NULL DEFAULT '0',
"abook_ignored" smallint NOT NULL DEFAULT '0',
"abook_hidden" smallint NOT NULL DEFAULT '0',
"abook_archived" smallint NOT NULL DEFAULT '0',
"abook_pending" smallint NOT NULL DEFAULT '0',
"abook_unconnected" smallint NOT NULL DEFAULT '0',
"abook_self" smallint NOT NULL DEFAULT '0',
"abook_feed" smallint NOT NULL DEFAULT '0',
"abook_not_here" smallint NOT NULL DEFAULT '0',
"abook_profile" varchar(64) NOT NULL DEFAULT '',
"abook_incl" TEXT NOT NULL DEFAULT '',
"abook_excl" TEXT NOT NULL DEFAULT '',
@ -42,8 +40,6 @@ CREATE TABLE "abook" (
create index "abook_account" on abook ("abook_account");
create index "abook_channel" on abook ("abook_channel");
create index "abook_xchan" on abook ("abook_xchan");
create index "abook_my_perms" on abook ("abook_my_perms");
create index "abook_their_perms" on abook ("abook_their_perms");
create index "abook_closeness" on abook ("abook_closeness");
create index "abook_created" on abook ("abook_created");
create index "abook_updated" on abook ("abook_updated");
@ -64,8 +60,8 @@ CREATE TABLE "abook" (
CREATE TABLE "account" (
"account_id" serial NOT NULL,
"account_parent" bigint NOT NULL DEFAULT 0 ,
"account_default_channel" bigint NOT NULL DEFAULT 0 ,
"account_parent" bigint NOT NULL DEFAULT '0',
"account_default_channel" bigint NOT NULL DEFAULT '0',
"account_salt" varchar(32) NOT NULL DEFAULT '',
"account_password" text NOT NULL DEFAULT '',
"account_email" text NOT NULL DEFAULT '',
@ -73,13 +69,13 @@ CREATE TABLE "account" (
"account_language" varchar(16) NOT NULL DEFAULT 'en',
"account_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"account_lastlog" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"account_flags" bigint NOT NULL DEFAULT 0 ,
"account_roles" bigint NOT NULL DEFAULT 0 ,
"account_flags" bigint NOT NULL DEFAULT '0',
"account_roles" bigint NOT NULL DEFAULT '0',
"account_reset" text NOT NULL DEFAULT '',
"account_expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"account_expire_notified" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"account_service_class" varchar(32) NOT NULL DEFAULT '',
"account_level" bigint NOT NULL DEFAULT 0 ,
"account_level" bigint NOT NULL DEFAULT '0',
"account_password_changed" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY ("account_id")
);
@ -97,11 +93,11 @@ create index "account_password_changed" on account ("account_password_changed")
CREATE TABLE "addon" (
"id" serial NOT NULL,
"aname" text NOT NULL,
"version" text NOT NULL DEFAULT 0 ,
"installed" numeric(1) NOT NULL DEFAULT 0 ,
"hidden" numeric(1) NOT NULL DEFAULT 0 ,
"tstamp" numeric(20) NOT NULL DEFAULT 0 ,
"plugin_admin" numeric(1) NOT NULL DEFAULT 0 ,
"version" text NOT NULL DEFAULT '0',
"installed" numeric(1) NOT NULL DEFAULT '0',
"hidden" numeric(1) NOT NULL DEFAULT '0',
"tstamp" numeric(20) NOT NULL DEFAULT '0',
"plugin_admin" numeric(1) NOT NULL DEFAULT '0',
PRIMARY KEY ("id")
);
create index "addon_hidden_idx" on addon ("hidden");
@ -117,13 +113,13 @@ CREATE TABLE "app" (
"app_url" text NOT NULL DEFAULT '',
"app_photo" text NOT NULL DEFAULT '',
"app_version" text NOT NULL DEFAULT '',
"app_channel" bigint NOT NULL DEFAULT 0 ,
"app_channel" bigint NOT NULL DEFAULT '0',
"app_addr" text NOT NULL DEFAULT '',
"app_price" text NOT NULL DEFAULT '',
"app_page" text NOT NULL DEFAULT '',
"app_requires" text NOT NULL DEFAULT '',
"app_deleted" smallint NOT NULL DEFAULT 0 ,
"app_system" smallint NOT NULL DEFAULT 0 ,
"app_deleted" smallint NOT NULL DEFAULT '0',
"app_system" smallint NOT NULL DEFAULT '0',
"app_plugin" text NOT NULL DEFAULT '',
"app_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"app_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -158,19 +154,19 @@ create index atoken_expires on atoken (atoken_expires);
CREATE TABLE "attach" (
"id" serial NOT NULL,
"aid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL DEFAULT '0',
"hash" varchar(64) NOT NULL DEFAULT '',
"creator" varchar(128) NOT NULL DEFAULT '',
"filename" text NOT NULL DEFAULT '',
"filetype" varchar(64) NOT NULL DEFAULT '',
"filesize" bigint NOT NULL DEFAULT 0 ,
"revision" bigint NOT NULL DEFAULT 0 ,
"filesize" bigint NOT NULL DEFAULT '0',
"revision" bigint NOT NULL DEFAULT '0',
"folder" varchar(64) NOT NULL DEFAULT '',
"flags" bigint NOT NULL DEFAULT 0 ,
"is_dir" smallint NOT NULL DEFAULT 0 ,
"is_photo" smallint NOT NULL DEFAULT 0 ,
"os_storage" smallint NOT NULL DEFAULT 0 ,
"flags" bigint NOT NULL DEFAULT '0',
"is_dir" smallint NOT NULL DEFAULT '0',
"is_photo" smallint NOT NULL DEFAULT '0',
"os_storage" smallint NOT NULL DEFAULT '0',
"os_path" text NOT NULL,
"display_path" text NOT NULL,
"content" bytea NOT NULL,
@ -214,8 +210,8 @@ CREATE TABLE "cache" (
);
CREATE TABLE "cal" (
"cal_id" serial NOT NULL,
"cal_aid" bigint NOT NULL DEFAULT 0 ,
"cal_uid" bigint NOT NULL DEFAULT 0 ,
"cal_aid" bigint NOT NULL DEFAULT '0',
"cal_uid" bigint NOT NULL DEFAULT '0',
"cal_hash" text NOT NULL,
"cal_name" text NOT NULL,
"uri" text NOT NULL,
@ -223,7 +219,7 @@ CREATE TABLE "cal" (
"pass" text NOT NULL,
"ctag" text NOT NULL,
"synctoken" text NOT NULL,
"cal_types" text NOT NULL DEFAULT 0 ,
"cal_types" text NOT NULL DEFAULT '0',
PRIMARY KEY ("cal_id")
);
create index "cal_hash_idx" on cal ("cal_hash");
@ -234,8 +230,8 @@ create index "cal_uid_idx" on cal ("cal_uid");
CREATE TABLE "channel" (
"channel_id" serial NOT NULL,
"channel_account_id" bigint NOT NULL DEFAULT 0 ,
"channel_primary" numeric(1) NOT NULL DEFAULT 0 ,
"channel_account_id" bigint NOT NULL DEFAULT '0',
"channel_primary" numeric(1) NOT NULL DEFAULT '0',
"channel_name" text NOT NULL DEFAULT '',
"channel_address" text NOT NULL DEFAULT '',
"channel_guid" text NOT NULL DEFAULT '',
@ -247,40 +243,22 @@ CREATE TABLE "channel" (
"channel_startpage" text NOT NULL DEFAULT '',
"channel_pubkey" text NOT NULL,
"channel_prvkey" text NOT NULL,
"channel_notifyflags" bigint NOT NULL DEFAULT 65535,
"channel_pageflags" bigint NOT NULL DEFAULT 0 ,
"channel_notifyflags" bigint NOT NULL DEFAULT '65535',
"channel_pageflags" bigint NOT NULL DEFAULT '0',
"channel_dirdate" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"channel_lastpost" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"channel_deleted" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"channel_max_anon_mail" bigint NOT NULL DEFAULT 10,
"channel_max_friend_req" bigint NOT NULL DEFAULT 10,
"channel_expire_days" bigint NOT NULL DEFAULT 0 ,
"channel_max_anon_mail" bigint NOT NULL DEFAULT '10',
"channel_max_friend_req" bigint NOT NULL DEFAULT '10',
"channel_expire_days" bigint NOT NULL DEFAULT '0',
"channel_passwd_reset" text NOT NULL DEFAULT '',
"channel_default_group" text NOT NULL DEFAULT '',
"channel_allow_cid" text ,
"channel_allow_gid" text ,
"channel_deny_cid" text ,
"channel_deny_gid" text ,
"channel_r_stream" bigint NOT NULL DEFAULT 0,
"channel_r_profile" bigint NOT NULL DEFAULT 0,
"channel_r_photos" bigint NOT NULL DEFAULT 0,
"channel_r_abook" bigint NOT NULL DEFAULT 0,
"channel_w_stream" bigint NOT NULL DEFAULT 0,
"channel_w_wall" bigint NOT NULL DEFAULT 0,
"channel_w_tagwall" bigint NOT NULL DEFAULT 0,
"channel_w_comment" bigint NOT NULL DEFAULT 0,
"channel_w_mail" bigint NOT NULL DEFAULT 0,
"channel_w_photos" bigint NOT NULL DEFAULT 0,
"channel_w_chat" bigint NOT NULL DEFAULT 0,
"channel_a_delegate" bigint NOT NULL DEFAULT 0 ,
"channel_r_storage" bigint NOT NULL DEFAULT 0,
"channel_w_storage" bigint NOT NULL DEFAULT 0,
"channel_r_pages" bigint NOT NULL DEFAULT 0,
"channel_w_pages" bigint NOT NULL DEFAULT 0,
"channel_a_republish" bigint NOT NULL DEFAULT 0,
"channel_w_like" bigint NOT NULL DEFAULT 0,
"channel_removed" smallint NOT NULL DEFAULT 0 ,
"channel_system" smallint NOT NULL DEFAULT 0 ,
"channel_removed" smallint NOT NULL DEFAULT '0',
"channel_system" smallint NOT NULL DEFAULT '0',
"channel_moved" text NOT NULL DEFAULT '',
"channel_password" varchar(255) NOT NULL,
"channel_salt" varchar(255) NOT NULL,
@ -298,28 +276,10 @@ create index "channel_pageflags" on channel ("channel_pageflags");
create index "channel_max_anon_mail" on channel ("channel_max_anon_mail");
create index "channel_max_friend_req" on channel ("channel_max_friend_req");
create index "channel_default_gid" on channel ("channel_default_group");
create index "channel_r_stream" on channel ("channel_r_stream");
create index "channel_r_profile" on channel ("channel_r_profile");
create index "channel_r_photos" on channel ("channel_r_photos");
create index "channel_r_abook" on channel ("channel_r_abook");
create index "channel_w_stream" on channel ("channel_w_stream");
create index "channel_w_wall" on channel ("channel_w_wall");
create index "channel_w_tagwall" on channel ("channel_w_tagwall");
create index "channel_w_comment" on channel ("channel_w_comment");
create index "channel_w_mail" on channel ("channel_w_mail");
create index "channel_w_photos" on channel ("channel_w_photos");
create index "channel_w_chat" on channel ("channel_w_chat");
create index "channel_guid" on channel ("channel_guid");
create index "channel_hash" on channel ("channel_hash");
create index "channel_expire_days" on channel ("channel_expire_days");
create index "channel_a_delegate" on channel ("channel_a_delegate");
create index "channel_r_storage" on channel ("channel_r_storage");
create index "channel_w_storage" on channel ("channel_w_storage");
create index "channel_r_pages" on channel ("channel_r_pages");
create index "channel_w_pages" on channel ("channel_w_pages");
create index "channel_deleted" on channel ("channel_deleted");
create index "channel_a_republish" on channel ("channel_a_republish");
create index "channel_w_like" on channel ("channel_w_like");
create index "channel_dirdate" on channel ("channel_dirdate");
create index "channel_lastpost" on channel ("channel_lastpost");
create index "channel_removed" on channel ("channel_removed");
@ -327,7 +287,7 @@ create index "channel_system" on channel ("channel_system");
create index "channel_moved" on channel ("channel_moved");
CREATE TABLE "chat" (
"chat_id" serial NOT NULL,
"chat_room" bigint NOT NULL DEFAULT 0 ,
"chat_room" bigint NOT NULL DEFAULT '0',
"chat_xchan" text NOT NULL DEFAULT '',
"chat_text" text NOT NULL,
"created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -338,7 +298,7 @@ create index "chat_xchan_idx" on chat ("chat_xchan");
create index "chat_created_idx" on chat ("created");
CREATE TABLE "chatpresence" (
"cp_id" serial NOT NULL,
"cp_room" bigint NOT NULL DEFAULT 0 ,
"cp_room" bigint NOT NULL DEFAULT '0',
"cp_xchan" text NOT NULL DEFAULT '',
"cp_last" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"cp_status" text NOT NULL,
@ -352,12 +312,12 @@ create index "cp_status" on chatpresence ("cp_status");
CREATE TABLE "chatroom" (
"cr_id" serial NOT NULL,
"cr_aid" bigint NOT NULL DEFAULT 0 ,
"cr_uid" bigint NOT NULL DEFAULT 0 ,
"cr_aid" bigint NOT NULL DEFAULT '0',
"cr_uid" bigint NOT NULL DEFAULT '0',
"cr_name" text NOT NULL DEFAULT '',
"cr_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"cr_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"cr_expire" bigint NOT NULL DEFAULT 0 ,
"cr_expire" bigint NOT NULL DEFAULT '0',
"allow_cid" text NOT NULL,
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
@ -376,7 +336,7 @@ CREATE TABLE "clients" (
"redirect_uri" varchar(200) NOT NULL,
"clname" text,
"icon" text,
"uid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT '0',
PRIMARY KEY ("client_id")
);
CREATE TABLE "config" (
@ -403,7 +363,7 @@ create index "conv_updated_idx" on conv ("updated");
CREATE TABLE IF NOT EXISTS "dreport" (
"dreport_id" serial NOT NULL,
"dreport_channel" int NOT NULL DEFAULT 0 ,
"dreport_channel" int NOT NULL DEFAULT '0',
"dreport_mid" varchar(255) NOT NULL DEFAULT '',
"dreport_site" varchar(255) NOT NULL DEFAULT '',
"dreport_recip" varchar(255) NOT NULL DEFAULT '',
@ -423,9 +383,9 @@ create index "dreport_channel" on dreport ("dreport_channel");
CREATE TABLE "event" (
"id" serial NOT NULL,
"aid" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL,
"cal_id" bigint NOT NULL DEFAULT 0 ,
"cal_id" bigint NOT NULL DEFAULT '0',
"event_xchan" text NOT NULL DEFAULT '',
"event_hash" text NOT NULL DEFAULT '',
"created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -436,19 +396,19 @@ CREATE TABLE "event" (
"description" text NOT NULL,
"location" text NOT NULL,
"etype" text NOT NULL,
"nofinish" numeric(1) NOT NULL DEFAULT 0 ,
"adjust" numeric(1) NOT NULL DEFAULT 1,
"dismissed" numeric(1) NOT NULL DEFAULT 0 ,
"nofinish" numeric(1) NOT NULL DEFAULT '0',
"adjust" numeric(1) NOT NULL DEFAULT '1',
"dismissed" numeric(1) NOT NULL DEFAULT '0',
"allow_cid" text NOT NULL,
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
"deny_gid" text NOT NULL,
"event_status" varchar(255) NOT NULL DEFAULT '',
"event_status_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"event_percent" smallint NOT NULL DEFAULT 0 ,
"event_percent" smallint NOT NULL DEFAULT '0',
"event_repeat" text NOT NULL,
"event_sequence" smallint NOT NULL DEFAULT 0 ,
"event_priority" smallint NOT NULL DEFAULT 0 ,
"event_sequence" smallint NOT NULL DEFAULT '0',
"event_priority" smallint NOT NULL DEFAULT '0',
"event_vdata" text NOT NULL,
PRIMARY KEY ("id")
);
@ -482,8 +442,8 @@ CREATE TABLE "groups" (
"id" serial NOT NULL,
"hash" text NOT NULL DEFAULT '',
"uid" bigint NOT NULL,
"visible" numeric(1) NOT NULL DEFAULT 0 ,
"deleted" numeric(1) NOT NULL DEFAULT 0 ,
"visible" numeric(1) NOT NULL DEFAULT '0',
"deleted" numeric(1) NOT NULL DEFAULT '0',
"gname" text NOT NULL,
PRIMARY KEY ("id")
@ -498,8 +458,8 @@ CREATE TABLE "hook" (
"hook" text NOT NULL,
"file" text NOT NULL,
"fn" text NOT NULL,
"priority" smallint NOT NULL DEFAULT 0 ,
"hook_version" smallint NOT NULL DEFAULT 0 ,
"priority" smallint NOT NULL DEFAULT '0',
"hook_version" smallint NOT NULL DEFAULT '0',
PRIMARY KEY ("id")
);
@ -514,8 +474,8 @@ CREATE TABLE "hubloc" (
"hubloc_hash" text NOT NULL,
"hubloc_addr" text NOT NULL DEFAULT '',
"hubloc_network" text NOT NULL DEFAULT '',
"hubloc_flags" bigint NOT NULL DEFAULT 0 ,
"hubloc_status" bigint NOT NULL DEFAULT 0 ,
"hubloc_flags" bigint NOT NULL DEFAULT '0',
"hubloc_status" bigint NOT NULL DEFAULT '0',
"hubloc_url" text NOT NULL DEFAULT '',
"hubloc_url_sig" text NOT NULL DEFAULT '',
"hubloc_host" text NOT NULL DEFAULT '',
@ -524,10 +484,10 @@ CREATE TABLE "hubloc" (
"hubloc_sitekey" text NOT NULL DEFAULT '',
"hubloc_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"hubloc_connected" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"hubloc_primary" smallint NOT NULL DEFAULT 0 ,
"hubloc_orphancheck" smallint NOT NULL DEFAULT 0 ,
"hubloc_error" smallint NOT NULL DEFAULT 0 ,
"hubloc_deleted" smallint NOT NULL DEFAULT 0 ,
"hubloc_primary" smallint NOT NULL DEFAULT '0',
"hubloc_orphancheck" smallint NOT NULL DEFAULT '0',
"hubloc_error" smallint NOT NULL DEFAULT '0',
"hubloc_deleted" smallint NOT NULL DEFAULT '0',
PRIMARY KEY ("hubloc_id")
);
create index "hubloc_url" on hubloc ("hubloc_url");
@ -546,11 +506,11 @@ create index "hubloc_error" on hubloc ("hubloc_error");
create index "hubloc_deleted" on hubloc ("hubloc_deleted");
CREATE TABLE "iconfig" (
"id" serial NOT NULL,
"iid" bigint NOT NULL DEFAULT 0 ,
"iid" bigint NOT NULL DEFAULT '0',
"cat" text NOT NULL DEFAULT '',
"k" text NOT NULL DEFAULT '',
"v" text NOT NULL DEFAULT '',
"sharing" int NOT NULL DEFAULT 0 ,
"sharing" int NOT NULL DEFAULT '0',
PRIMARY KEY("id")
);
create index "iconfig_iid" on iconfig ("iid");
@ -577,9 +537,9 @@ create index "issue_component" on issue ("issue_component");
CREATE TABLE "item" (
"id" serial NOT NULL,
"mid" text NOT NULL DEFAULT '',
"aid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT 0 ,
"parent" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL DEFAULT '0',
"parent" bigint NOT NULL DEFAULT '0',
"parent_mid" text NOT NULL DEFAULT '',
"thr_parent" text NOT NULL DEFAULT '',
"created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
@ -598,7 +558,7 @@ CREATE TABLE "item" (
"html" text NOT NULL,
"app" text NOT NULL DEFAULT '',
"lang" varchar(64) NOT NULL DEFAULT '',
"revision" bigint NOT NULL DEFAULT 0 ,
"revision" bigint NOT NULL DEFAULT '0',
"verb" text NOT NULL DEFAULT '',
"obj_type" text NOT NULL DEFAULT '',
"obj" text NOT NULL,
@ -613,7 +573,6 @@ CREATE TABLE "item" (
"resource_type" varchar(16) NOT NULL DEFAULT '',
"attach" text NOT NULL,
"sig" text NOT NULL DEFAULT '',
"diaspora_meta" text NOT NULL DEFAULT '',
"location" text NOT NULL DEFAULT '',
"coord" text NOT NULL DEFAULT '',
"public_policy" text NOT NULL DEFAULT '',
@ -622,32 +581,32 @@ CREATE TABLE "item" (
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
"deny_gid" text NOT NULL,
"item_restrict" bigint NOT NULL DEFAULT 0 ,
"item_flags" bigint NOT NULL DEFAULT 0 ,
"item_private" numeric(4) NOT NULL DEFAULT 0 ,
"item_unseen" smallint NOT NULL DEFAULT 0 ,
"item_wall" smallint NOT NULL DEFAULT 0 ,
"item_origin" smallint NOT NULL DEFAULT 0 ,
"item_starred" smallint NOT NULL DEFAULT 0 ,
"item_uplink" smallint NOT NULL DEFAULT 0 ,
"item_consensus" smallint NOT NULL DEFAULT 0 ,
"item_thread_top" smallint NOT NULL DEFAULT 0 ,
"item_notshown" smallint NOT NULL DEFAULT 0 ,
"item_nsfw" smallint NOT NULL DEFAULT 0 ,
"item_relay" smallint NOT NULL DEFAULT 0 ,
"item_mentionsme" smallint NOT NULL DEFAULT 0 ,
"item_nocomment" smallint NOT NULL DEFAULT 0 ,
"item_obscured" smallint NOT NULL DEFAULT 0 ,
"item_verified" smallint NOT NULL DEFAULT 0 ,
"item_retained" smallint NOT NULL DEFAULT 0 ,
"item_rss" smallint NOT NULL DEFAULT 0 ,
"item_deleted" smallint NOT NULL DEFAULT 0 ,
"item_type" int NOT NULL DEFAULT 0 ,
"item_hidden" smallint NOT NULL DEFAULT 0 ,
"item_unpublished" smallint NOT NULL DEFAULT 0 ,
"item_delayed" smallint NOT NULL DEFAULT 0 ,
"item_pending_remove" smallint NOT NULL DEFAULT 0 ,
"item_blocked" smallint NOT NULL DEFAULT 0 ,
"item_restrict" bigint NOT NULL DEFAULT '0',
"item_flags" bigint NOT NULL DEFAULT '0',
"item_private" numeric(4) NOT NULL DEFAULT '0',
"item_unseen" smallint NOT NULL DEFAULT '0',
"item_wall" smallint NOT NULL DEFAULT '0',
"item_origin" smallint NOT NULL DEFAULT '0',
"item_starred" smallint NOT NULL DEFAULT '0',
"item_uplink" smallint NOT NULL DEFAULT '0',
"item_consensus" smallint NOT NULL DEFAULT '0',
"item_thread_top" smallint NOT NULL DEFAULT '0',
"item_notshown" smallint NOT NULL DEFAULT '0',
"item_nsfw" smallint NOT NULL DEFAULT '0',
"item_relay" smallint NOT NULL DEFAULT '0',
"item_mentionsme" smallint NOT NULL DEFAULT '0',
"item_nocomment" smallint NOT NULL DEFAULT '0',
"item_obscured" smallint NOT NULL DEFAULT '0',
"item_verified" smallint NOT NULL DEFAULT '0',
"item_retained" smallint NOT NULL DEFAULT '0',
"item_rss" smallint NOT NULL DEFAULT '0',
"item_deleted" smallint NOT NULL DEFAULT '0',
"item_type" int NOT NULL DEFAULT '0',
"item_hidden" smallint NOT NULL DEFAULT '0',
"item_unpublished" smallint NOT NULL DEFAULT '0',
"item_delayed" smallint NOT NULL DEFAULT '0',
"item_pending_remove" smallint NOT NULL DEFAULT '0',
"item_blocked" smallint NOT NULL DEFAULT '0',
"item_search_vector" tsvector,
PRIMARY KEY ("id")
);
@ -725,10 +684,10 @@ create index "itemid_service" on item_id ("service");
create index "itemid_iid" on item_id ("iid");
CREATE TABLE "likes" (
"id" serial NOT NULL,
"channel_id" bigint NOT NULL DEFAULT 0 ,
"channel_id" bigint NOT NULL DEFAULT '0',
"liker" varchar(128) NOT NULL DEFAULT '',
"likee" varchar(128) NOT NULL DEFAULT '',
"iid" bigint NOT NULL DEFAULT 0 ,
"iid" bigint NOT NULL DEFAULT '0',
"i_mid" varchar(255) NOT NULL DEFAULT '',
"verb" text NOT NULL DEFAULT '',
"target_type" text NOT NULL DEFAULT '',
@ -746,27 +705,27 @@ create index "likes_target_type" on likes ("target_type");
create index "likes_target_id" on likes ("target_id");
CREATE TABLE "mail" (
"id" serial NOT NULL,
"convid" bigint NOT NULL DEFAULT 0 ,
"convid" bigint NOT NULL DEFAULT '0',
"conv_guid" text NOT NULL,
"mail_flags" bigint NOT NULL DEFAULT 0 ,
"mail_flags" bigint NOT NULL DEFAULT '0',
"from_xchan" text NOT NULL DEFAULT '',
"to_xchan" text NOT NULL DEFAULT '',
"account_id" bigint NOT NULL DEFAULT 0 ,
"channel_id" bigint NOT NULL DEFAULT 0 ,
"mail_mimetype" varchar(64) NOT NULL DEFAULT 'text/bbcode',
"account_id" bigint NOT NULL DEFAULT '0',
"channel_id" bigint NOT NULL DEFAULT '0',
"mail_mimetype" varchar(64) NOT NULL DEFAULT '0',
"title" text NOT NULL,
"body" text NOT NULL,
"sig" text NOT NULL,
"attach" text NOT NULL DEFAULT '',
"mid" text NOT NULL,
"parent_mid" text NOT NULL,
"mail_deleted" smallint NOT NULL DEFAULT 0 ,
"mail_replied" smallint NOT NULL DEFAULT 0 ,
"mail_isreply" smallint NOT NULL DEFAULT 0 ,
"mail_seen" smallint NOT NULL DEFAULT 0 ,
"mail_recalled" smallint NOT NULL DEFAULT 0 ,
"mail_obscured" smallint NOT NULL DEFAULT 0 ,
"mail_raw" smallint NOT NULL DEFAULT 0 ,
"mail_deleted" smallint NOT NULL DEFAULT '0',
"mail_replied" smallint NOT NULL DEFAULT '0',
"mail_isreply" smallint NOT NULL DEFAULT '0',
"mail_seen" smallint NOT NULL DEFAULT '0',
"mail_recalled" smallint NOT NULL DEFAULT '0',
"mail_obscured" smallint NOT NULL DEFAULT '0',
"mail_raw" smallint NOT NULL DEFAULT '0',
"created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY ("id")
@ -790,10 +749,10 @@ create index "mail_recalled" on mail ("mail_recalled");
create index "mail_obscured" on mail ("mail_obscured");
CREATE TABLE "menu" (
"menu_id" serial NOT NULL,
"menu_channel_id" bigint NOT NULL DEFAULT 0 ,
"menu_channel_id" bigint NOT NULL DEFAULT '0',
"menu_name" text NOT NULL DEFAULT '',
"menu_desc" text NOT NULL DEFAULT '',
"menu_flags" bigint NOT NULL DEFAULT 0 ,
"menu_flags" bigint NOT NULL DEFAULT '0',
"menu_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"menu_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY ("menu_id")
@ -807,14 +766,14 @@ CREATE TABLE "menu_item" (
"mitem_id" serial NOT NULL,
"mitem_link" text NOT NULL DEFAULT '',
"mitem_desc" text NOT NULL DEFAULT '',
"mitem_flags" bigint NOT NULL DEFAULT 0 ,
"mitem_flags" bigint NOT NULL DEFAULT '0',
"allow_cid" text NOT NULL,
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
"deny_gid" text NOT NULL,
"mitem_channel_id" bigint NOT NULL,
"mitem_menu_id" bigint NOT NULL DEFAULT 0 ,
"mitem_order" bigint NOT NULL DEFAULT 0 ,
"mitem_menu_id" bigint NOT NULL DEFAULT '0',
"mitem_order" bigint NOT NULL DEFAULT '0',
PRIMARY KEY ("mitem_id")
);
@ -833,7 +792,7 @@ CREATE TABLE "notify" (
"uid" bigint NOT NULL,
"link" text NOT NULL,
"parent" text NOT NULL DEFAULT '',
"seen" numeric(1) NOT NULL DEFAULT 0 ,
"seen" numeric(1) NOT NULL DEFAULT '0',
"ntype" bigint NOT NULL,
"verb" text NOT NULL,
"otype" varchar(16) NOT NULL,
@ -882,18 +841,18 @@ create index "obj_quantity" on obj ("obj_quantity");
CREATE TABLE "outq" (
"outq_hash" text NOT NULL,
"outq_account" bigint NOT NULL DEFAULT 0 ,
"outq_channel" bigint NOT NULL DEFAULT 0 ,
"outq_account" bigint NOT NULL DEFAULT '0',
"outq_channel" bigint NOT NULL DEFAULT '0',
"outq_driver" varchar(32) NOT NULL DEFAULT '',
"outq_posturl" text NOT NULL DEFAULT '',
"outq_async" numeric(1) NOT NULL DEFAULT 0 ,
"outq_delivered" numeric(1) NOT NULL DEFAULT 0 ,
"outq_async" numeric(1) NOT NULL DEFAULT '0',
"outq_delivered" numeric(1) NOT NULL DEFAULT '0',
"outq_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"outq_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"outq_scheduled" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"outq_notify" text NOT NULL,
"outq_msg" text NOT NULL,
"outq_priority" smallint NOT NULL DEFAULT 0 ,
"outq_priority" smallint NOT NULL DEFAULT '0',
PRIMARY KEY ("outq_hash")
);
create index "outq_account" on outq ("outq_account");
@ -908,7 +867,7 @@ create index "outq_priority" on outq ("outq_priority");
CREATE TABLE "pconfig" (
"id" serial NOT NULL,
"uid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT '0',
"cat" text NOT NULL,
"k" text NOT NULL,
"v" text NOT NULL,
@ -918,7 +877,7 @@ CREATE TABLE "pconfig" (
CREATE TABLE "photo" (
"id" serial NOT NULL,
"aid" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL,
"xchan" text NOT NULL DEFAULT '',
"resource_id" text NOT NULL,
@ -931,16 +890,16 @@ CREATE TABLE "photo" (
"mimetype" varchar(128) NOT NULL DEFAULT 'image/jpeg',
"height" numeric(6) NOT NULL,
"width" numeric(6) NOT NULL,
"filesize" bigint NOT NULL DEFAULT 0 ,
"filesize" bigint NOT NULL DEFAULT '0',
"content" bytea NOT NULL,
"imgscale" numeric(3) NOT NULL DEFAULT 0 ,
"profile" numeric(1) NOT NULL DEFAULT 0 ,
"photo_usage" smallint NOT NULL DEFAULT 0 ,
"is_nsfw" smallint NOT NULL DEFAULT 0 ,
"os_storage" smallint NOT NULL DEFAULT 0 ,
"imgscale" numeric(3) NOT NULL DEFAULT '0',
"profile" numeric(1) NOT NULL DEFAULT '0',
"photo_usage" smallint NOT NULL DEFAULT '0',
"is_nsfw" smallint NOT NULL DEFAULT '0',
"os_storage" smallint NOT NULL DEFAULT '0',
"os_path" text NOT NULL,
"display_path" text NOT NULL,
"photo_flags" bigint NOT NULL DEFAULT 0 ,
"photo_flags" bigint NOT NULL DEFAULT '0',
"allow_cid" text NOT NULL,
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
@ -963,10 +922,10 @@ create index "photo_os_storage" on photo ("os_storage");
CREATE TABLE "poll" (
"poll_id" serial NOT NULL,
"poll_channel" bigint NOT NULL DEFAULT 0 ,
"poll_channel" bigint NOT NULL DEFAULT '0',
"poll_desc" text NOT NULL,
"poll_flags" bigint NOT NULL DEFAULT 0 ,
"poll_votes" bigint NOT NULL DEFAULT 0 ,
"poll_flags" bigint NOT NULL DEFAULT '0',
"poll_votes" bigint NOT NULL DEFAULT '0',
PRIMARY KEY ("poll_id")
);
@ -975,10 +934,10 @@ create index "poll_flags" on poll ("poll_flags");
create index "poll_votes" on poll ("poll_votes");
CREATE TABLE "poll_elm" (
"pelm_id" serial NOT NULL,
"pelm_poll" bigint NOT NULL DEFAULT 0 ,
"pelm_poll" bigint NOT NULL DEFAULT '0',
"pelm_desc" text NOT NULL,
"pelm_flags" bigint NOT NULL DEFAULT 0 ,
"pelm_result" float NOT NULL DEFAULT 0 ,
"pelm_flags" bigint NOT NULL DEFAULT '0',
"pelm_result" float NOT NULL DEFAULT '0',
PRIMARY KEY ("pelm_id")
);
create index "pelm_poll" on poll_elm ("pelm_poll");
@ -996,7 +955,7 @@ CREATE TABLE "profdef" (
create index "profdef_field_name" on profdef ("field_name");
CREATE TABLE "profext" (
"id" serial NOT NULL,
"channel_id" bigint NOT NULL DEFAULT 0 ,
"channel_id" bigint NOT NULL DEFAULT '0',
"hash" text NOT NULL DEFAULT '',
"k" text NOT NULL DEFAULT '',
"v" text NOT NULL,
@ -1009,11 +968,11 @@ create index "profext_k" on profext ("k");
CREATE TABLE "profile" (
"id" serial NOT NULL,
"profile_guid" varchar(64) NOT NULL DEFAULT '',
"aid" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL,
"profile_name" text NOT NULL,
"is_default" numeric(1) NOT NULL DEFAULT 0 ,
"hide_friends" numeric(1) NOT NULL DEFAULT 0 ,
"is_default" numeric(1) NOT NULL DEFAULT '0',
"hide_friends" numeric(1) NOT NULL DEFAULT '0',
"fullname" text NOT NULL,
"pdesc" text NOT NULL DEFAULT '',
"chandesc" text NOT NULL DEFAULT '',
@ -1050,7 +1009,7 @@ CREATE TABLE "profile" (
"homepage" text NOT NULL DEFAULT '',
"photo" text NOT NULL,
"thumb" text NOT NULL,
"publish" numeric(1) NOT NULL DEFAULT 0 ,
"publish" numeric(1) NOT NULL DEFAULT '0',
"profile_vcard" text NOT NULL DEFAULT '',
PRIMARY KEY ("id"),
UNIQUE ("profile_guid","uid")
@ -1072,7 +1031,7 @@ create index "profile_guid" on profile ("profile_guid");
CREATE TABLE "profile_check" (
"id" serial NOT NULL,
"uid" bigint NOT NULL,
"cid" bigint NOT NULL DEFAULT 0 ,
"cid" bigint NOT NULL DEFAULT '0',
"dfrn_id" text NOT NULL,
"sec" text NOT NULL,
"expire" bigint NOT NULL,
@ -1107,8 +1066,8 @@ create index "session_sid" on session ("sid");
create index "session_expire" on session ("expire");
CREATE TABLE "shares" (
"share_id" serial NOT NULL,
"share_type" bigint NOT NULL DEFAULT 0 ,
"share_target" bigint NOT NULL DEFAULT 0 ,
"share_type" bigint NOT NULL DEFAULT '0',
"share_target" bigint NOT NULL DEFAULT '0',
"share_xchan" text NOT NULL DEFAULT '',
PRIMARY KEY ("share_id")
);
@ -1118,8 +1077,8 @@ create index "share_xchan" on shares ("share_xchan");
CREATE TABLE "sign" (
"id" serial NOT NULL,
"iid" bigint NOT NULL DEFAULT 0 ,
"retract_iid" bigint NOT NULL DEFAULT 0 ,
"iid" bigint NOT NULL DEFAULT '0',
"retract_iid" bigint NOT NULL DEFAULT '0',
"signed_text" text NOT NULL,
"signature" text NOT NULL,
"signer" text NOT NULL,
@ -1130,19 +1089,19 @@ create index "sign_retract_iid" on "sign" ("retract_iid");
CREATE TABLE "site" (
"site_url" text NOT NULL,
"site_access" bigint NOT NULL DEFAULT 0 ,
"site_flags" bigint NOT NULL DEFAULT 0 ,
"site_access" bigint NOT NULL DEFAULT '0',
"site_flags" bigint NOT NULL DEFAULT '0',
"site_update" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"site_pull" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"site_sync" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"site_directory" text NOT NULL DEFAULT '',
"site_register" bigint NOT NULL DEFAULT 0 ,
"site_register" bigint NOT NULL DEFAULT '0',
"site_sellpage" text NOT NULL DEFAULT '',
"site_location" text NOT NULL DEFAULT '',
"site_realm" text NOT NULL DEFAULT '',
"site_valid" smallint NOT NULL DEFAULT 0 ,
"site_dead" smallint NOT NULL DEFAULT 0 ,
"site_type" smallint NOT NULL DEFAULT 0 ,
"site_valid" smallint NOT NULL DEFAULT '0',
"site_dead" smallint NOT NULL DEFAULT '0',
"site_type" smallint NOT NULL DEFAULT '0',
"site_project" text NOT NULL DEFAULT '',
"site_version" text NOT NULL DEFAULT '',
"site_crypto" text NOT NULL DEFAULT '',
@ -1162,7 +1121,7 @@ create index "site_project" on site ("site_project");
CREATE TABLE "source" (
"src_id" serial NOT NULL,
"src_channel_id" bigint NOT NULL DEFAULT 0 ,
"src_channel_id" bigint NOT NULL DEFAULT '0',
"src_channel_xchan" text NOT NULL DEFAULT '',
"src_xchan" text NOT NULL DEFAULT '',
"src_patt" text NOT NULL DEFAULT '',
@ -1182,8 +1141,8 @@ CREATE TABLE "sys_perms" (
);
CREATE TABLE "term" (
"tid" serial NOT NULL,
"aid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT 0 ,
"aid" bigint NOT NULL DEFAULT '0',
"uid" bigint NOT NULL DEFAULT '0',
"oid" bigint NOT NULL,
"otype" numeric(3) NOT NULL,
"ttype" numeric(3) NOT NULL,
@ -1222,7 +1181,7 @@ CREATE TABLE "updates" (
"ud_guid" text NOT NULL DEFAULT '',
"ud_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"ud_last" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"ud_flags" bigint NOT NULL DEFAULT 0 ,
"ud_flags" bigint NOT NULL DEFAULT '0',
"ud_addr" text NOT NULL DEFAULT '',
PRIMARY KEY ("ud_id")
);
@ -1234,7 +1193,7 @@ create index "ud_addr" on updates ("ud_addr");
create index "ud_last" on updates ("ud_last");
CREATE TABLE "verify" (
"id" serial NOT NULL,
"channel" bigint NOT NULL DEFAULT 0 ,
"channel" bigint NOT NULL DEFAULT '0',
"vtype" varchar(32) NOT NULL DEFAULT '',
"token" text NOT NULL DEFAULT '',
"meta" text NOT NULL DEFAULT '',
@ -1248,8 +1207,8 @@ create index "verify_meta" on verify ("meta");
create index "verify_created" on verify ("created");
CREATE TABLE "vote" (
"vote_id" serial NOT NULL,
"vote_poll" bigint NOT NULL DEFAULT 0 ,
"vote_element" bigint NOT NULL DEFAULT 0 ,
"vote_poll" bigint NOT NULL DEFAULT '0',
"vote_element" bigint NOT NULL DEFAULT '0',
"vote_result" text NOT NULL,
"vote_xchan" text NOT NULL DEFAULT '',
PRIMARY KEY ("vote_id"),
@ -1274,16 +1233,16 @@ CREATE TABLE "xchan" (
"xchan_name" text NOT NULL DEFAULT '',
"xchan_network" text NOT NULL DEFAULT '',
"xchan_instance_url" text NOT NULL DEFAULT '',
"xchan_flags" bigint NOT NULL DEFAULT 0 ,
"xchan_flags" bigint NOT NULL DEFAULT '0',
"xchan_photo_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"xchan_name_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"xchan_hidden" smallint NOT NULL DEFAULT 0 ,
"xchan_orphan" smallint NOT NULL DEFAULT 0 ,
"xchan_censored" smallint NOT NULL DEFAULT 0 ,
"xchan_selfcensored" smallint NOT NULL DEFAULT 0 ,
"xchan_system" smallint NOT NULL DEFAULT 0 ,
"xchan_pubforum" smallint NOT NULL DEFAULT 0 ,
"xchan_deleted" smallint NOT NULL DEFAULT 0 ,
"xchan_hidden" smallint NOT NULL DEFAULT '0',
"xchan_orphan" smallint NOT NULL DEFAULT '0',
"xchan_censored" smallint NOT NULL DEFAULT '0',
"xchan_selfcensored" smallint NOT NULL DEFAULT '0',
"xchan_system" smallint NOT NULL DEFAULT '0',
"xchan_pubforum" smallint NOT NULL DEFAULT '0',
"xchan_deleted" smallint NOT NULL DEFAULT '0',
PRIMARY KEY ("xchan_hash")
);
create index "xchan_guid" on xchan ("xchan_guid");
@ -1328,7 +1287,7 @@ create index "xconfig_cat" on xconfig ("cat");
create index "xconfig_k" on xconfig ("k");
CREATE TABLE "xign" (
"id" serial NOT NULL,
"uid" bigint NOT NULL DEFAULT 0 ,
"uid" bigint NOT NULL DEFAULT '0',
"xchan" text NOT NULL DEFAULT '',
PRIMARY KEY ("id")
);
@ -1338,10 +1297,10 @@ CREATE TABLE "xlink" (
"xlink_id" serial NOT NULL,
"xlink_xchan" text NOT NULL DEFAULT '',
"xlink_link" text NOT NULL DEFAULT '',
"xlink_rating" bigint NOT NULL DEFAULT 0 ,
"xlink_rating" bigint NOT NULL DEFAULT '0',
"xlink_rating_text" TEXT NOT NULL DEFAULT '',
"xlink_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"xlink_static" numeric(1) NOT NULL DEFAULT 0 ,
"xlink_static" numeric(1) NOT NULL DEFAULT '0',
"xlink_sig" text NOT NULL DEFAULT '',
PRIMARY KEY ("xlink_id")
);
@ -1353,7 +1312,7 @@ create index "xlink_static" on xlink ("xlink_static");
CREATE TABLE "xperm" (
"xp_id" serial NOT NULL,
"xp_client" varchar( 20 ) NOT NULL DEFAULT '',
"xp_channel" bigint NOT NULL DEFAULT 0 ,
"xp_channel" bigint NOT NULL DEFAULT '0',
"xp_perm" varchar( 64 ) NOT NULL DEFAULT '',
PRIMARY KEY ("xp_id")
);
@ -1362,7 +1321,7 @@ create index "xp_channel" on xperm ("xp_channel");
create index "xp_perm" on xperm ("xp_perm");
CREATE TABLE "xprof" (
"xprof_hash" text NOT NULL,
"xprof_age" numeric(3) NOT NULL DEFAULT 0 ,
"xprof_age" numeric(3) NOT NULL DEFAULT '0',
"xprof_desc" text NOT NULL DEFAULT '',
"xprof_dob" varchar(12) NOT NULL DEFAULT '',
"xprof_gender" text NOT NULL DEFAULT '',
@ -1393,7 +1352,7 @@ CREATE TABLE "xtag" (
"xtag_id" serial NOT NULL,
"xtag_hash" text NOT NULL,
"xtag_term" text NOT NULL DEFAULT '',
"xtag_flags" bigint NOT NULL DEFAULT 0 ,
"xtag_flags" bigint NOT NULL DEFAULT '0',
PRIMARY KEY ("xtag_id")
);
create index "xtag_term" on xtag ("xtag_term");

View File

@ -1,3 +0,0 @@
.DS_Store
*.pyc
node_modules

View File

@ -1,81 +0,0 @@
{
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : true, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"immed" : true, // true: Require immediate invocations to be wrapped in parens
// e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : true, // true: Require variables/functions to be defined before being used
"newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : "single", // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // true: Require all defined variables be used
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
"trailing" : true, // true: Prohibit trailing whitespaces
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : false, // {int} Max number of characters per line
// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : false, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements"
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function
// Environments
"browser" : false, // Web Browser (window, document, etc)
"couch" : false, // CouchDB
"devel" : false, // Development/debugging (alert, confirm, etc)
"dojo" : false, // Dojo Toolkit
"jquery" : false, // jQuery
"mootools" : false, // MooTools
"node" : false, // Node.js
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
"prototypejs" : false, // Prototype and Scriptaculous
"rhino" : false, // Rhino
"worker" : false, // Web Workers
"wsh" : false, // Windows Scripting Host
"yui" : false, // Yahoo User Interface
// Legacy
"nomen" : true, // true: Prohibit dangling `_` in variables
"onevar" : true, // true: Allow only one `var` statement per function
"passfail" : false, // true: Stop on first error
"white" : true, // true: Check against strict whitespace and indentation rules
// Custom Globals
"globals" : {} // additional predefined global variables
}

Some files were not shown because too many files have changed in this diff Show More