Merge branch 2.2RC

This commit is contained in:
Mario Vavti
2017-03-08 09:39:46 +01:00
868 changed files with 164621 additions and 46416 deletions
-148
View File
@@ -1,148 +0,0 @@
<?php
require_once('include/bb2diaspora.php');
require_once('include/group.php');
require_once('include/follow.php');
require_once('include/photo/photo_driver.php');
function import_diaspora($data) {
$account = App::get_account();
if(! $account)
return false;
$address = escape_tags($data['user']['username']);
if(! $address) {
notice( t('No username found in import file.') . EOL);
return false;
}
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($address)
);
if($r) {
// try at most ten times to generate a unique address.
$x = 0;
$found_unique = false;
do {
$tmp = $address . mt_rand(1000,9999);
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($tmp)
);
if(! $r) {
$address = $tmp;
$found_unique = true;
break;
}
$x ++;
} while ($x < 10);
if(! $found_unique) {
logger('import_diaspora: duplicate channel address. randomisation failed.');
notice( t('Unable to create a unique channel address. Import failed.') . EOL);
return;
}
}
$c = create_identity(array(
'name' => escape_tags($data['user']['name']),
'nickname' => $address,
'account_id' => $account['account_id'],
'permissions_role' => 'social'
));
if(! $c['success'])
return;
$channel_id = $c['channel']['channel_id'];
// Hubzilla only: Turn on the Diaspora protocol so that follow requests will be sent.
set_pconfig($channel_id,'system','diaspora_allowed','1');
// todo - add auto follow settings, (and strip exif in hubzilla)
$location = escape_tags($data['user']['profile']['location']);
if(! $location)
$location = '';
q("update channel set channel_location = '%s' where channel_id = %d",
dbesc($location),
intval($channel_id)
);
if($data['user']['profile']['nsfw']) {
q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d",
intval(PAGE_ADULT),
intval($channel_id)
);
}
if($data['user']['profile']['image_url']) {
$p = z_fetch_url($data['user']['profile']['image_url'],true);
if($p['success']) {
$rawbytes = $p['body'];
$type = guess_image_type('dummyfile',$p['header']);
import_channel_photo($rawbytes,$type,$c['channel']['channel_account_id'],$channel_id);
}
}
$gender = escape_tags($data['user']['profile']['gender']);
$about = markdown_to_bb($data['user']['profile']['bio']);
$publish = intval($data['user']['profile']['searchable']);
if($data['user']['profile']['birthday'])
$dob = datetime_convert('UTC','UTC',$data['user']['profile']['birthday'],'Y-m-d');
else
$dob = '0000-00-00';
// we're relying on the fact that this channel was just created and will only
// have the default profile currently
$r = q("update profile set gender = '%s', about = '%s', dob = '%s', publish = %d where uid = %d",
dbesc($gender),
dbesc($about),
dbesc($dob),
dbesc($publish),
intval($channel_id)
);
if($data['user']['aspects']) {
foreach($data['user']['aspects'] as $aspect) {
group_add($channel_id,escape_tags($aspect['name']),intval($aspect['contacts_visible']));
}
}
// now add connections and send friend requests
if($data['user']['contacts']) {
foreach($data['user']['contacts'] as $contact) {
$result = new_contact($channel_id, $contact['person_diaspora_handle'], $c['channel']);
if($result['success']) {
if($contact['aspects']) {
foreach($contact['aspects'] as $aspect) {
group_add_member($channel_id,$aspect['name'],$result['abook']['xchan_hash']);
}
}
}
}
}
// Then add items - note this can't be done until Diaspora adds guids to exported
// items and comments
// This will indirectly perform a refresh_all *and* update the directory
proc_run('php', 'include/directory.php', $channel_id);
notice( t('Import completed.') . EOL);
change_channel($channel_id);
goaway(z_root() . '/network' );
}
-1
View File
@@ -1,7 +1,6 @@
<?php
require_once('include/html2bbcode.php');
require_once('include/hubloc.php');
// Sample module for importing conversation data from Reflection CMS. Some preparation was used to
// dump relevant posts, categories and comments into individual JSON files, and also JSON dump of
+10
View File
@@ -174,6 +174,16 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
$custom = false;
}
$r = q("SELECT id, profile_guid, profile_name from profile where is_default = 0 and uid = %d order by profile_name",
intval(local_channel())
);
if($r) {
foreach($r as $rv) {
$selected = (($single_group && 'vp.' . $rr['hash'] === $allow_gid[0]) ? ' selected = "selected" ' : '');
$groups .= '<option id="' . 'vp' . $rv['id'] . '" value="' . 'vp.' . $rv['profile_guid'] . '"' . $selected . '>' . t('Profile','acl') . ' ' . $rv['profile_name'] . '</option>' . "\r\n";
}
}
$r = q("SELECT id, hash, gname FROM groups WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval(local_channel())
);
+1 -1
View File
@@ -27,7 +27,7 @@ function profile_activity($changed, $value) {
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = ACTIVITY_OBJ_PROFILE;
$arr['plink'] = z_root() . '/channel/' . $self['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['plink'] = z_root() . '/channel/' . $self['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$A = '[url=' . z_root() . '/channel/' . $self['channel_address'] . ']' . $self['channel_name'] . '[/url]';
+9 -5
View File
@@ -69,8 +69,13 @@
logger('api_export_basic: no user');
return false;
}
json_return_and_die(identity_basic_export(api_user(),(($_REQUEST['posts']) ? intval($_REQUEST['posts']) : 0 )));
$sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
if($_REQUEST['posts']) {
$sections = get_default_export_sections();
$sections[] = 'items';
}
json_return_and_die(identity_basic_export(api_user(),$sections));
}
@@ -350,10 +355,9 @@
if(api_user() === false)
return false;
logger('api_xchan');
require_once('include/hubloc.php');
if($_SERVER['REQUEST_METHOD'] === 'POST') {
// $r = xchan_store($_REQUEST);
if($_SERVER['REQUEST_METHOD'] === 'POST') {
$r = xchan_store($_REQUEST);
}
$r = xchan_fetch($_REQUEST);
json_return_and_die($r);
+78 -49
View File
@@ -28,29 +28,31 @@ function z_mime_content_type($filename) {
$mime_types = array(
'txt' => 'text/plain',
'htm' => 'text/html',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'php' => 'text/html',
'css' => 'text/css',
'md' => 'text/markdown',
'bb' => 'text/bbcode',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
'epub' => 'application/epub+zip',
// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// archives
@@ -61,27 +63,27 @@ function z_mime_content_type($filename) {
'cab' => 'application/vnd.ms-cab-compressed',
// audio/video
'mp3' => 'audio/mpeg',
'wav' => 'audio/wav',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'mp3' => 'audio/mpeg',
'wav' => 'audio/wav',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'ogg' => 'audio/ogg',
'ogv' => 'video/ogg',
'ogx' => 'application/ogg',
'flac' => 'audio/flac',
'opus' => 'audio/ogg',
'webm' => 'video/webm',
// 'webm' => 'audio/webm',
'mp4' => 'video/mp4',
// 'mp4' => 'audio/mp4',
'mkv' => 'video/x-matroska',
'mp4' => 'video/mp4',
// 'mp4' => 'audio/mp4',
'mkv' => 'video/x-matroska',
// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'ps' => 'application/postscript',
// ms office
'doc' => 'application/msword',
@@ -1279,8 +1281,10 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
intval($channel_id)
);
if(! $r)
if(! $r) {
attach_drop_photo($channel_id,$resource);
return;
}
$cloudpath = get_parent_cloudpath($channel_id, $channel_address, $resource);
$object = get_file_activity_object($channel_id, $resource, $cloudpath);
@@ -1326,19 +1330,10 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
);
if($r[0]['is_photo']) {
$x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d",
dbesc($resource),
intval($channel_id)
);
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
}
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)
);
attach_drop_photo($channel_id,$resource);
}
// update the parent folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
dbesc(datetime_convert()),
@@ -1351,6 +1346,24 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
return;
}
function attach_drop_photo($channel_id,$resource) {
$x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d",
dbesc($resource),
intval($channel_id)
);
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
}
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)
);
}
/**
* @brief Returns path to file in cloud/.
*
@@ -1464,18 +1477,34 @@ function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = fa
function find_folder_hash_by_path($channel_id, $path) {
$filename = end(explode('/', $path));
if(! $path)
return '';
$r = q("SELECT hash FROM attach WHERE uid = %d AND filename = '%s' LIMIT 1",
intval($channel_id),
dbesc($filename)
);
$comps = explode('/',$path);
$errors = false;
$parent_hash = '';
$hash = '';
if($r && $r[0]['hash']) {
$hash = $r[0]['hash'];
for($x = 0; $x < count($comps); $x ++) {
$element = $comps[$x];
$r = q("SELECT hash FROM attach WHERE uid = %d AND filename = '%s' AND folder = '%s' LIMIT 1",
intval($channel_id),
dbesc($element),
dbesc($parent_hash)
);
if($r) {
$parent_hash = $r[0]['hash'];
}
else {
$errors ++;
break;
}
}
return $hash;
if($errors)
return '';
return $parent_hash;
}
/**
+1 -1
View File
@@ -300,7 +300,7 @@ else {
// (i.e. expire when the browser is closed), even when there's a time expiration
// on the cookie
if($_POST['remember_me']) {
if(($_POST['remember_me']) || ($_POST['remember'])) {
$_SESSION['remember_me'] = 1;
App::$session->new_cookie(31449600); // one year
}
+86 -8
View File
@@ -7,7 +7,7 @@
require_once('include/oembed.php');
require_once('include/event.php');
require_once('include/zot.php');
require_once('include/hubloc.php');
function tryoembed($match) {
$url = ((count($match) == 2) ? $match[1] : $match[2]);
@@ -473,11 +473,40 @@ function bb_sanitize_style($input) {
return '<span style="' . $css_string_san . '">' . $input[2] . '</span>';
}
function oblanguage_callback($matches) {
if(strlen($matches[1]) == 2) {
$compare = strtolower(substr(\App::$language,0,2));
}
else {
$compare = strtolower(\App::$language);
}
if($compare === strtolower($matches[1]))
return $matches[2];
return '';
}
function oblanguage_necallback($matches) {
if(strlen($matches[1]) == 2) {
$compare = strtolower(substr(\App::$language,0,2));
}
else {
$compare = strtolower(\App::$language);
}
if($compare !== strtolower($matches[1]))
return $matches[2];
return '';
}
function bb_observer($Text) {
$observer = App::get_observer();
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
if ($observer) {
$Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
$Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
@@ -511,6 +540,20 @@ function bb_code($match) {
return '<code class="inline-code">' . trim($match[1]) . '</code>';
}
function bb_code_options($match) {
if(strpos($match[0], "<br />")) {
$class = "";
} else {
$class = "inline-code";
}
if(strpos($match[1], 'nowrap')) {
$style = "overflow-x: auto; white-space: pre;";
} else {
$style = "";
}
return '<code class="'. $class .'" style="'. $style .'">' . trim($match[2]) . '</code>';
}
function bb_highlight($match) {
$lang = ((in_array(strtolower($match[1]),['php','css','mysql','sql','abap','diff','html','perl','ruby',
'vbscript','avrc','dtd','java','xml','cpp','python','javascript','js','json','sh']))
@@ -530,13 +573,28 @@ function bb_fixtable_lf($match) {
}
function parseIdentityAwareHTML($Text) {
// Hide all [noparse] contained bbtags by spacefying them
if (strpos($Text,'[noparse]') !== false) {
$Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
}
if (strpos($Text,'[nobb]') !== false) {
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_spacefy',$Text);
}
if (strpos($Text,'[pre]') !== false) {
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text);
}
// process [observer] tags before we do anything else because we might
// be stripping away stuff that then doesn't need to be worked on anymore
$observer = App::get_observer();
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
$Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text);
$Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text);
if ($observer) {
$Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
$Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
@@ -568,9 +626,21 @@ function parseIdentityAwareHTML($Text) {
$Text = str_replace('[observer.photo]','', $Text);
}
$Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text);
$Text = str_replace(array('[baseurl]','[sitename]'),array(z_root(),get_config('system','sitename')),$Text);
return $Text;
// Unhide all [noparse] contained bbtags unspacefying them
// and triming the [noparse] tag.
if (strpos($Text,'[noparse]') !== false) {
$Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_unspacefy_and_trim', $Text);
}
if (strpos($Text,'[nobb]') !== false) {
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim', $Text);
}
if (strpos($Text,'[pre]') !== false) {
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text);
}
return $Text;
}
// BBcode 2 HTML was written by WAY2WEB.net
@@ -607,6 +677,9 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$observer = App::get_observer();
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
$Text = preg_replace_callback("/\[observer\.language\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_callback', $Text);
$Text = preg_replace_callback("/\[observer\.language\!\=(.*?)\](.*?)\[\/observer\]/ism",'oblanguage_necallback', $Text);
if ($observer) {
$Text = preg_replace("/\[observer\=1\](.*?)\[\/observer\]/ism", '$1', $Text);
$Text = preg_replace("/\[observer\=0\].*?\[\/observer\]/ism", '', $Text);
@@ -891,8 +964,8 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
}
if (strpos($Text,'[/table]') !== false) {
$Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>', $Text);
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>', $Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>', $Text);
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table class="table table-responsive table-bordered" >$1</table>', $Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table class="table table-responsive" >$1</table>', $Text);
}
$Text = str_replace('</tr><br /><tr>', "</tr>\n<tr>", $Text);
$Text = str_replace('[hr]', '<hr />', $Text);
@@ -911,6 +984,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism", 'bb_code', $Text);
}
// Check for [code options] text
if (strpos($Text,'[code ') !== false) {
$Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text);
}
// Check for [spoiler] text
$endlessloop = 0;
while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
@@ -1127,9 +1205,9 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text);
// This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where
// the scheme begins with z (zhttp), h (http(s)), f (ftp), m (mailto), and named anchors.
// the scheme begins with z (zhttp), h (http(s)), f (ftp(s)), m (mailto), t (tel) and named anchors.
$Text = preg_replace("/\<(.*?)(src|href)=\"[^zhfm#](.*?)\>/ism", '<$1$2="">', $Text);
$Text = preg_replace("/\<(.*?)(src|href)=\"[^zhfmt#](.*?)\>/ism", '<$1$2="">', $Text);
$Text = bb_replace_images($Text, $saved_images);
-1
View File
@@ -23,7 +23,6 @@ function bookmark_add($channel,$sender,$taxonomy,$private,$opts = null) {
$iarr['mitem_desc'] = $taxonomy['term'];
$iarr['mitem_flags'] = (($ischat) ? MENU_ITEM_CHATROOM : 0);
require_once('include/hubloc.php');
$zrl = is_matrix_url($taxonomy['url']);
if($zrl)
+398 -232
View File
@@ -291,59 +291,63 @@ function create_identity($arr) {
// Create a verified hub location pointing to this site.
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($guid),
dbesc($sig),
dbesc($hash),
dbesc(channel_reddress($ret['channel'])),
intval($primary),
dbesc(z_root()),
dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))),
dbesc(App::get_hostname()),
dbesc(z_root() . '/post'),
dbesc(get_config('system','pubkey')),
dbesc('zot')
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $guid,
'hubloc_guid_sig' => $sig,
'hubloc_hash' => $hash,
'hubloc_addr' => channel_reddress($ret['channel']),
'hubloc_primary' => $primary,
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey'])),
'hubloc_host' => App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_network' => 'zot',
'hubloc_updated' => datetime_convert()
]
);
if(! $r)
logger('create_identity: Unable to store hub location');
$newuid = $ret['channel']['channel_id'];
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_system ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
dbesc($hash),
dbesc($guid),
dbesc($sig),
dbesc($key['pubkey']),
dbesc(z_root() . "/photo/profile/l/{$newuid}"),
dbesc(z_root() . "/photo/profile/m/{$newuid}"),
dbesc(z_root() . "/photo/profile/s/{$newuid}"),
dbesc(channel_reddress($ret['channel'])),
dbesc(z_root() . '/channel/' . $ret['channel']['channel_address']),
dbesc(z_root() . '/follow?f=&url=%s'),
dbesc(z_root() . '/poco/' . $ret['channel']['channel_address']),
dbesc($ret['channel']['channel_name']),
dbesc('zot'),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($system)
$r = xchan_store_lowlevel(
[
'xchan_hash' => $hash,
'xchan_guid' => $guid,
'xchan_guid_sig' => $sig,
'xchan_pubkey' => $key['pubkey'],
'xchan_photo_l' => z_root() . "/photo/profile/l/{$newuid}",
'xchan_photo_m' => z_root() . "/photo/profile/m/{$newuid}",
'xchan_photo_s' => z_root() . "/photo/profile/s/{$newuid}",
'xchan_addr' => channel_reddress($ret['channel']),
'xchan_url' => z_root() . '/channel/' . $ret['channel']['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_connurl' => z_root() . '/poco/' . $ret['channel']['channel_address'],
'xchan_name' => $ret['channel']['channel_name'],
'xchan_network' => 'zot',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert(),
'xchan_system' => $system
]
);
// Not checking return value.
// It's ok for this to fail if it's an imported channel, and therefore the hash is a duplicate
$r = q("INSERT INTO profile ( aid, uid, profile_guid, profile_name, is_default, publish, fullname, photo, thumb)
VALUES ( %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s') ",
intval($ret['channel']['channel_account_id']),
intval($newuid),
dbesc(random_string()),
t('Default Profile'),
1,
$publish,
dbesc($ret['channel']['channel_name']),
dbesc(z_root() . "/photo/profile/l/{$newuid}"),
dbesc(z_root() . "/photo/profile/m/{$newuid}")
$r = profile_store_lowlevel(
[
'aid' => intval($ret['channel']['channel_account_id']),
'uid' => intval($newuid),
'profile_guid' => random_string(),
'profile_name' => t('Default Profile'),
'is_default' => 1,
'publish' => $publish,
'fullname' => $ret['channel']['channel_name'],
'photo' => z_root() . "/photo/profile/l/{$newuid}",
'thumb' => z_root() . "/photo/profile/m/{$newuid}"
]
);
if($role_permissions) {
@@ -354,15 +358,16 @@ function create_identity($arr) {
$myperms = $x['perms_connect'];
}
$r = q("insert into abook ( abook_account, abook_channel, abook_xchan, abook_closeness, abook_created, abook_updated, abook_self )
values ( %d, %d, '%s', %d, '%s', '%s', %d ) ",
intval($ret['channel']['channel_account_id']),
intval($newuid),
dbesc($hash),
intval(0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval(1)
$r = abook_store_lowlevel(
[
'abook_account' => intval($ret['channel']['channel_account_id']),
'abook_channel' => intval($newuid),
'abook_xchan' => $hash,
'abook_closeness' => 0,
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_self' => 1
]
);
$x = \Zotlabs\Access\Permissions::FilledPerms($myperms);
@@ -387,6 +392,7 @@ function create_identity($arr) {
set_pconfig($newuid,'autoperms',$k,$v);
}
}
// as this is a new channel, this shouldn't do anything and probaby is not needed
else {
$r = q("delete from pconfig where uid = %d and cat = 'autoperms'",
intval($newuid)
@@ -459,6 +465,7 @@ function create_identity($arr) {
* if true, set this default unconditionally
* if $force is false only do this if there is no existing default
*/
function set_default_login_identity($account_id, $channel_id, $force = true) {
$r = q("select account_default_channel from account where account_id = %d limit 1",
intval($account_id)
@@ -473,6 +480,16 @@ function set_default_login_identity($account_id, $channel_id, $force = true) {
}
}
function get_default_export_sections() {
$sections = [ 'channel', 'connections', 'config', 'apps', 'chatrooms', 'events', 'webpages', 'mail', 'wikis' ];
$cb = [ 'sections' => $sections ];
call_hooks('get_default_export_sections', $cb);
return $cb['sections'];
}
/**
* @brief Create an array representing the important channel information
* which would be necessary to create a nomadic identity clone. This includes
@@ -486,214 +503,280 @@ function set_default_login_identity($account_id, $channel_id, $force = true) {
* @returns array
* See function for details
*/
function identity_basic_export($channel_id, $items = false) {
function identity_basic_export($channel_id, $sections = null) {
/*
* Red basic channel export
* basic channel export
*/
$ret = array();
if(! $sections) {
$sections = get_default_export_sections();
}
$ret = [];
// use constants here as otherwise we will have no idea if we can import from a site
// with a non-standard platform and version.
$ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role());
$ret['compatibility'] = [
'project' => PLATFORM_NAME,
'version' => STD_VERSION,
'database' => DB_UPDATE_VERSION,
'server_role' => Zotlabs\Lib\System::get_server_role()
];
/*
* Process channel information regardless of it is one of the sections desired
* because we need the channel relocation information in all export files/streams.
*/
$r = q("select * from channel where channel_id = %d limit 1",
intval($channel_id)
);
if($r) {
translate_channel_perms_outbound($r[0]);
$ret['channel'] = $r[0];
$ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()];
}
$r = q("select * from profile where uid = %d",
intval($channel_id)
);
if($r)
$ret['profile'] = $r;
$xchans = array();
$r = q("select * from abook where abook_channel = %d ",
intval($channel_id)
);
if($r) {
$ret['abook'] = $r;
for($x = 0; $x < count($ret['abook']); $x ++) {
$xchans[] = $ret['abook'][$x]['abook_xchan'];
$abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']);
if($abconfig)
$ret['abook'][$x]['abconfig'] = $abconfig;
translate_abook_perms_outbound($ret['abook'][$x]);
if(in_array('channel',$sections)) {
$ret['channel'] = $r[0];
}
stringify_array_elms($xchans);
}
if($xchans) {
$r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) ");
if(in_array('channel',$sections)) {
$r = q("select * from profile where uid = %d",
intval($channel_id)
);
if($r)
$ret['xchan'] = $r;
$ret['profile'] = $r;
$r = q("select mimetype, content, os_storage from photo
where imgscale = 4 and photo_usage = %d and uid = %d limit 1",
intval(PHOTO_PROFILE),
intval($channel_id)
);
if($r) {
$ret['photo'] = [
'type' => $r[0]['mimetype'],
'data' => (($r[0]['os_storage'])
? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content']))
];
}
}
if(in_array('connections',$sections)) {
$xchans = array();
$r = q("select * from abook where abook_channel = %d ",
intval($channel_id)
);
if($r) {
$ret['abook'] = $r;
for($x = 0; $x < count($ret['abook']); $x ++) {
$xchans[] = $ret['abook'][$x]['abook_xchan'];
$abconfig = load_abconfig($channel_id,$ret['abook'][$x]['abook_xchan']);
if($abconfig)
$ret['abook'][$x]['abconfig'] = $abconfig;
translate_abook_perms_outbound($ret['abook'][$x]);
}
stringify_array_elms($xchans);
}
if($xchans) {
$r = q("select * from xchan where xchan_hash in ( " . implode(',',$xchans) . " ) ");
if($r)
$ret['xchan'] = $r;
$r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) ");
if($r)
$ret['hubloc'] = $r;
}
$r = q("select * from groups where uid = %d ",
intval($channel_id)
);
$r = q("select * from hubloc where hubloc_hash in ( " . implode(',',$xchans) . " ) ");
if($r)
$ret['hubloc'] = $r;
$ret['group'] = $r;
$r = q("select * from group_member where uid = %d ",
intval($channel_id)
);
if($r)
$ret['group_member'] = $r;
}
$r = q("select * from groups where uid = %d ",
intval($channel_id)
);
if(in_array('config',$sections)) {
$r = q("select * from pconfig where uid = %d",
intval($channel_id)
);
if($r)
$ret['config'] = $r;
// All other term types will be included in items, if requested.
if($r)
$ret['group'] = $r;
$r = q("select * from term where ttype in (%d,%d) and uid = %d",
intval(TERM_SAVEDSEARCH),
intval(TERM_THING),
intval($channel_id)
);
if($r)
$ret['term'] = $r;
$r = q("select * from group_member where uid = %d ",
intval($channel_id)
);
if($r)
$ret['group_member'] = $r;
// add psuedo-column obj_baseurl to aid in relocations
$r = q("select * from pconfig where uid = %d",
intval($channel_id)
);
if($r)
$ret['config'] = $r;
$r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d",
dbesc(z_root()),
intval($channel_id)
);
$r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1",
intval(PHOTO_PROFILE),
intval($channel_id)
);
if($r)
$ret['obj'] = $r;
$r = q("select * from likes where channel_id = %d",
intval($channel_id)
);
if($r)
$ret['likes'] = $r;
if($r) {
$ret['photo'] = array('type' => $r[0]['mimetype'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content'])));
}
// All other term types will be included in items, if requested.
$r = q("select * from term where ttype in (%d,%d) and uid = %d",
intval(TERM_SAVEDSEARCH),
intval(TERM_THING),
intval($channel_id)
);
if($r)
$ret['term'] = $r;
// add psuedo-column obj_baseurl to aid in relocations
$r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d",
dbesc(z_root()),
intval($channel_id)
);
if($r)
$ret['obj'] = $r;
$r = q("select * from app where app_channel = %d and app_system = 0",
intval($channel_id)
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['term'] = q("select * from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($r[$x]['id'])
);
}
$ret['app'] = $r;
}
$r = q("select * from chatroom where cr_uid = %d",
intval($channel_id)
);
if($r)
$ret['chatroom'] = $r;
$r = q("select * from event where uid = %d",
intval($channel_id)
);
if($r)
$ret['event'] = $r;
$r = q("select * from item where resource_type = 'event' and uid = %d",
intval($channel_id)
);
if($r) {
$ret['event_item'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
for($y = 0; $y < count($x); $y ++) {
$m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']);
if($m)
$ret['menu'][] = menu_element($ret['channel'],$m);
if(in_array('apps',$sections)) {
$r = q("select * from app where app_channel = %d and app_system = 0",
intval($channel_id)
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['term'] = q("select * from term where otype = %d and oid = %d",
intval(TERM_OBJ_APP),
intval($r[$x]['id'])
);
}
$ret['app'] = $r;
}
}
$addon = array('channel_id' => $channel_id,'data' => $ret);
if(in_array('chatrooms',$sections)) {
$r = q("select * from chatroom where cr_uid = %d",
intval($channel_id)
);
if($r)
$ret['chatroom'] = $r;
}
if(in_array('events',$sections)) {
$r = q("select * from event where uid = %d",
intval($channel_id)
);
if($r)
$ret['event'] = $r;
$r = q("select * from item where resource_type = 'event' and uid = %d",
intval($channel_id)
);
if($r) {
$ret['event_item'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
}
if(in_array('webpages',$sections)) {
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
for($y = 0; $y < count($x); $y ++) {
$m = menu_fetch($x[$y]['menu_name'],$channel_id,$ret['channel']['channel_hash']);
if($m)
$ret['menu'][] = menu_element($ret['channel'],$m);
}
}
$r = q("select * from item where item_type in ( "
. ITEM_TYPE_BLOCK . "," . ITEM_TYPE_PDL . "," . ITEM_TYPE_WEBPAGE . " ) and uid = %d",
intval($channel_id)
);
if($r) {
$ret['webpages'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['webpages'][] = encode_item($rr,true);
}
}
if(in_array('mail',$sections)) {
$r = q("select * from conv where uid = %d",
intval($channel_id)
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
}
$ret['conv'] = $r;
}
$r = q("select * from mail where mail.uid = %d",
intval($channel_id)
);
if($r) {
$m = array();
foreach($r as $rr) {
xchan_mail_query($rr);
$m[] = mail_encode($rr,true);
}
$ret['mail'] = $m;
}
}
if(in_array('wikis',$sections)) {
$r = q("select * from item where resource_type like 'nwiki%%' and uid = %d order by created",
intval($channel_id)
);
if($r) {
$ret['wiki'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rv) {
$ret['wiki'][] = encode_item($rv,true);
}
}
}
if(in_array('items',$sections)) {
/** @warning this may run into memory limits on smaller systems */
/** export three months of posts. If you want to export and import all posts you have to start with
* the first year and export/import them in ascending order.
*
* Don't export linked resource items. we'll have to pull those out separately.
*/
$r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d
and created > %s - INTERVAL %s and resource_type = '' order by created",
intval($channel_id),
db_utcnow(),
db_quoteinterval('3 MONTH')
);
if($r) {
$ret['item'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['item'][] = encode_item($rr,true);
}
}
$addon = [ 'channel_id' => $channel_id, 'sections' => $sections, 'data' => $ret];
call_hooks('identity_basic_export',$addon);
$ret = $addon['data'];
if(! $items)
return $ret;
$r = q("select * from likes where channel_id = %d",
intval($channel_id)
);
if($r)
$ret['likes'] = $r;
$r = q("select * from conv where uid = %d",
intval($channel_id)
);
if($r) {
for($x = 0; $x < count($r); $x ++) {
$r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject']));
}
$ret['conv'] = $r;
}
$r = q("select * from mail where mail.uid = %d",
intval($channel_id)
);
if($r) {
$m = array();
foreach($r as $rr) {
xchan_mail_query($rr);
$m[] = mail_encode($rr,true);
}
$ret['mail'] = $m;
}
/** @warning this may run into memory limits on smaller systems */
/** export three months of posts. If you want to export and import all posts you have to start with
* the first year and export/import them in ascending order.
*
* Don't export linked resource items. we'll have to pull those out separately.
*/
$r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created",
intval($channel_id),
db_utcnow(),
db_quoteinterval('3 MONTH')
);
if($r) {
$ret['item'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['item'][] = encode_item($rr,true);
}
return $ret;
}
@@ -768,7 +851,7 @@ function channel_export_items($channel_id, $start, $finish) {
$ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()];
}
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type = '' order by created",
intval(ITEM_TYPE_POST),
intval($channel_id),
dbesc($start),
@@ -1218,7 +1301,7 @@ function advanced_profile(&$a) {
$profile['marital'] = array( t('Status:'), App::$profile['marital']);
if(App::$profile['partner'])
$profile['marital']['partner'] = bbcode(App::$profile['partner']);
$profile['marital']['partner'] = zidify_links(bbcode(App::$profile['partner']));
if(strlen(App::$profile['howlong']) && App::$profile['howlong'] > NULL_DATE) {
$profile['howlong'] = relative_date(App::$profile['howlong'], t('for %1$d %2$s'));
@@ -1278,10 +1361,14 @@ function advanced_profile(&$a) {
// logger('mod_profile: things: ' . print_r($things,true), LOGGER_DATA);
$exportlink = ((App::$profile['profile_vcard']) ? zid(z_root() . '/profile/' . App::$profile['channel_address'] . '/vcard') : '');
return replace_macros($tpl, array(
'$title' => t('Profile'),
'$canlike' => (($profile['canlike'])? true : false),
'$likethis' => t('Like this thing'),
'$export' => t('Export'),
'$exportlink' => $exportlink,
'$profile' => $profile,
'$fields' => $clean_fields,
'$editmenu' => profile_edit_menu(App::$profile['profile_uid']),
@@ -1705,21 +1792,26 @@ function get_zcard($channel, $observer_hash = '', $args = array()) {
$maxwidth = (($args['width']) ? intval($args['width']) : 0);
$maxheight = (($args['height']) ? intval($args['height']) : 0);
if(($maxwidth > 1200) || ($maxwidth < 1))
if(($maxwidth > 1200) || ($maxwidth < 1)) {
$maxwidth = 1200;
$cover_width = 1200;
}
if($maxwidth <= 425) {
$width = 425;
$cover_width = 425;
$size = 'hz_small';
$cover_size = PHOTO_RES_COVER_425;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']);
} elseif($maxwidth <= 900) {
$width = 900;
$cover_width = 850;
$size = 'hz_medium';
$cover_size = PHOTO_RES_COVER_850;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']);
} elseif($maxwidth <= 1200) {
$width = 1200;
$cover_width = 1200;
$size = 'hz_large';
$cover_size = PHOTO_RES_COVER_1200;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']);
@@ -1741,7 +1833,8 @@ function get_zcard($channel, $observer_hash = '', $args = array()) {
$cover = $r[0];
$cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
} else {
$cover = $pphoto;
$default_cover = get_config('system','default_cover_photo','pexels-94622');
$cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ];
}
$o .= replace_macros(get_markup_template('zcard.tpl'), array(
@@ -1765,23 +1858,28 @@ function get_zcard_embed($channel, $observer_hash = '', $args = array()) {
$maxwidth = (($args['width']) ? intval($args['width']) : 0);
$maxheight = (($args['height']) ? intval($args['height']) : 0);
if(($maxwidth > 1200) || ($maxwidth < 1))
if(($maxwidth > 1200) || ($maxwidth < 1)) {
$maxwidth = 1200;
$cover_width = 1200;
}
if($maxwidth <= 425) {
$width = 425;
$cover_width = 425;
$size = 'hz_small';
$cover_size = PHOTO_RES_COVER_425;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 80 , 'height' => 80, 'href' => $channel['xchan_photo_m']);
}
elseif($maxwidth <= 900) {
$width = 900;
$cover_width = 850;
$size = 'hz_medium';
$cover_size = PHOTO_RES_COVER_850;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 160 , 'height' => 160, 'href' => $channel['xchan_photo_l']);
}
elseif($maxwidth <= 1200) {
$width = 1200;
$cover_width = 1200;
$size = 'hz_large';
$cover_size = PHOTO_RES_COVER_1200;
$pphoto = array('mimetype' => $channel['xchan_photo_mimetype'], 'width' => 300 , 'height' => 300, 'href' => $channel['xchan_photo_l']);
@@ -1799,8 +1897,10 @@ function get_zcard_embed($channel, $observer_hash = '', $args = array()) {
if($r) {
$cover = $r[0];
$cover['href'] = z_root() . '/photo/' . $r[0]['resource_id'] . '-' . $r[0]['imgscale'];
} else {
$cover = $pphoto;
}
else {
$default_cover = get_config('system','default_cover_photo','pexels-94622');
$cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.jpg' ];
}
$o .= replace_macros(get_markup_template('zcard_embed.tpl'),array(
@@ -1876,8 +1976,74 @@ function channel_manual_conv_update($channel_id) {
$x = get_pconfig($channel_id, 'system','manual_conversation_update');
if($x === false)
$x = get_config('system','manual_conversation_update');
$x = get_config('system','manual_conversation_update', 1);
return intval($x);
}
function remote_login() {
$o = replace_macros(get_markup_template('remote_login.tpl'),array(
'$title' => t('Remote Authentication'),
'$desc' => t('Enter your channel address (e.g. [email protected])'),
'$submit' => t('Authenticate')
));
return $o;
}
function profile_store_lowlevel($arr) {
$store = [
'profile_guid' => ((array_key_exists('profile_guid',$arr)) ? $arr['profile_guid'] : ''),
'aid' => ((array_key_exists('aid',$arr)) ? $arr['aid'] : 0),
'uid' => ((array_key_exists('uid',$arr)) ? $arr['uid'] : 0),
'profile_name' => ((array_key_exists('profile_name',$arr)) ? $arr['profile_name'] : ''),
'is_default' => ((array_key_exists('is_default',$arr)) ? $arr['is_default'] : 0),
'hide_friends' => ((array_key_exists('hide_friends',$arr)) ? $arr['hide_friends'] : 0),
'fullname' => ((array_key_exists('fullname',$arr)) ? $arr['fullname'] : ''),
'pdesc' => ((array_key_exists('pdesc',$arr)) ? $arr['pdesc'] : ''),
'chandesc' => ((array_key_exists('chandesc',$arr)) ? $arr['chandesc'] : ''),
'dob' => ((array_key_exists('dob',$arr)) ? $arr['dob'] : ''),
'dob_tz' => ((array_key_exists('dob_tz',$arr)) ? $arr['dob_tz'] : ''),
'address' => ((array_key_exists('address',$arr)) ? $arr['address'] : ''),
'locality' => ((array_key_exists('locality',$arr)) ? $arr['locality'] : ''),
'region' => ((array_key_exists('region',$arr)) ? $arr['region'] : ''),
'postal_code' => ((array_key_exists('postal_code',$arr)) ? $arr['postal_code'] : ''),
'country_name' => ((array_key_exists('country_name',$arr)) ? $arr['country_name'] : ''),
'hometown' => ((array_key_exists('hometown',$arr)) ? $arr['hometown'] : ''),
'gender' => ((array_key_exists('gender',$arr)) ? $arr['gender'] : ''),
'marital' => ((array_key_exists('marital',$arr)) ? $arr['marital'] : ''),
'partner' => ((array_key_exists('partner',$arr)) ? $arr['partner'] : ''),
'howlong' => ((array_key_exists('howlong',$arr)) ? $arr['howlong'] : NULL_DATE),
'sexual' => ((array_key_exists('sexual',$arr)) ? $arr['sexual'] : ''),
'politic' => ((array_key_exists('politic',$arr)) ? $arr['politic'] : ''),
'religion' => ((array_key_exists('religion',$arr)) ? $arr['religion'] : ''),
'keywords' => ((array_key_exists('keywords',$arr)) ? $arr['keywords'] : ''),
'likes' => ((array_key_exists('likes',$arr)) ? $arr['likes'] : ''),
'dislikes' => ((array_key_exists('dislikes',$arr)) ? $arr['dislikes'] : ''),
'about' => ((array_key_exists('about',$arr)) ? $arr['about'] : ''),
'summary' => ((array_key_exists('summary',$arr)) ? $arr['summary'] : ''),
'music' => ((array_key_exists('music',$arr)) ? $arr['music'] : ''),
'book' => ((array_key_exists('book',$arr)) ? $arr['book'] : ''),
'tv' => ((array_key_exists('tv',$arr)) ? $arr['tv'] : ''),
'film' => ((array_key_exists('film',$arr)) ? $arr['film'] : ''),
'interest' => ((array_key_exists('interest',$arr)) ? $arr['interest'] : ''),
'romance' => ((array_key_exists('romance',$arr)) ? $arr['romance'] : ''),
'employment' => ((array_key_exists('employment',$arr)) ? $arr['employment'] : ''),
'education' => ((array_key_exists('education',$arr)) ? $arr['education'] : ''),
'contact' => ((array_key_exists('contact',$arr)) ? $arr['contact'] : ''),
'channels' => ((array_key_exists('channels',$arr)) ? $arr['channels'] : ''),
'homepage' => ((array_key_exists('homepage',$arr)) ? $arr['homepage'] : ''),
'photo' => ((array_key_exists('photo',$arr)) ? $arr['photo'] : ''),
'thumb' => ((array_key_exists('thumb',$arr)) ? $arr['thumb'] : ''),
'publish' => ((array_key_exists('publish',$arr)) ? $arr['publish'] : 0),
'profile_vcard' => ((array_key_exists('profile_vcard',$arr)) ? $arr['profile_vcard'] : '')
];
return create_table_from_array('profile',$store);
}
+308
View File
@@ -1,6 +1,38 @@
<?php /** @file */
function abook_store_lowlevel($arr) {
$store = [
'abook_account' => ((array_key_exists('abook_account',$arr)) ? $arr['abook_account'] : 0),
'abook_channel' => ((array_key_exists('abook_channel',$arr)) ? $arr['abook_channel'] : 0),
'abook_xchan' => ((array_key_exists('abook_xchan',$arr)) ? $arr['abook_xchan'] : ''),
'abook_my_perms' => ((array_key_exists('abook_my_perms',$arr)) ? $arr['abook_my_perms'] : 0),
'abook_their_perms' => ((array_key_exists('abook_their_perms',$arr)) ? $arr['abook_their_perms'] : 0),
'abook_closeness' => ((array_key_exists('abook_closeness',$arr)) ? $arr['abook_closeness'] : 99),
'abook_created' => ((array_key_exists('abook_created',$arr)) ? $arr['abook_created'] : NULL_DATE),
'abook_updated' => ((array_key_exists('abook_updated',$arr)) ? $arr['abook_updated'] : NULL_DATE),
'abook_connected' => ((array_key_exists('abook_connected',$arr)) ? $arr['abook_connected'] : NULL_DATE),
'abook_dob' => ((array_key_exists('abook_dob',$arr)) ? $arr['abook_dob'] : NULL_DATE),
'abook_flags' => ((array_key_exists('abook_flags',$arr)) ? $arr['abook_flags'] : 0),
'abook_blocked' => ((array_key_exists('abook_blocked',$arr)) ? $arr['abook_blocked'] : 0),
'abook_ignored' => ((array_key_exists('abook_ignored',$arr)) ? $arr['abook_ignored'] : 0),
'abook_hidden' => ((array_key_exists('abook_hidden',$arr)) ? $arr['abook_hidden'] : 0),
'abook_archived' => ((array_key_exists('abook_archived',$arr)) ? $arr['abook_archived'] : 0),
'abook_pending' => ((array_key_exists('abook_pending',$arr)) ? $arr['abook_pending'] : 0),
'abook_unconnected' => ((array_key_exists('abook_unconnected',$arr)) ? $arr['abook_unconnected'] : 0),
'abook_self' => ((array_key_exists('abook_self',$arr)) ? $arr['abook_self'] : 0),
'abook_feed' => ((array_key_exists('abook_feed',$arr)) ? $arr['abook_feed'] : 0),
'abook_profile' => ((array_key_exists('abook_profile',$arr)) ? $arr['abook_profile'] : ''),
'abook_incl' => ((array_key_exists('abook_incl',$arr)) ? $arr['abook_incl'] : ''),
'abook_excl' => ((array_key_exists('abook_excl',$arr)) ? $arr['abook_excl'] : ''),
'abook_instance' => ((array_key_exists('abook_instance',$arr)) ? $arr['abook_instance'] : '')
];
return create_table_from_array('abook',$store);
}
function rconnect_url($channel_id,$xchan) {
@@ -630,3 +662,279 @@ function random_profile() {
return '';
}
function update_vcard($arr,$vcard = null) {
// logger('update_vcard: ' . print_r($arr,true));
$fn = $arr['fn'];
// This isn't strictly correct and could be a cause for concern.
// 'N' => array_reverse(explode(' ', $fn))
// What we really want is
// 'N' => Adams;John;Quincy;Reverend,Dr.;III
// which is a very difficult parsing problem especially if you allow
// the surname to contain spaces. The only way to be sure to get it
// right is to provide a form to input all the various fields and not
// try to extract it from the FN.
if(! $vcard) {
$vcard = new \Sabre\VObject\Component\VCard([
'FN' => $fn,
'N' => array_reverse(explode(' ', $fn))
]);
}
else {
$vcard->FN = $fn;
$vcard->N = array_reverse(explode(' ', $fn));
}
$org = $arr['org'];
if($org) {
$vcard->ORG = $org;
}
$title = $arr['title'];
if($title) {
$vcard->TITLE = $title;
}
$tel = $arr['tel'];
$tel_type = $arr['tel_type'];
if($tel) {
$i = 0;
foreach($tel as $item) {
if($item) {
$vcard->add('TEL', $item, ['type' => $tel_type[$i]]);
}
$i++;
}
}
$email = $arr['email'];
$email_type = $arr['email_type'];
if($email) {
$i = 0;
foreach($email as $item) {
if($item) {
$vcard->add('EMAIL', $item, ['type' => $email_type[$i]]);
}
$i++;
}
}
$impp = $arr['impp'];
$impp_type = $arr['impp_type'];
if($impp) {
$i = 0;
foreach($impp as $item) {
if($item) {
$vcard->add('IMPP', $item, ['type' => $impp_type[$i]]);
}
$i++;
}
}
$url = $arr['url'];
$url_type = $arr['url_type'];
if($url) {
$i = 0;
foreach($url as $item) {
if($item) {
$vcard->add('URL', $item, ['type' => $url_type[$i]]);
}
$i++;
}
}
$adr = $arr['adr'];
$adr_type = $arr['adr_type'];
if($adr) {
$i = 0;
foreach($adr as $item) {
if($item) {
$vcard->add('ADR', $item, ['type' => $adr_type[$i]]);
}
$i++;
}
}
$note = $arr['note'];
if($note) {
$vcard->NOTE = $note;
}
return $vcard->serialize();
}
function get_vcard_array($vc,$id) {
$photo = '';
if($vc->PHOTO) {
$photo_value = strtolower($vc->PHOTO->getValueType()); // binary or uri
if($photo_value === 'binary') {
$photo_type = strtolower($vc->PHOTO['TYPE']); // mime jpeg, png or gif
$photo = 'data:image/' . $photo_type . ';base64,' . base64_encode((string)$vc->PHOTO);
}
else {
$url = parse_url((string)$vc->PHOTO);
$photo = 'data:' . $url['path'];
}
}
$fn = '';
if($vc->FN) {
$fn = (string) escape_tags($vc->FN);
}
$org = '';
if($vc->ORG) {
$org = (string) escape_tags($vc->ORG);
}
$title = '';
if($vc->TITLE) {
$title = (string) escape_tags($vc->TITLE);
}
$tels = [];
if($vc->TEL) {
foreach($vc->TEL as $tel) {
$type = (($tel['TYPE']) ? vcard_translate_type((string)$tel['TYPE']) : '');
$tels[] = [
'type' => $type,
'nr' => (string) escape_tags($tel)
];
}
}
$emails = [];
if($vc->EMAIL) {
foreach($vc->EMAIL as $email) {
$type = (($email['TYPE']) ? vcard_translate_type((string)$email['TYPE']) : '');
$emails[] = [
'type' => $type,
'address' => (string) escape_tags($email)
];
}
}
$impps = [];
if($vc->IMPP) {
foreach($vc->IMPP as $impp) {
$type = (($impp['TYPE']) ? vcard_translate_type((string)$impp['TYPE']) : '');
$impps[] = [
'type' => $type,
'address' => (string) escape_tags($impp)
];
}
}
$urls = [];
if($vc->URL) {
foreach($vc->URL as $url) {
$type = (($url['TYPE']) ? vcard_translate_type((string)$url['TYPE']) : '');
$urls[] = [
'type' => $type,
'address' => (string) escape_tags($url)
];
}
}
$adrs = [];
if($vc->ADR) {
foreach($vc->ADR as $adr) {
$type = (($adr['TYPE']) ? vcard_translate_type((string)$adr['TYPE']) : '');
$adrs[] = [
'type' => $type,
'address' => $adr->getParts()
];
$last_entry = end($adrs);
if($adrs[$last_entry]['address'])
array_walk($adrs[$last_entry]['address'],'array_escape_tags');
}
}
$note = '';
if($vc->NOTE) {
$note = (string) escape_tags($vc->NOTE);
}
$card = [
'id' => $id,
'photo' => $photo,
'fn' => $fn,
'org' => $org,
'title' => $title,
'tels' => $tels,
'emails' => $emails,
'impps' => $impps,
'urls' => $urls,
'adrs' => $adrs,
'note' => $note
];
return $card;
}
function vcard_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 . ')'];
}
}
function vcard_query(&$r) {
$arr = [];
if($r && is_array($r) && count($r)) {
$uid = $r[0]['abook_channel'];
foreach($r as $rv) {
if($rv['abook_xchan'] && (! in_array("'" . dbesc($rv['abook_xchan']) . "'",$arr)))
$arr[] = "'" . dbesc($rv['abook_xchan']) . "'";
}
}
if($arr) {
$a = q("select * from abconfig where chan = %d and xchan in (" . protect_sprintf(implode(',', $arr)) . ") and cat = 'system' and k = 'vcard'",
intval($uid)
);
if($a) {
foreach($a as $av) {
for($x = 0; $x < count($r); $x ++) {
if($r[$x]['abook_xchan'] == $av['xchan']) {
$vctmp = \Sabre\VObject\Reader::read($av['v']);
$r[$x]['vcard'] = (($vctmp) ? get_vcard_array($vctmp,$r[$x]['abook_id']) : [] );
}
}
}
}
}
}
+191 -12
View File
@@ -689,7 +689,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'id' => (($preview) ? 'P0' : $item['item_id']),
'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, $profile_url),
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
'thread_action_menu' => thread_action_menu($item,$mode),
'thread_author_menu' => thread_author_menu($item,$mode),
'name' => $profile_name,
'sparkle' => $sparkle,
'lock' => $lock,
@@ -732,7 +733,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'like' => '',
'dislike' => '',
'comment' => '',
'conv' => (($preview) ? '' : array('href'=> z_root() . '/display/' . $item['mid'], 'title'=> t('View in context'))),
'conv' => (($preview) ? '' : array('href'=> z_root() . '/display/' . gen_link_id($item['mid']), 'title'=> t('View in context'))),
'previewing' => $previewing,
'wait' => t('Please wait'),
'thread_level' => 1,
@@ -960,6 +961,169 @@ function item_photo_menu($item){
return $o;
}
function thread_action_menu($item,$mode = '') {
$menu = [];
if((local_channel()) && local_channel() == $item['uid']) {
$menu[] = [
'menu' => 'view_source',
'title' => t('View Source'),
'icon' => 'eye',
'action' => 'viewsrc(' . $item['id'] . '); return false;',
'href' => '#'
];
if(! in_array($mode, [ 'network-new', 'search', 'community'])) {
if($item['parent'] == $item['id'] && (get_observer_hash() != $item['author_xchan'])) {
$menu[] = [
'menu' => 'follow_thread',
'title' => t('Follow Thread'),
'icon' => 'plus',
'action' => 'dosubthread(' . $item['id'] . '); return false;',
'href' => '#'
];
}
$menu[] = [
'menu' => 'unfollow_thread',
'title' => t('Unfollow Thread'),
'icon' => 'minus',
'action' => 'dounsubthread(' . $item['id'] . '); return false;',
'href' => '#'
];
}
}
$args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ];
call_hooks('thread_action_menu', $args);
return $args['menu'];
}
function thread_author_menu($item, $mode = '') {
$menu = [];
$local_channel = local_channel();
if($local_channel) {
if(! count(App::$contacts))
load_contact_links($local_channel);
$channel = App::get_channel();
$channel_hash = (($channel) ? $channel['channel_hash'] : '');
}
$profile_link = chanlink_hash($item['author_xchan']);
if($item['uid'] > 0)
$pm_url = z_root() . '/mail/new/?f=&hash=' . $item['author_xchan'];
if(App::$contacts && array_key_exists($item['author_xchan'],App::$contacts))
$contact = App::$contacts[$item['author_xchan']];
else
if($local_channel && $item['author']['xchan_addr'])
$follow_url = z_root() . '/follow/?f=&url=' . $item['author']['xchan_addr'];
if($contact) {
$poke_link = z_root() . '/poke/?f=&c=' . $contact['abook_id'];
if (! intval($contact['abook_self']))
$contact_url = z_root() . '/connedit/' . $contact['abook_id'];
$posts_link = z_root() . '/network/?cid=' . $contact['abook_id'];
$clean_url = normalise_link($item['author-link']);
}
$rating_enabled = get_config('system','rating_enabled');
$ratings_url = (($rating_enabled) ? z_root() . '/ratings/' . urlencode($item['author_xchan']) : '');
if($profile_link) {
$menu[] = [
'menu' => 'view_profile',
'title' => t('View Profile'),
'icon' => 'fw',
'action' => '',
'href' => $profile_link
];
}
if($posts_link) {
$menu[] = [
'menu' => 'view_posts',
'title' => t('Activity/Posts'),
'icon' => 'fw',
'action' => '',
'href' => $posts_link
];
}
if($follow_url) {
$menu[] = [
'menu' => 'follow',
'title' => t('Connect'),
'icon' => 'fw',
'action' => '',
'href' => $follow_url
];
}
if($contact_url) {
$menu[] = [
'menu' => 'connedit',
'title' => t('Edit Connection'),
'icon' => 'fw',
'action' => '',
'href' => $contact_url
];
}
if($pm_url) {
$menu[] = [
'menu' => 'prv_message',
'title' => t('Message'),
'icon' => 'fw',
'action' => '',
'href' => $pm_url
];
}
if($ratings_url) {
$menu[] = [
'menu' => 'ratings',
'title' => t('Ratings'),
'icon' => 'fw',
'action' => '',
'href' => $ratings_url
];
}
if($poke_link) {
$menu[] = [
'menu' => 'poke',
'title' => t('Poke'),
'icon' => 'fw',
'action' => '',
'href' => $poke_link
];
}
$args = [ 'item' => $item, 'mode' => $mode, 'menu' => $menu ];
call_hooks('thread_author_menu', $args);
return $args['menu'];
}
/**
* @brief Checks item to see if it is one of the builtin activities (like/dislike, event attendance, consensus items, etc.)
*
@@ -1011,8 +1175,8 @@ function builtin_activity_puller($item, &$conv_responses) {
if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) {
$name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown'));
$url = (($item['author']['xchan_url'] && $item['author']['xchan_photo_s'])
? '<a href="' . chanlink_url($item['author']['xchan_url']) . '">' . '<img class="dropdown-menu-img-xs" src="' . zid($item['author']['xchan_photo_s']) . '" alt="' . urlencode($name) . '" />' . $name . '</a>'
$url = (($item['author_xchan'] && $item['author']['xchan_photo_s'])
? '<a href="' . chanlink_hash($item['author_xchan']) . '">' . '<img class="dropdown-menu-img-xs" src="' . zid($item['author']['xchan_photo_s']) . '" alt="' . urlencode($name) . '" />' . $name . '</a>'
: '<a href="#" class="disabled">' . $name . '</a>'
);
@@ -1232,11 +1396,11 @@ function status_editor($a, $x, $popup = false) {
'$setloc' => $setloc,
'$voting' => t('Toggle voting'),
'$feature_voting' => $feature_voting,
'$consensus' => 0,
'$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0),
'$nocommenttitle' => t('Disable comments'),
'$nocommenttitlesub' => t('Toggle comments'),
'$feature_nocomment' => $feature_nocomment,
'$nocomment' => 0,
'$nocomment' => ((array_key_exists('item',$x)) ? $x['item']['item_nocomment'] : 0),
'$clearloc' => $clearloc,
'$title' => ((x($x, 'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''),
'$placeholdertitle' => ((x($x, 'placeholdertitle')) ? $x['placeholdertitle'] : t('Title (optional)')),
@@ -1400,7 +1564,7 @@ function format_location($item) {
if(strpos($item['location'],'#') === 0) {
$location = substr($item['location'],1);
$location = ((strpos($location,'[') !== false) ? bbcode($location) : $location);
$location = ((strpos($location,'[') !== false) ? zidify_links(bbcode($location)) : $location);
}
else {
$locate = array('location' => $item['location'], 'coord' => $item['coord'], 'html' => '');
@@ -1452,7 +1616,7 @@ function prepare_page($item) {
'$author' => (($naked) ? '' : $item['author']['xchan_name']),
'$auth_url' => (($naked) ? '' : zid($item['author']['xchan_url'])),
'$date' => (($naked) ? '' : datetime_convert('UTC', date_default_timezone_get(), $item['created'], 'Y-m-d H:i')),
'$title' => smilies(bbcode($item['title'])),
'$title' => zidify_links(smilies(bbcode($item['title']))),
'$body' => $body['html'],
'$preview' => $preview,
'$link' => $link,
@@ -1622,6 +1786,20 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
$cal_link = '/cal/' . $nickname;
}
require_once('include/security.php');
$sql_options = item_permissions_sql($uid);
$r = q("select item.* from item left join iconfig on item.id = iconfig.iid
where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s'
and item.item_delayed = 0 and item.item_deleted = 0
and ( iconfig.k = 'WEBPAGE' and item_type = %d )
$sql_options limit 1",
intval($uid),
dbesc('home'),
intval(ITEM_TYPE_WEBPAGE)
);
$has_webpages = (($r) ? true : false);
if (get_pconfig($uid, 'system', 'noprofiletabs'))
return;
@@ -1706,15 +1884,16 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
);
}
if ($p['write_pages'] && feature_enabled($uid,'webpages')) {
if($has_webpages && feature_enabled($uid,'webpages')) {
$tabs[] = array(
'label' => t('Webpages'),
'url' => z_root() . '/webpages/' . $nickname,
'url' => z_root() . '/page/' . $nickname . '/home',
'sel' => ((argv(0) == 'webpages') ? 'active' : ''),
'title' => t('Manage Webpages'),
'title' => t('View Webpages'),
'id' => 'webpages-tab',
);
}
}
if(feature_enabled($uid,'wiki') && (get_account_techlevel($account_id) > 3)) {
$tabs[] = array(
+1 -1
View File
@@ -337,7 +337,7 @@ function db_concat($fld, $sep) {
function q($sql) {
$args = func_get_args();
unset($args[0]);
array_shift($args);
if(\DBA::$dba && \DBA::$dba->connected) {
$stmt = vsprintf($sql, $args);
+60 -21
View File
@@ -25,7 +25,7 @@ function format_event_html($ev) {
$o = '<div class="vevent">' . "\r\n";
$o .= '<div class="event-title"><h3><i class="fa fa-calendar"></i>&nbsp;' . bbcode($ev['summary']) . '</h3></div>' . "\r\n";
$o .= '<div class="event-title"><h3><i class="fa fa-calendar"></i>&nbsp;' . zidify_links(smilies(bbcode($ev['summary']))) . '</h3></div>' . "\r\n";
$o .= '<div class="event-start"><span class="event-label">' . t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. datetime_convert('UTC', 'UTC', $ev['dtstart'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
@@ -46,11 +46,11 @@ function format_event_html($ev) {
$ev['dtend'] , $bd_format )))
. '</span></div>' . "\r\n";
$o .= '<div class="event-description">' . bbcode($ev['description']) . '</div>' . "\r\n";
$o .= '<div class="event-description">' . zidify_links(smilies(bbcode($ev['description']))) . '</div>' . "\r\n";
if(strlen($ev['location']))
$o .= '<div class="event-location"><span class="event-label"> ' . t('Location:') . '</span>&nbsp;<span class="location">'
. bbcode($ev['location'])
. zidify_links(smilies(bbcode($ev['location'])))
. '</span></div>' . "\r\n";
$o .= '</div>' . "\r\n";
@@ -69,7 +69,7 @@ function format_event_obj($jobject) {
$bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM
$event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array(
'$title' => bbcode($object['title']),
'$title' => zidify_links(smilies(bbcode($object['title']))),
'$dtstart_label' => t('Starts:'),
'$dtstart_title' => datetime_convert('UTC', 'UTC', $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )),
'$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))),
@@ -80,9 +80,9 @@ function format_event_obj($jobject) {
));
$event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array(
'$description' => bbcode($object['description']),
'$description' => zidify_links(smilies(bbcode($object['description']))),
'$location_label' => t('Location:'),
'$location' => bbcode($object['location'])
'$location' => zidify_links(smilies(bbcode($object['location'])))
));
}
@@ -127,12 +127,18 @@ function format_event_ical($ev) {
$o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['dtend'] && ! $ev['nofinish'])
$o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['summary'])
if($ev['summary']) {
$o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']);
if($ev['location'])
$o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']);
}
if($ev['location']) {
$o .= "\r\nLOCATION:" . format_ical_text($ev['location']);
if($ev['description'])
$o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']);
}
if($ev['description']) {
$o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']);
$o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']);
}
if($ev['event_priority'])
$o .= "\r\nPRIORITY:" . intval($ev['event_priority']);
$o .= "\r\nUID:" . $ev['event_hash'] ;
@@ -154,8 +160,10 @@ function format_todo_ical($ev) {
$o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['dtend'] && ! $ev['nofinish'])
$o .= "\r\nDUE:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : ''));
if($ev['summary'])
if($ev['summary']) {
$o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']);
$o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']);
}
if($ev['event_status']) {
$o .= "\r\nSTATUS:" . $ev['event_status'];
if($ev['event_status'] === 'COMPLETED')
@@ -165,10 +173,14 @@ function format_todo_ical($ev) {
$o .= "\r\nPERCENT-COMPLETE:" . $ev['event_percent'];
if(intval($ev['event_sequence']))
$o .= "\r\nSEQUENCE:" . $ev['event_sequence'];
if($ev['location'])
if($ev['location']) {
$o .= "\r\nLOCATION:" . format_ical_text($ev['location']);
if($ev['description'])
$o .= "\r\nX-ZOT-LOCATION:" . format_ical_sourcetext($ev['location']);
}
if($ev['description']) {
$o .= "\r\nDESCRIPTION:" . format_ical_text($ev['description']);
$o .= "\r\nX-ZOT-DESCRIPTION:" . format_ical_sourcetext($ev['description']);
}
$o .= "\r\nUID:" . $ev['event_hash'] ;
if($ev['event_priority'])
$o .= "\r\nPRIORITY:" . intval($ev['event_priority']);
@@ -178,7 +190,6 @@ function format_todo_ical($ev) {
}
function format_ical_text($s) {
require_once('include/bbcode.php');
require_once('include/html2plain.php');
@@ -186,6 +197,12 @@ function format_ical_text($s) {
$s = html2plain(bbcode($s));
$s = str_replace(["\r\n","\n"],["",""],$s);
return(wordwrap(str_replace(['\\',',',';'],['\\\\','\\,','\\;'],$s),72,"\r\n ",true));
}
function format_ical_sourcetext($s) {
$s = base64_encode($s);
return(wordwrap(str_replace(['\\',',',';'],['\\\\','\\,','\\;'],$s),72,"\r\n ",true));
}
@@ -623,12 +640,21 @@ function event_import_ical($ical, $uid) {
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
}
if(isset($ical->LOCATION))
if(isset($ical->{'X-ZOT-LOCATION'}))
$ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'});
elseif(isset($ical->LOCATION))
$ev['location'] = (string) $ical->LOCATION;
if(isset($ical->DESCRIPTION))
if(isset($ical->{'X-ZOT-DESCRIPTION'}))
$ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'});
elseif(isset($ical->DESCRIPTION))
$ev['description'] = (string) $ical->DESCRIPTION;
if(isset($ical->SUMMARY))
if(isset($ical->{'X-ZOT-SUMMARY'}))
$ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'});
elseif(isset($ical->SUMMARY))
$ev['summary'] = (string) $ical->SUMMARY;
if(isset($ical->PRIORITY))
$ev['event_priority'] = intval((string) $ical->PRIORITY);
@@ -663,6 +689,10 @@ function event_import_ical($ical, $uid) {
}
function event_ical_get_sourcetext($s) {
return base64_decode($s);
}
function event_import_ical_task($ical, $uid) {
$c = q("select * from channel where channel_id = %d limit 1",
@@ -718,12 +748,21 @@ function event_import_ical_task($ical, $uid) {
$ev['edited'] = datetime_convert('UTC','UTC',$edited->format(\DateTime::W3C));
}
if(isset($ical->LOCATION))
if(isset($ical->{'X-ZOT-LOCATION'}))
$ev['location'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-LOCATION'});
elseif(isset($ical->LOCATION))
$ev['location'] = (string) $ical->LOCATION;
if(isset($ical->DESCRIPTION))
if(isset($ical->{'X-ZOT-DESCRIPTION'}))
$ev['description'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-DESCRIPTION'});
elseif(isset($ical->DESCRIPTION))
$ev['description'] = (string) $ical->DESCRIPTION;
if(isset($ical->SUMMARY))
if(isset($ical->{'X-ZOT-SUMMARY'}))
$ev['summary'] = event_ical_get_sourcetext( (string) $ical->{'X-ZOT-SUMMARY'});
elseif(isset($ical->SUMMARY))
$ev['summary'] = (string) $ical->SUMMARY;
if(isset($ical->PRIORITY))
$ev['event_priority'] = intval((string) $ical->PRIORITY);
@@ -977,9 +1016,9 @@ function event_store_item($arr, $event) {
// otherwise we'll fallback to /display/$message_id
if($wall)
$item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . $item_arr['mid'];
$item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . urlencode($item_arr['mid']);
else
$item_arr['plink'] = z_root() . '/display/' . $item_arr['mid'];
$item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']);
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['event_xchan'])
+18
View File
@@ -148,6 +148,15 @@ function get_features($filtered = true) {
feature_level('ajaxchat',1),
],
[
'permcats',
t('Permission Groups'),
t('Provide alternate connection permission roles.'),
false,
get_config('feature_lock','permcats'),
feature_level('permcats',2),
],
[
'smart_birthdays',
t('Smart Birthdays'),
@@ -157,6 +166,15 @@ function get_features($filtered = true) {
feature_level('smart_birthdays',2),
],
[
'event_tz_select',
t('Event Timezone Selection'),
t('Allow event creation in timezones other than your own.'),
false,
get_config('feature_lock','event_tz_select'),
feature_level('event_tz_select',2),
],
[
'advanced_dirsearch',
t('Advanced Directory Search'),
+103 -32
View File
@@ -236,7 +236,7 @@ function get_atom_elements($feed, $item, &$author) {
if(substr($author['author_link'],-1,1) == '/')
$author['author_link'] = substr($author['author_link'],0,-1);
$res['mid'] = base64url_encode(unxmlify($item->get_id()));
$res['mid'] = unxmlify($item->get_id());
$res['title'] = unxmlify($item->get_title());
$res['body'] = unxmlify($item->get_content());
$res['plink'] = unxmlify($item->get_link(0));
@@ -331,6 +331,8 @@ function get_atom_elements($feed, $item, &$author) {
}
}
$ostatus_protocol = (($item->get_item_tags(NAMESPACE_OSTATUS,'conversation')) ? true : false);
$apps = $item->get_item_tags(NAMESPACE_STATUSNET,'notice_info');
if($apps && $apps[0]['attribs']['']['source']) {
$res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source']));
@@ -343,6 +345,8 @@ function get_atom_elements($feed, $item, &$author) {
$have_real_body = false;
$rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env');
if(! $rawenv)
$rawenv = $item->get_item_tags(NAMESPACE_ZOT,'source');
if($rawenv) {
$have_real_body = true;
$res['body'] = $rawenv[0]['data'];
@@ -388,7 +392,15 @@ function get_atom_elements($feed, $item, &$author) {
$res['body'] = escape_tags($res['body']);
}
if($res['plink'] && $res['title']) {
// strip title and don't apply "title-in-body" if the feed involved
// uses the OStatus stack. We need a more generalised way for the calling
// function to specify this behaviour or for plugins to alter it.
if($ostatus_protocol) {
$res['title'] = '';
}
elseif($res['plink'] && $res['title']) {
$res['body'] = '#^[url=' . $res['plink'] . ']' . $res['title'] . '[/url]' . "\n\n" . $res['body'];
$terms = array();
$terms[] = array(
@@ -623,14 +635,16 @@ function get_atom_elements($feed, $item, &$author) {
$res['target'] = $obj;
}
$arr = array('feed' => $feed, 'item' => $item, 'result' => $res);
$arr = array('feed' => $feed, 'item' => $item, 'author' => $author, 'result' => $res);
call_hooks('parse_atom', $arr);
logger('get_atom_elements: author: ' . print_r($author,true),LOGGER_DATA);
logger('get_atom_elements: ' . print_r($res,true),LOGGER_DATA);
logger('get_atom_elements: author: ' . print_r($arr['author'],true),LOGGER_DATA);
return $res;
logger('get_atom_elements: ' . print_r($arr['result'],true),LOGGER_DATA);
return $arr['result'];
}
function encode_rel_links($links) {
@@ -718,7 +732,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
foreach($del_entries as $dentry) {
$deleted = false;
if(isset($dentry['attribs']['']['ref'])) {
$mid = $dentry['attribs']['']['ref'];
$mid = normalise_id($dentry['attribs']['']['ref']);
$deleted = true;
if(isset($dentry['attribs']['']['when'])) {
$when = $dentry['attribs']['']['when'];
@@ -730,7 +744,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
if($deleted && is_array($contact)) {
$r = q("SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1",
dbesc(base64url_encode($mid)),
dbesc($mid),
dbesc($contact['xchan_hash']),
intval($importer['channel_id'])
);
@@ -739,7 +753,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
$item = $r[0];
if(! intval($item['item_deleted'])) {
logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG);
logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . $item['mid'], LOGGER_DEBUG);
drop_item($item['id'],false);
}
}
@@ -758,14 +772,14 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
foreach($items as $item) {
$is_reply = false;
$item_id = base64url_encode($item->get_id());
$item_id = normalise_id($item->get_id());
logger('consume_feed: processing ' . $item_id, LOGGER_DEBUG);
logger('consume_feed: processing ' . $raw_item_id, LOGGER_DEBUG);
$rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to');
if(isset($rawthread[0]['attribs']['']['ref'])) {
$is_reply = true;
$parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']);
$parent_mid = normalise_id($rawthread[0]['attribs']['']['ref']);
}
if($is_reply) {
@@ -775,7 +789,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Have we seen it? If not, import it.
$item_id = base64url_encode($item->get_id());
$item_id = normalise_id($item->get_id());
$author = array();
$datarray = get_atom_elements($feed,$item,$author);
@@ -824,7 +838,16 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
continue;
}
$x = q("select mid from item where mid = '%s' and uid = %d limit 1",
dbesc($parent_mid),
intval($importer['channel_id'])
);
if($x)
$parent_mid = $x[0]['mid'];
$datarray['parent_mid'] = $parent_mid;
$datarray['aid'] = $importer['channel_account_id'];
$datarray['uid'] = $importer['channel_id'];
@@ -838,7 +861,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
// Head post of a conversation. Have we seen it? If not, import it.
$item_id = base64url_encode($item->get_id());
$item_id = normalise_id($item->get_id());
$author = array();
$datarray = get_atom_elements($feed,$item,$author);
@@ -943,6 +966,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
}
function normalise_id($id) {
return str_replace('X-ZOT:','',$id);
}
/**
* @brief Process atom feed and return the first post and structure
*
@@ -983,14 +1011,14 @@ function process_salmon_feed($xml, $importer) {
foreach($items as $item) {
$item_id = base64url_encode($item->get_id());
$item_id = normalise_id($item->get_id());
logger('processing ' . $item_id, LOGGER_DEBUG);
$rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to');
if(isset($rawthread[0]['attribs']['']['ref'])) {
$is_reply = true;
$parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']);
$parent_mid = normalise_id($rawthread[0]['attribs']['']['ref']);
}
if($is_reply)
@@ -1159,7 +1187,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
if(($item['parent'] != $item['id']) || ($item['parent_mid'] !== $item['mid']) || (($item['thr_parent'] !== '') && ($item['thr_parent'] !== $item['mid']))) {
$parent_item = (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']);
$o .= '<thr:in-reply-to ref="' . z_root() . '/display/' . xmlify($parent_item) . '" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n";
$o .= '<thr:in-reply-to ref="' . 'X-ZOT:' . xmlify($parent_item) . '" type="text/html" href="' . xmlify($item['plink']) . '" />' . "\r\n";
}
if(activity_match($item['obj_type'],ACTIVITY_OBJ_EVENT) && activity_match($item['verb'],ACTIVITY_POST)) {
@@ -1177,7 +1206,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
$o .= '<content type="' . $type . '" >' . xmlify(prepare_text($body,$item['mimetype'])) . '</content>' . "\r\n";
}
$o .= '<id>' . z_root() . '/display/' . xmlify($item['mid']) . '</id>' . "\r\n";
$o .= '<id>' . 'X-ZOT:' . xmlify($item['mid']) . '</id>' . "\r\n";
$o .= '<published>' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '</published>' . "\r\n";
$o .= '<updated>' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '</updated>' . "\r\n";
@@ -1206,26 +1235,68 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
if(strlen($actarg))
$o .= $actarg;
// FIXME
// $tags = item_getfeedtags($item);
// if(count($tags)) {
// foreach($tags as $t) {
// $o .= '<category scheme="X-DFRN:' . xmlify($t[0]) . ':' . xmlify($t[1]) . '" term="' . xmlify($t[2]) . '" />' . "\r\n";
// }
// }
// FIXME
// $o .= item_getfeedattach($item);
if($item['attach']) {
$enclosures = json_decode($item['attach'],true);
if($enclosures) {
foreach($enclosures as $enc) {
$o .= '<link rel="enclosure" '
. (($enc['href']) ? 'href="' . $enc['href'] . '" ' : '')
. (($enc['length']) ? 'length="' . $enc['length'] . '" ' : '')
. (($enc['type']) ? 'type="' . $enc['type'] . '" ' : '')
. ' />';
}
}
}
// $mentioned = get_mentions($item,$tags);
// if($mentioned)
// $o .= $mentioned;
if($item['term']) {
foreach($item['term'] as $term) {
$scheme = '';
$label = '';
switch($term['ttype']) {
case TERM_UNKNOWN:
$scheme = NAMESPACE_ZOT . '/term/unknown';
$label = $term['term'];
break;
case TERM_HASHTAG:
case TERM_COMMUNITYTAG:
$scheme = NAMESPACE_ZOT . '/term/hashtag';
$label = '#' . $term['term'];
break;
case TERM_MENTION:
$scheme = NAMESPACE_ZOT . '/term/mention';
$label = '@' . $term['term'];
break;
case TERM_CATEGORY:
$scheme = NAMESPACE_ZOT . '/term/category';
$label = $term['term'];
break;
default:
break;
}
if(! $scheme)
continue;
call_hooks('atom_entry', $o);
$o .= '<category scheme="' . $scheme . '" term="' . $term['term'] . '" label="' . $label . '" />' . "\r\n";
}
}
$o .= '</entry>' . "\r\n";
return $o;
$x = [
'item' => $item,
'type' => $type,
'author' => $author,
'owner' => $owner,
'comment' => $comment,
'abook_id' => $cid,
'entry' => $o
];
call_hooks('atom_entry', $x);
return $x['entry'];
}
+26 -50
View File
@@ -13,12 +13,11 @@ require_once('include/zot.php');
function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) {
$result = [ 'success' => false, 'message' => '' ];
$result = array('success' => false,'message' => '');
$is_red = false;
$is_http = ((strpos($url,'://') !== false) ? true : false);
$my_perms = false;
$is_zot = false;
$is_http = ((strpos($url,'://') !== false) ? true : false);
if($is_http && substr($url,-1,1) === '/')
$url = substr($url,0,-1);
@@ -58,20 +57,14 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
$ret = Zotlabs\Zot\Finger::run($url,$channel);
if($ret && is_array($ret) && $ret['success']) {
$is_red = true;
$is_zot = true;
$j = $ret;
}
$my_perms = get_channel_default_perms($uid);
$p = \Zotlabs\Access\Permissions::connect_perms($uid);
$my_perms = $p['perms'];
$role = get_pconfig($uid,'system','permissions_role');
if($role) {
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
if($x['perms_connect'])
$my_perms = $x['perms_connect'];
}
if($is_red && $j) {
if($is_zot && $j) {
logger('follow: ' . $url . ' ' . print_r($j,true), LOGGER_DEBUG);
@@ -166,14 +159,13 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
}
if(! $xchan_hash) {
$result['message'] = t('Channel discovery failed.');
logger('follow: ' . $result['message']);
return $result;
}
$allowed = (($is_red || $r[0]['xchan_network'] === 'rss') ? 1 : 0);
$allowed = (($is_zot || $r[0]['xchan_network'] === 'rss') ? 1 : 0);
$x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0);
@@ -211,7 +203,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
return $result;
}
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook where abook_xchan = '%s' and abook_channel = %d limit 1",
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
where abook_xchan = '%s' and abook_channel = %d limit 1",
dbesc($xchan_hash),
intval($uid)
);
@@ -226,6 +219,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
}
if($r) {
$abook_instance = $r[0]['abook_instance'];
if(($singleton) && strpos($abook_instance,z_root()) === false) {
@@ -240,21 +234,6 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
);
if(intval($r[0]['abook_pending'])) {
$abook_my_perms = get_channel_default_perms($uid);
$role = get_pconfig($uid,'system','permissions_role');
if($role) {
$x = \Zotlabs\Access\PermissionRoles::role_perms($role);
if($x['perms_connect']) {
$abook_my_perms = $x['perms_connect'];
}
}
$filled_perms = \Zotlabs\Access\Permissions::FilledPerms($abook_my_perms);
foreach($filled_perms as $k => $v) {
set_abconfig($uid,$r[0]['abook_xchan'],'my_perms',$k,$v);
}
$x = q("update abook set abook_pending = 0 where abook_id = %d",
intval($r[0]['abook_id'])
);
@@ -265,29 +244,26 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
if($closeness === false)
$closeness = 80;
$r = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_feed, abook_created, abook_updated, abook_instance )
values( %d, %d, %d, '%s', %d, '%s', '%s', '%s' ) ",
intval($aid),
intval($uid),
intval($closeness),
dbesc($xchan_hash),
intval(($is_http) ? 1 : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(($singleton) ? z_root() : '')
$r = abook_store_lowlevel(
[
'abook_account' => intval($aid),
'abook_channel' => intval($uid),
'abook_closeness' => intval($closeness),
'abook_xchan' => $xchan_hash,
'abook_feed' => intval(($is_http) ? 1 : 0),
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_instance' => (($singleton) ? z_root() : '')
]
);
}
if(! $r)
logger('mod_follow: abook creation failed');
$all_perms = \Zotlabs\Access\Permissions::Perms();
if($all_perms) {
foreach($all_perms as $k => $v) {
if(in_array($k,$my_perms))
set_abconfig($uid,$xchan_hash,'my_perms',$k,1);
else
set_abconfig($uid,$xchan_hash,'my_perms',$k,0);
if($my_perms) {
foreach($my_perms as $k => $v) {
set_abconfig($uid,$xchan_hash,'my_perms',$k,$v);
}
}
+57 -11
View File
@@ -227,6 +227,26 @@ function group_get_members_xchan($gid) {
return $ret;
}
function group_get_profile_members_xchan($uid,$gid) {
$ret = [];
if(intval($gid)) {
$r = q("SELECT abook_xchan as xchan from abook left join profile on abook_profile = profile_guid where profile.id = %d and profile.uid = %d",
intval($gid),
intval($uid)
);
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
return $ret;
}
function mini_group_select($uid,$group = '') {
$grps = array();
@@ -320,20 +340,46 @@ function group_side($every="connections",$each="group",$edit = false, $group_id
return $o;
}
function expand_groups($a) {
if(! (is_array($a) && count($a)))
function expand_groups($g) {
if(! (is_array($g) && count($g)))
return array();
$x = $a;
stringify_array_elms($x,true);
$groups = implode(',', $x);
if($groups)
$r = q("SELECT xchan FROM group_member WHERE gid IN ( select id from groups where hash in ( $groups ))");
$ret = array();
$ret = [];
$x = [];
if($r)
foreach($r as $rr)
$ret[] = $rr['xchan'];
// private profile linked virtual groups
foreach($g as $gv) {
if(substr($gv,0,3) === 'vp.') {
$profile_hash = substr($gv,3);
if($profile_hash) {
$r = q("select abook_xchan from abook where abook_profile = '%s'",
dbesc($profile_hash)
);
if($r) {
foreach($r as $rv) {
$ret[] = $rv['abook_xchan'];
}
}
}
}
else {
$x[] = $gv;
}
}
if($x) {
stringify_array_elms($x,true);
$groups = implode(',', $x);
if($groups) {
$r = q("SELECT xchan FROM group_member WHERE gid IN ( select id from groups where hash in ( $groups ))");
if($r) {
foreach($r as $rr) {
$ret[] = $rr['xchan'];
}
}
}
}
return $ret;
}
+2 -2
View File
@@ -79,7 +79,7 @@ function get_help_content($tocpath = false) {
}
if($doctype === 'bbcode') {
require_once('include/bbcode.php');
$content = bbcode($text);
$content = zidify_links(bbcode($text));
// bbcode retargets external content to new windows. This content is internal.
$content = str_replace(' target="_blank"', '', $content);
}
@@ -95,7 +95,7 @@ function preg_callback_help_include($matches) {
$include = str_replace($matches[0],load_doc_file($matches[1]),$matches[0]);
if(preg_match('/\.bb$/', $matches[1]) || preg_match('/\.txt$/', $matches[1])) {
require_once('include/bbcode.php');
$include = bbcode($include);
$include = zidify_links(bbcode($include));
$include = str_replace(' target="_blank"','',$include);
}
elseif(preg_match('/\.md$/', $matches[1])) {
+1 -1
View File
@@ -113,7 +113,7 @@ function html2plain($html, $wraplength = 75, $compact = false)
$xpath = new DomXPath($doc);
$list = $xpath->query("//pre");
foreach ($list as $node) {
$node->nodeValue = str_replace("\n", "\r", $node->nodeValue);
$node->nodeValue = str_replace("\n", "\r", htmlspecialchars($node->nodeValue));
}
$message = $doc->saveHTML();
+31 -96
View File
@@ -1,5 +1,36 @@
<?php /** @file */
function hubloc_store_lowlevel($arr) {
$store = [
'hubloc_guid' => ((array_key_exists('hubloc_guid',$arr)) ? $arr['hubloc_guid'] : ''),
'hubloc_guid_sig' => ((array_key_exists('hubloc_guid_sig',$arr)) ? $arr['hubloc_guid_sig'] : ''),
'hubloc_hash' => ((array_key_exists('hubloc_hash',$arr)) ? $arr['hubloc_hash'] : ''),
'hubloc_addr' => ((array_key_exists('hubloc_addr',$arr)) ? $arr['hubloc_addr'] : ''),
'hubloc_network' => ((array_key_exists('hubloc_network',$arr)) ? $arr['hubloc_network'] : ''),
'hubloc_flags' => ((array_key_exists('hubloc_flags',$arr)) ? $arr['hubloc_flags'] : 0),
'hubloc_status' => ((array_key_exists('hubloc_status',$arr)) ? $arr['hubloc_status'] : 0),
'hubloc_url' => ((array_key_exists('hubloc_url',$arr)) ? $arr['hubloc_url'] : ''),
'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig',$arr)) ? $arr['hubloc_url_sig'] : ''),
'hubloc_host' => ((array_key_exists('hubloc_host',$arr)) ? $arr['hubloc_host'] : ''),
'hubloc_callback' => ((array_key_exists('hubloc_callback',$arr)) ? $arr['hubloc_callback'] : ''),
'hubloc_connect' => ((array_key_exists('hubloc_connect',$arr)) ? $arr['hubloc_connect'] : ''),
'hubloc_sitekey' => ((array_key_exists('hubloc_sitekey',$arr)) ? $arr['hubloc_sitekey'] : ''),
'hubloc_updated' => ((array_key_exists('hubloc_updated',$arr)) ? $arr['hubloc_updated'] : NULL_DATE),
'hubloc_connected' => ((array_key_exists('hubloc_connected',$arr)) ? $arr['hubloc_connected'] : NULL_DATE),
'hubloc_primary' => ((array_key_exists('hubloc_primary',$arr)) ? $arr['hubloc_primary'] : 0),
'hubloc_orphancheck' => ((array_key_exists('hubloc_orphancheck',$arr)) ? $arr['hubloc_orphancheck'] : 0),
'hubloc_error' => ((array_key_exists('hubloc_error',$arr)) ? $arr['hubloc_error'] : 0),
'hubloc_deleted' => ((array_key_exists('hubloc_deleted',$arr)) ? $arr['hubloc_deleted'] : 0)
];
return create_table_from_array('hubloc',$store);
}
function prune_hub_reinstalls() {
$r = q("select site_url from site where site_type = %d",
@@ -176,102 +207,6 @@ function hubloc_mark_as_down($posturl) {
}
function xchan_store($arr) {
logger('xchan_store: ' . print_r($arr,true));
if(! $arr['hash'])
$arr['hash'] = $arr['guid'];
if(! $arr['hash'])
return false;
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['hash'])
);
if($r)
return true;
if(! $arr['network'])
$arr['network'] = 'unknown';
if(! $arr['name'])
$arr['name'] = 'unknown';
if(! $arr['url'])
$arr['url'] = z_root();
if(! $arr['photo'])
$arr['photo'] = z_root() . '/' . get_default_profile_photo();
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_instance_url, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s','%s',%d, %d, %d, %d, %d, %d, %d, '%s') ",
dbesc($arr['hash']),
dbesc($arr['guid']),
dbesc($arr['guid_sig']),
dbesc($arr['pubkey']),
dbesc($arr['address']),
dbesc($arr['url']),
dbesc($arr['connurl']),
dbesc($arr['follow']),
dbesc($arr['connpage']),
dbesc($arr['name']),
dbesc($arr['network']),
dbesc($arr['instance_url']),
intval($arr['hidden']),
intval($arr['orphan']),
intval($arr['censored']),
intval($arr['selfcensored']),
intval($arr['system']),
intval($arr['pubforum']),
intval($arr['deleted']),
dbesc(datetime_convert())
);
if(! $r)
return $r;
$photos = import_xchan_photo($arr['photo'],$arr['hash']);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($arr['hash'])
);
return $r;
}
function xchan_fetch($arr) {
$key = '';
if($arr['hash']) {
$key = 'xchan_hash';
$v = $arr['hash'];
}
elseif($arr['guid']) {
$key = 'xchan_guid';
$v = $arr['guid'];
}
elseif($arr['address']) {
$key = 'xchan_addr';
$v = $arr['address'];
}
if(! $key)
return false;
$r = q("select * from xchan where $key = '$v' limit 1");
if(! $r)
return false;
$ret = array();
foreach($r[0] as $k => $v) {
if($k === 'xchan_addr')
$ret['address'] = $v;
else
$ret[str_replace('xchan_','',$k)] = $v;
}
return $ret;
}
function ping_site($url) {
+379 -355
View File
@@ -156,7 +156,7 @@ function import_profiles($channel,$profiles) {
}
function import_hublocs($channel,$hublocs,$seize) {
function import_hublocs($channel,$hublocs,$seize,$moving = false) {
if($channel && $hublocs) {
foreach($hublocs as $hubloc) {
@@ -174,19 +174,32 @@ function import_hublocs($channel,$hublocs,$seize) {
$hubloc['hubloc_deleted'] = (($hubloc['hubloc_flags'] & 0x1000) ? 1 : 0);
}
if($moving && $hubloc['hubloc_hash'] === $channel['channel_hash'] && $hubloc['hubloc_url'] !== z_root()) {
$hubloc['hubloc_deleted'] = 1;
}
$arr = array(
'guid' => $hubloc['hubloc_guid'],
'guid_sig' => $hubloc['hubloc_guid_sig'],
'url' => $hubloc['hubloc_url'],
'url_sig' => $hubloc['hubloc_url_sig']
'url_sig' => $hubloc['hubloc_url_sig'],
'sitekey' => ((array_key_exists('hubloc_sitekey',$hubloc)) ? $hubloc['hubloc_sitekey'] : '')
);
if(($hubloc['hubloc_hash'] === $channel['channel_hash']) && intval($hubloc['hubloc_primary']) && ($seize))
$hubloc['hubloc_primary'] = 0;
if(! zot_gethub($arr)) {
if(($x = zot_gethub($arr,false)) === false) {
unset($hubloc['hubloc_id']);
create_table_from_array('hubloc',$hubloc);
}
else {
q("UPDATE hubloc set hubloc_primary = %d, hubloc_deleted = %d where hubloc_id = %d",
intval($hubloc['hubloc_primary']),
intval($hubloc['hubloc_deleted']),
intval($x['hubloc_id'])
);
}
}
}
}
@@ -1175,413 +1188,424 @@ function convert_oldfields(&$arr,$old,$new) {
}
function scan_webpage_elements($path, $type, $cloud = false) {
$channel = \App::get_channel();
$dirtoscan = $path;
switch ($type) {
case 'page':
$dirtoscan .= '/pages/';
$json_filename = 'page.json';
break;
case 'layout':
$dirtoscan .= '/layouts/';
$json_filename = 'layout.json';
break;
case 'block':
$dirtoscan .= '/blocks/';
$json_filename = 'block.json';
break;
default :
return array();
}
if($cloud) {
$dirtoscan = get_dirpath_by_cloudpath($channel, $dirtoscan);
}
$elements = [];
if (is_dir($dirtoscan)) {
$dirlist = scandir($dirtoscan);
if ($dirlist) {
foreach ($dirlist as $element) {
if ($element === '.' || $element === '..') {
continue;
$channel = \App::get_channel();
$dirtoscan = $path;
switch ($type) {
case 'page':
$dirtoscan .= '/pages/';
$json_filename = 'page.json';
break;
case 'layout':
$dirtoscan .= '/layouts/';
$json_filename = 'layout.json';
break;
case 'block':
$dirtoscan .= '/blocks/';
$json_filename = 'block.json';
break;
default :
return array();
}
if($cloud) {
$dirtoscan = get_dirpath_by_cloudpath($channel, $dirtoscan);
}
$elements = [];
if(is_dir($dirtoscan)) {
$dirlist = scandir($dirtoscan);
if($dirlist) {
foreach($dirlist as $element) {
if($element === '.' || $element === '..') {
continue;
}
$folder = $dirtoscan . '/' . $element;
if(is_dir($folder)) {
if($cloud) {
$jsonfilepath = $folder . '/' . get_filename_by_cloudname($json_filename, $channel, $folder);
}
$folder = $dirtoscan . '/' . $element;
if (is_dir($folder)) {
else {
$jsonfilepath = $folder . '/' . $json_filename;
}
if(is_file($jsonfilepath)) {
$metadata = json_decode(file_get_contents($jsonfilepath), true);
if($cloud) {
$jsonfilepath = $folder . '/' . get_filename_by_cloudname($json_filename, $channel, $folder);
} else {
$jsonfilepath = $folder . '/' . $json_filename;
$contentfilename = get_filename_by_cloudname($metadata['contentfile'], $channel, $folder);
$metadata['path'] = $folder . '/' . $contentfilename;
}
if (is_file($jsonfilepath)) {
$metadata = json_decode(file_get_contents($jsonfilepath), true);
if($cloud) {
$contentfilename = get_filename_by_cloudname($metadata['contentfile'], $channel, $folder);
$metadata['path'] = $folder . '/' . $contentfilename;
} else {
$contentfilename = $metadata['contentfile'];
$metadata['path'] = $folder . '/' . $contentfilename;
else {
$contentfilename = $metadata['contentfile'];
$metadata['path'] = $folder . '/' . $contentfilename;
}
if($metadata['contentfile'] === '') {
logger('Invalid ' . $type . ' content file');
return false;
}
$content = file_get_contents($folder . '/' . $contentfilename);
if(!$content) {
if(is_readable($folder . '/' . $contentfilename)) {
$content = '';
}
if ($metadata['contentfile'] === '') {
logger('Invalid ' . $type . ' content file');
else {
logger('Failed to get file content for ' . $metadata['contentfile']);
return false;
}
$content = file_get_contents($folder . '/' . $contentfilename);
if (!$content) {
if(is_readable($folder . '/' . $contentfilename)) {
$content = '';
} else {
logger('Failed to get file content for ' . $metadata['contentfile']);
return false;
}
}
$elements[] = $metadata;
}
$elements[] = $metadata;
}
}
}
}
return $elements;
}
return $elements;
}
function import_webpage_element($element, $channel, $type) {
function import_webpage_element($element, $channel, $type) {
$arr = array(); // construct information for the webpage element item table record
$arr = array(); // construct information for the webpage element item table record
switch ($type) {
//
// PAGES
//
case 'page':
$arr['item_type'] = ITEM_TYPE_WEBPAGE;
$namespace = 'WEBPAGE';
$name = $element['pagelink'];
if($name) {
require_once('library/urlify/URLify.php');
$name = strtolower(\URLify::transliterate($name));
}
$arr['title'] = $element['title'];
$arr['term'] = $element['term'];
$arr['layout_mid'] = ''; // by default there is no layout associated with the page
// If a layout was specified, find it in the database and get its info. If
// it does not exist, leave layout_mid empty
if($element['layout'] !== '') {
$liid = q("select iid from iconfig where k = 'PDL' and v = '%s' and cat = 'system'",
dbesc($element['layout'])
);
if($liid) {
$linfo = q("select mid from item where id = %d",
intval($liid[0]['iid'])
);
$arr['layout_mid'] = $linfo[0]['mid'];
}
}
break;
//
// LAYOUTS
//
case 'layout':
$arr['item_type'] = ITEM_TYPE_PDL;
$namespace = 'PDL';
$name = $element['name'];
$arr['title'] = $element['description'];
$arr['term'] = $element['term'];
break;
//
// BLOCKS
//
case 'block':
$arr['item_type'] = ITEM_TYPE_BLOCK;
$namespace = 'BUILDBLOCK';
$name = $element['name'];
$arr['title'] = $element['title'];
switch($type) {
//
// PAGES
//
case 'page':
$arr['item_type'] = ITEM_TYPE_WEBPAGE;
$namespace = 'WEBPAGE';
$name = $element['pagelink'];
if($name) {
require_once('library/urlify/URLify.php');
$name = strtolower(\URLify::transliterate($name));
}
$arr['title'] = $element['title'];
$arr['term'] = $element['term'];
$arr['layout_mid'] = ''; // by default there is no layout associated with the page
// If a layout was specified, find it in the database and get its info. If
// it does not exist, leave layout_mid empty
if($element['layout'] !== '') {
$liid = q("select iid from iconfig where k = 'PDL' and v = '%s' and cat = 'system'",
dbesc($element['layout'])
);
if($liid) {
$linfo = q("select mid from item where id = %d",
intval($liid[0]['iid'])
);
$arr['layout_mid'] = $linfo[0]['mid'];
}
}
break;
//
// LAYOUTS
//
case 'layout':
$arr['item_type'] = ITEM_TYPE_PDL;
$namespace = 'PDL';
$name = $element['name'];
$arr['title'] = $element['description'];
$arr['term'] = $element['term'];
break;
//
// BLOCKS
//
case 'block':
$arr['item_type'] = ITEM_TYPE_BLOCK;
$namespace = 'BUILDBLOCK';
$name = $element['name'];
$arr['title'] = $element['title'];
break;
default :
return null; // return null if invalid element type
}
break;
default :
return null; // return null if invalid element type
}
$arr['uid'] = $channel['channel_id'];
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = local_channel();
$arr['aid'] = $channel['channel_account_id'];
// Check if an item already exists based on the name
$iid = q("select iid from iconfig where k = '" . $namespace . "' and v = '%s' and cat = 'system'",
dbesc($name)
// Check if an item already exists based on the name
$iid = q("select iid from iconfig where k = '" . $namespace . "' and v = '%s' and cat = 'system'",
dbesc($name)
);
if($iid) { // If the item does exist, get the item metadata
$iteminfo = q("select mid,created,edited from item where id = %d",
intval($iid[0]['iid'])
);
if($iid) { // If the item does exist, get the item metadata
$iteminfo = q("select mid,created,edited from item where id = %d",
intval($iid[0]['iid'])
);
$arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid'];
$arr['created'] = $iteminfo[0]['created'];
} else { // otherwise, generate the creation times and unique id
$arr['created'] = datetime_convert('UTC', 'UTC');
$arr['mid'] = $arr['parent_mid'] = item_message_id();
}
// Update the edited time whether or not the element already exists
$arr['edited'] = datetime_convert('UTC', 'UTC');
// Import the actual element content
$arr['body'] = file_get_contents($element['path']);
// The element owner is the channel importing the elements
$arr['owner_xchan'] = get_observer_hash();
// The author is either the owner or whomever was specified
$arr['author_xchan'] = (($element['author_xchan']) ? $element['author_xchan'] : get_observer_hash());
// Import mimetype if it is a valid mimetype for the element
$mimetypes = [ 'text/bbcode',
'text/html',
'text/markdown',
'text/plain',
'application/x-pdl',
'application/x-php'
];
// Blocks and pages can have any of the valid mimetypes, but layouts must be text/bbcode
if((in_array($element['mimetype'], $mimetypes)) && ($type === 'page' || $type === 'block') ) {
$arr['mimetype'] = $element['mimetype'];
} else {
$arr['mimetype'] = 'text/bbcode';
}
$arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid'];
$arr['created'] = $iteminfo[0]['created'];
}
else { // otherwise, generate the creation times and unique id
$arr['created'] = datetime_convert('UTC', 'UTC');
$arr['mid'] = $arr['parent_mid'] = item_message_id();
}
// Update the edited time whether or not the element already exists
$arr['edited'] = datetime_convert('UTC', 'UTC');
// Import the actual element content
$arr['body'] = file_get_contents($element['path']);
// The element owner is the channel importing the elements
$arr['owner_xchan'] = get_observer_hash();
// The author is either the owner or whomever was specified
$arr['author_xchan'] = (($element['author_xchan']) ? $element['author_xchan'] : get_observer_hash());
// Import mimetype if it is a valid mimetype for the element
$mimetypes = [ 'text/bbcode',
'text/html',
'text/markdown',
'text/plain',
'application/x-pdl',
'application/x-php'
];
// Blocks and pages can have any of the valid mimetypes, but layouts must be text/bbcode
if((in_array($element['mimetype'], $mimetypes)) && ($type === 'page' || $type === 'block') ) {
$arr['mimetype'] = $element['mimetype'];
}
else {
$arr['mimetype'] = 'text/bbcode';
}
// Verify ability to use html or php!!!
$execflag = false;
if ($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') {
$z = q("select account_id, account_roles, channel_pageflags from account "
. "left join channel on channel_account_id = account_id where channel_id = %d limit 1",
intval(local_channel())
);
if ($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
$execflag = true;
} else {
logger('Unable to import element "' . $name .'" because AllowCode permission is denied.');
notice( t('Unable to import element "' . $name .'" because AllowCode permission is denied.') . EOL);
$element['import_success'] = 0;
return $element;
}
}
$z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'system' limit 1",
dbesc($name),
dbesc($namespace)
);
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
// Verify ability to use html or php!!!
$execflag = false;
if($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') {
$z = q("select account_id, account_roles, channel_pageflags from account "
. "left join channel on channel_account_id = account_id where channel_id = %d limit 1",
intval(local_channel())
);
$remote_id = 0;
if ($z && $i) {
$remote_id = $z[0]['id'];
$arr['id'] = $i[0]['id'];
// don't update if it has the same timestamp as the original
if ($arr['edited'] > $i[0]['edited'])
$x = item_store_update($arr, $execflag);
} else {
if (($i) && (intval($i[0]['item_deleted']))) {
// was partially deleted already, finish it off
q("delete from item where mid = '%s' and uid = %d",
dbesc($arr['mid']),
intval(local_channel())
);
}
$x = item_store($arr, $execflag);
if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
$execflag = true;
}
if ($x['success']) {
$item_id = $x['item_id'];
update_remote_id($channel, $item_id, $arr['item_type'], $name, $namespace, $remote_id, $arr['mid']);
$element['import_success'] = 1;
} else {
$element['import_success'] = 0;
else {
logger('Unable to import element "' . $name .'" because AllowCode permission is denied.');
notice( t('Unable to import element "' . $name .'" because AllowCode permission is denied.') . EOL);
$element['import_success'] = 0;
return $element;
}
}
return $element;
// $z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'system' limit 1",
// dbesc($name),
// dbesc($namespace)
// );
$i = q("select id, edited, item_deleted from item where mid = '%s' and uid = %d limit 1",
dbesc($arr['mid']),
intval(local_channel())
);
\Zotlabs\Lib\IConfig::Set($arr,'system',$namespace,(($name) ? $name : substr($arr['mid'],0,16)),true);
if($i) {
$arr['id'] = $i[0]['id'];
// don't update if it has the same timestamp as the original
if($arr['edited'] > $i[0]['edited'])
$x = item_store_update($arr,$execflag);
}
else {
if(($i) && (intval($i[0]['item_deleted']))) {
// was partially deleted already, finish it off
q("delete from item where mid = '%s' and uid = %d",
dbesc($arr['mid']),
intval(local_channel())
);
}
else
$x = item_store($arr,$execflag);
}
if($x && $x['success']) {
$item_id = $x['item_id'];
//update_remote_id($channel, $item_id, $arr['item_type'], $name, $namespace, $remote_id, $arr['mid']);
$element['import_success'] = 1;
}
else {
$element['import_success'] = 0;
}
return $element;
}
function get_webpage_elements($channel, $type = 'all') {
$elements = array();
if(!$channel['channel_id']) {
return null;
}
switch ($type) {
case 'all':
// If all, execute all the pages, layouts, blocks case statements
case 'pages':
$elements['pages'] = null;
$owner = $channel['channel_id'];
$elements = array();
if(!$channel['channel_id']) {
return null;
}
switch($type) {
case 'all':
// If all, execute all the pages, layouts, blocks case statements
case 'pages':
$elements['pages'] = null;
$owner = $channel['channel_id'];
$sql_extra = item_permissions_sql($owner);
$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",
intval($owner),
intval(ITEM_TYPE_WEBPAGE)
);
$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",
intval($owner),
intval(ITEM_TYPE_WEBPAGE)
);
$pages = null;
$pages = null;
if($r) {
$elements['pages'] = array();
$pages = array();
foreach($r as $rr) {
unobscure($rr);
if($r) {
$elements['pages'] = array();
$pages = array();
foreach($r as $rr) {
unobscure($rr);
//$lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock');
//$lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock');
$element_arr = array(
'type' => 'webpage',
'title' => $rr['title'],
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'pagetitle' => $rr['v'],
'mid' => $rr['mid'],
'layout_mid' => $rr['layout_mid']
);
$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']),
'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]',
//'lockstate' => $lockstate
);
$elements['pages'][] = $element_arr;
}
$element_arr = array(
'type' => 'webpage',
'title' => $rr['title'],
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'pagetitle' => $rr['v'],
'mid' => $rr['mid'],
'layout_mid' => $rr['layout_mid']
);
$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']),
'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]',
//'lockstate' => $lockstate
);
$elements['pages'][] = $element_arr;
}
}
if($type !== 'all') {
break;
}
}
if($type !== 'all') {
break;
}
case 'layouts':
$elements['layouts'] = null;
$owner = $channel['channel_id'];
case 'layouts':
$elements['layouts'] = null;
$owner = $channel['channel_id'];
$sql_extra = item_permissions_sql($owner);
$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 = 'PDL' and item_type = %d
$sql_extra order by item.created desc",
intval($owner),
intval(ITEM_TYPE_PDL)
);
$r = q("select * from iconfig left join item on iconfig.iid = item.id
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d
$sql_extra order by item.created desc",
intval($owner),
intval(ITEM_TYPE_PDL)
);
$layouts = null;
$layouts = null;
if($r) {
$elements['layouts'] = array();
$layouts = array();
foreach($r as $rr) {
unobscure($rr);
if($r) {
$elements['layouts'] = array();
$layouts = array();
foreach($r as $rr) {
unobscure($rr);
$elements['layouts'][] = array(
'type' => 'layout',
'description' => $rr['title'], // description of the layout
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'name' => $rr['v'], // name of reference for the layout
'mid' => $rr['mid'],
);
}
$elements['layouts'][] = array(
'type' => 'layout',
'description' => $rr['title'], // description of the layout
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'name' => $rr['v'], // name of reference for the layout
'mid' => $rr['mid'],
);
}
}
if($type !== 'all') {
break;
}
case 'blocks':
$elements['blocks'] = null;
$owner = $channel['channel_id'];
}
$sql_extra = item_permissions_sql($owner);
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
left join item on iconfig.iid = item.id
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
and item_type = %d order by item.created desc",
intval($owner),
intval(ITEM_TYPE_BLOCK)
);
if($type !== 'all') {
break;
}
case 'blocks':
$elements['blocks'] = null;
$owner = $channel['channel_id'];
$blocks = null;
if($r) {
$elements['blocks'] = array();
$blocks = array();
foreach($r as $rr) {
unobscure($rr);
$elements['blocks'][] = array(
'type' => 'block',
'title' => $rr['title'],
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'name' => $rr['v'],
'mid' => $rr['mid']
);
}
$sql_extra = item_permissions_sql($owner);
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
left join item on iconfig.iid = item.id
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
and item_type = %d order by item.created desc",
intval($owner),
intval(ITEM_TYPE_BLOCK)
);
}
$blocks = null;
if($r) {
$elements['blocks'] = array();
$blocks = array();
foreach($r as $rr) {
unobscure($rr);
$elements['blocks'][] = array(
'type' => 'block',
'title' => $rr['title'],
'body' => $rr['body'],
'created' => $rr['created'],
'edited' => $rr['edited'],
'mimetype' => $rr['mimetype'],
'name' => $rr['v'],
'mid' => $rr['mid']
);
}
}
if($type !== 'all') {
break;
}
if($type !== 'all') {
break;
}
default:
break;
}
return $elements;
default:
break;
}
return $elements;
}
/* creates a compressed zip file */
function create_zip_file($files = array(), $destination = '', $overwrite = false) {
//if the zip file already exists and overwrite is false, return false
if (file_exists($destination) && !$overwrite) {
return false;
// if the zip file already exists and overwrite is false, return false
if(file_exists($destination) && !$overwrite) {
return false;
}
//vars
$valid_files = array();
// if files were passed in...
if(is_array($files)) {
// cycle through each file
foreach($files as $file) {
// make sure the file exists
if(file_exists($file)) {
$valid_files[] = $file;
}
}
//vars
$valid_files = array();
//if files were passed in...
if (is_array($files)) {
//cycle through each file
foreach ($files as $file) {
//make sure the file exists
if (file_exists($file)) {
$valid_files[] = $file;
}
}
}
}
//if we have good files...
if (count($valid_files)) {
//create the archive
$zip = new ZipArchive();
if ($zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}
//add the files
foreach ($valid_files as $file) {
$zip->addFile($file, $file);
}
//debug
//echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
//close the zip -- done!
$zip->close();
//check to make sure the file exists
return file_exists($destination);
} else {
return false;
// if we have good files...
if(count($valid_files)) {
//create the archive
$zip = new ZipArchive();
if($zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}
// add the files
foreach($valid_files as $file) {
$zip->addFile($file, $file);
}
//debug
//echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
//close the zip -- done!
$zip->close();
// check to make sure the file exists
return file_exists($destination);
}
else {
return false;
}
}
+71 -45
View File
@@ -302,7 +302,7 @@ function add_source_route($iid, $hash) {
* * \e boolean \b success true or false
* * \e array \b activity the resulting activity if successful
*/
function post_activity_item($arr) {
function post_activity_item($arr,$allow_code = false,$deliver = true) {
$ret = array('success' => false);
@@ -328,7 +328,8 @@ function post_activity_item($arr) {
return $ret;
}
$arr['public_policy'] = ((x($_REQUEST,'public_policy')) ? escape_tags($_REQUEST['public_policy']) : map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'),true));
$arr['public_policy'] = ((array_key_exists('public_policy',$arr)) ? escape_tags($arr['public_policy']) : map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'view_stream'),true));
if($arr['public_policy'])
$arr['item_private'] = 1;
@@ -359,15 +360,18 @@ function post_activity_item($arr) {
if(($is_comment) && ($arr['obj_type'] === ACTIVITY_OBJ_NOTE))
$arr['obj_type'] = ACTIVITY_OBJ_COMMENT;
$arr['allow_cid'] = ((x($arr,'allow_cid')) ? $arr['allow_cid'] : $channel['channel_allow_cid']);
$arr['allow_gid'] = ((x($arr,'allow_gid')) ? $arr['allow_gid'] : $channel['channel_allow_gid']);
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? $arr['deny_cid'] : $channel['channel_deny_cid']);
$arr['deny_gid'] = ((x($arr,'deny_gid')) ? $arr['deny_gid'] : $channel['channel_deny_gid']);
if(! ( array_key_exists('allow_cid',$arr) || array_key_exists('allow_gid',$arr)
|| array_key_exists('deny_cid',$arr) || array_key_exists('deny_gid',$arr))) {
$arr['allow_cid'] = $channel['channel_allow_cid'];
$arr['allow_gid'] = $channel['channel_allow_gid'];
$arr['deny_cid'] = $channel['channel_deny_cid'];
$arr['deny_gid'] = $channel['channel_deny_gid'];
}
$arr['comment_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'));
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
}
@@ -382,18 +386,22 @@ function post_activity_item($arr) {
return $ret;
}
$post = item_store($arr);
if($post['success'])
$post_id = $post['item_id'];
$post = item_store($arr,$allow_code,$deliver);
if($post_id) {
$arr['id'] = $post_id;
call_hooks('post_local_end', $arr);
Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$post_id));
if($post['success']) {
$post_id = $post['item_id'];
$ret['success'] = true;
$ret['item_id'] = $post_id;
$ret['activity'] = $post['item'];
call_hooks('post_local_end', $ret['activity']);
}
if($post_id && $deliver) {
Zotlabs\Daemon\Master::Summon(array('Notifier','activity',$post_id));
}
$ret['success'] = true;
return $ret;
}
@@ -420,7 +428,7 @@ function validate_item_elements($message,$arr) {
/**
* @brief Limit lenght on imported system messages.
* @brief Limit length on imported system messages.
*
* The purpose of this function is to apply system message length limits to
* imported messages without including any embedded photos in the length.
@@ -829,13 +837,15 @@ function import_author_rss($x) {
}
$name = trim($x['name']);
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_url, xchan_name, xchan_network )
values ( '%s', '%s', '%s', '%s', '%s' )",
dbesc($x['guid']),
dbesc($x['guid']),
dbesc($x['url']),
dbesc(($name) ? $name : t('(Unknown)')),
dbesc('rss')
$r = xchan_store_lowlevel(
[
'xchan_hash' => $x['guid'],
'xchan_guid' => $x['guid'],
'xchan_url' => $x['url'],
'xchan_name' => (($name) ? $name : t('(Unknown)')),
'xchan_name_date' => datetime_convert(),
'xchan_network' => 'rss'
]
);
if($r && $x['photo']) {
@@ -874,14 +884,17 @@ function import_author_unknown($x) {
$name = trim($x['name']);
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_url, xchan_name, xchan_network )
values ( '%s', '%s', '%s', '%s', '%s' )",
dbesc($x['url']),
dbesc($x['url']),
dbesc($x['url']),
dbesc(($name) ? $name : t('(Unknown)')),
dbesc('unknown')
$r = xchan_store_lowlevel(
[
'xchan_hash' => $x['url'],
'xchan_guid' => $x['url'],
'xchan_url' => $x['url'],
'xchan_name' => (($name) ? $name : t('(Unknown)')),
'xchan_name_date' => datetime_convert(),
'xchan_network' => 'unknown'
]
);
if($r && $x['photo']) {
$photos = import_xchan_photo($x['photo']['src'],$x['url']);
@@ -1512,6 +1525,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : '');
$arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : '');
$arr['postopts'] = ((x($arr,'postopts')) ? trim($arr['postopts']) : '');
$arr['route'] = ((x($arr,'route')) ? trim($arr['route']) : '');
$arr['item_private'] = ((x($arr,'item_private')) ? intval($arr['item_private']) : 0 );
$arr['item_wall'] = ((x($arr,'item_wall')) ? intval($arr['item_wall']) : 0 );
$arr['item_type'] = ((x($arr,'item_type')) ? intval($arr['item_type']) : 0 );
@@ -1528,7 +1542,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// apply the input filter here - if it is obscured it has been filtered already
$arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
if(local_channel() && (! $arr['sig'])) {
if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
@@ -1565,8 +1579,11 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['attach'] = json_encode($arr['attach']);
}
$arr['aid'] = ((x($arr,'aid')) ? intval($arr['aid']) : 0);
$arr['mid'] = ((x($arr,'mid')) ? notags(trim($arr['mid'])) : random_string());
$arr['aid'] = ((x($arr,'aid')) ? intval($arr['aid']) : 0);
$arr['mid'] = ((x($arr,'mid')) ? notags(trim($arr['mid'])) : random_string());
$arr['revision'] = ((x($arr,'revision') && intval($arr['revision']) > 0) ? intval($arr['revision']) : 0);
logger('revision: ' . $arr['revision']);
$arr['author_xchan'] = ((x($arr,'author_xchan')) ? notags(trim($arr['author_xchan'])) : '');
$arr['owner_xchan'] = ((x($arr,'owner_xchan')) ? notags(trim($arr['owner_xchan'])) : '');
$arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert());
@@ -1622,7 +1639,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if($d2 > $d1)
$arr['item_delayed'] = 1;
$arr['llink'] = z_root() . '/display/' . $arr['mid'];
$arr['llink'] = z_root() . '/display/' . gen_link_id($arr['mid']);
if(! $arr['plink'])
$arr['plink'] = $arr['llink'];
@@ -1727,9 +1744,10 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
if($parent_deleted)
$arr['item_deleted'] = 1;
$r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d LIMIT 1",
$r = q("SELECT id FROM item WHERE mid = '%s' AND uid = %d and revision = %d LIMIT 1",
dbesc($arr['mid']),
intval($arr['uid'])
intval($arr['uid']),
intval($arr['revision'])
);
if($r) {
logger('item_store: duplicate item ignored. ' . print_r($arr,true));
@@ -1784,9 +1802,10 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
// find the item we just created
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d ORDER BY id ASC ",
$r = q("SELECT * FROM item WHERE mid = '%s' AND uid = %d and revision = %d ORDER BY id ASC ",
$arr['mid'], // already dbesc'd
intval($arr['uid'])
intval($arr['uid']),
intval($arr['revision'])
);
if($r && count($r)) {
@@ -1945,7 +1964,7 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
// apply the input filter here - if it is obscured it has been filtered already
$arr['body'] = trim(z_input_filter($arr['uid'],$arr['body'],$arr['mimetype']));
if(local_channel() && (! $arr['sig'])) {
if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
@@ -1997,6 +2016,8 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
$arr['edited'] = ((x($arr,'edited') !== false) ? datetime_convert('UTC','UTC',$arr['edited']) : datetime_convert());
$arr['expires'] = ((x($arr,'expires') !== false) ? datetime_convert('UTC','UTC',$arr['expires']) : $orig[0]['expires']);
$arr['revision'] = ((x($arr,'revision') && $arr['revision'] > 0) ? intval($arr['revision']) : 0);
if(array_key_exists('comments_closed',$arr) && $arr['comments_closed'] > NULL_DATE)
$arr['comments_closed'] = datetime_convert('UTC','UTC',$arr['comments_closed']);
else
@@ -2174,7 +2195,7 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id,
// since Diaspora doesn't handle edits we can only do this for the original text and not update it.
require_once('include/bb2diaspora.php');
require_once('include/markdown.php');
$signed_body = bb2diaspora_itembody($datarray,$walltowall);
if($walltowall) {
@@ -2273,7 +2294,7 @@ function send_status_notifications($post_id,$item) {
if($unfollowed)
return;
$link = z_root() . '/display/' . $item['mid'];
$link = z_root() . '/display/' . gen_link_id($item['mid']);
$y = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($link),
@@ -3300,7 +3321,7 @@ function retain_item($id) {
);
}
function drop_items($items) {
function drop_items($items,$interactive = false,$stage = DROPITEM_NORMAL,$force = false) {
$uid = 0;
if(! local_channel() && ! remote_channel())
@@ -3308,7 +3329,7 @@ function drop_items($items) {
if(count($items)) {
foreach($items as $item) {
$owner = drop_item($item,false);
$owner = drop_item($item,$interactive,$stage,$force);
if($owner && ! $uid)
$uid = $owner;
}
@@ -3332,6 +3353,11 @@ function drop_items($items) {
function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = false) {
// These resource types have linked items that should only be removed at the same time
// as the linked resource; if we encounter one set it to item_hidden rather than item_deleted.
$linked_resource_types = [ 'photo' ];
// locate item to be deleted
$r = q("SELECT * FROM item WHERE id = %d LIMIT 1",
@@ -3347,7 +3373,7 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = fal
$item = $r[0];
$linked_item = (($item['resource_id']) ? true : false);
$linked_item = (($item['resource_id'] && $item['resource_type'] && in_array($item['resource_type'], $linked_resource_types)) ? true : false);
$ok_to_delete = false;
@@ -4464,9 +4490,9 @@ function item_create_edit_activity($post) {
$new_item['verb'] = ACTIVITY_UPDATE;
$new_item['item_thread_top'] = 0;
$new_item['created'] = $new_item['edited'] = datetime_convert();
$new_item['obj_type'] = (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT);
$new_item['obj'] = json_encode(array(
'type' => (($update_item['item_thread_top']) ? ACTIVITY_OBJ_NOTE : ACTIVITY_OBJ_COMMENT),
'type' => $new_item['obj_type'],
'id' => $update_item['mid'],
'parent' => $update_item['parent_mid'],
'link' => array(array('rel' => 'alternate','type' => 'text/html', 'href' => $update_item['plink'])),
@@ -1,6 +1,6 @@
<?php
/**
* @file include/bb2diaspora.php
* @file include/markdown.php
* @brief Some functions for BB conversions for Diaspora protocol.
*/
@@ -110,6 +110,39 @@ function diaspora_mention_callback($matches) {
}
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
@@ -128,6 +161,11 @@ function markdown_to_bb($s, $use_zrl = false) {
$s = str_replace("&#xD;","\r",$s);
$s = str_replace("&#xD;\n&gt;","",$s);
if(is_array($s)) {
btlogger('markdown_to_bb called with array. ' . print_r($s,true), LOGGER_NORMAL, LOG_WARNING);
return '';
}
$s = html_entity_decode($s,ENT_COMPAT,'UTF-8');
// if empty link text replace with the url
@@ -136,9 +174,11 @@ function markdown_to_bb($s, $use_zrl = false) {
// first try plustags
$s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s);
$s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}/','diaspora_mention_callback',$s);
$s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}\+/','diaspora_mention_callback2',$s);
$s = preg_replace_callback('/\@\{(.+?)\@(.+?)\}/','diaspora_mention_callback2',$s);
// Escaping the hash tags - doesn't always seem to work
// $s = preg_replace('/\#([^\s\#])/','\\#$1',$s);
// This seems to work
+1 -1
View File
@@ -102,7 +102,7 @@ function menu_render($menu, $class='', $edit = false, $var = array()) {
if($menu['items'][$x]['mitem_flags'] & MENU_ITEM_NEWWIN)
$menu['items'][$x]['newwin'] = '1';
$menu['items'][$x]['mitem_desc'] = bbcode($menu['items'][$x]['mitem_desc']);
$menu['items'][$x]['mitem_desc'] = zidify_links(smilies(bbcode($menu['items'][$x]['mitem_desc'])));
}
$wrap = (($var['wrap'] === 'none') ? false : true);
+41 -39
View File
@@ -8,7 +8,7 @@ require_once('include/attach.php');
// send a private message
function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='',$expires = ''){
function send_message($uid = 0, $recipient = '', $body = '', $subject = '', $replyto = '', $expires = NULL_DATE) {
$ret = array('success' => false);
$is_reply = false;
@@ -16,19 +16,6 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$a = get_app();
$observer_hash = get_observer_hash();
if(! $recipient) {
$ret['message'] = t('No recipient provided.');
return $ret;
}
if(! strlen($subject))
$subject = t('[no subject]');
// if(! $expires)
// $expires = NULL_DATE;
// else
// $expires = datetime_convert(date_default_timezone_get(),'UTC',$expires);
if($uid) {
$r = q("select * from channel where channel_id = %d limit 1",
@@ -47,6 +34,46 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
}
$body = cleanup_bbcode($body);
$results = linkify_tags($a, $body, $uid);
if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match))
$attaches = $match[1];
$attachments = '';
if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
$attachments = array();
foreach($match[2] as $mtch) {
$hash = substr($mtch,0,strpos($mtch,','));
$rev = intval(substr($mtch,strpos($mtch,',')));
$r = attach_by_hash_nodata($hash,get_observer_hash(),$rev);
if($r['success']) {
$attachments[] = array(
'href' => z_root() . '/attach/' . $r['data']['hash'],
'length' => $r['data']['filesize'],
'type' => $r['data']['filetype'],
'title' => urlencode($r['data']['filename']),
'revision' => $r['data']['revision']
);
}
$body = trim(str_replace($match[1],'',$body));
}
}
$jattach = (($attachments) ? json_encode($attachments) : '');
if(! $recipient) {
$ret['message'] = t('No recipient provided.');
return $ret;
}
if(! strlen($subject))
$subject = t('[no subject]');
// look for any existing conversation structure
$conv_guid = '';
@@ -156,31 +183,6 @@ function send_message($uid = 0, $recipient='', $body='', $subject='', $replyto='
$match = false;
if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",((strpos($body,'[/crypt]')) ? $_POST['media_str'] : $body),$match))
$attaches = $match[1];
$attachments = '';
if(preg_match_all('/(\[attachment\](.*?)\[\/attachment\])/',$body,$match)) {
$attachments = array();
foreach($match[2] as $mtch) {
$hash = substr($mtch,0,strpos($mtch,','));
$rev = intval(substr($mtch,strpos($mtch,',')));
$r = attach_by_hash_nodata($hash,get_observer_hash(),$rev);
if($r['success']) {
$attachments[] = array(
'href' => z_root() . '/attach/' . $r['data']['hash'],
'length' => $r['data']['filesize'],
'type' => $r['data']['filetype'],
'title' => urlencode($r['data']['filename']),
'revision' => $r['data']['revision']
);
}
$body = trim(str_replace($match[1],'',$body));
}
}
$jattach = (($attachments) ? json_encode($attachments) : '');
if($subject)
$subject = str_rot47(base64url_encode($subject));
+80 -37
View File
@@ -1,6 +1,8 @@
<?php /** @file */
function nav(&$a) {
use \Zotlabs\Lib as Zlib;
function nav() {
/**
*
@@ -12,8 +14,8 @@ function nav(&$a) {
App::$page['nav'] = '';
$base = z_root();
App::$page['htmlhead'] .= <<< EOT
App::$page['htmlhead'] .= <<< EOT
<script>$(document).ready(function() {
$("#nav-search-text").search_autocomplete('$base/acl');
});
@@ -21,8 +23,6 @@ function nav(&$a) {
</script>
EOT;
if(local_channel()) {
$channel = App::get_channel();
$observer = App::get_observer();
@@ -76,6 +76,20 @@ EOT;
$userinfo = null;
$nav['loginmenu']=array();
if($observer) {
$userinfo = array(
'icon' => $observer['xchan_photo_m'],
'name' => $observer['xchan_addr'],
);
}
elseif(! $_SESSION['authenticated']) {
$nav['remote_login'] = remote_login();
$nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn');
}
if(local_channel()) {
@@ -85,34 +99,42 @@ EOT;
$nav['logout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn');
// user menu
$nav['usermenu'][] = Array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations'),'channel_nav_btn');
//$nav['usermenu'][] = Array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations'),'channel_nav_btn');
$nav['usermenu'][] = Array('profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'),'profile_nav_btn');
if(feature_enabled(local_channel(),'multi_profiles') && (! $basic))
$nav['usermenu'][] = Array('profiles', t('Edit Profiles'),"", t('Manage/Edit profiles'),'profiles_nav_btn');
else
$nav['usermenu'][] = Array('profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile'),'profiles_nav_btn');
$nav['usermenu'][] = Array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos'),'photos_nav_btn');
$nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files'),'cloud_nav_btn');
//$nav['usermenu'][] = Array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos'),'photos_nav_btn');
//$nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files'),'cloud_nav_btn');
if((! $basic) && feature_enabled(local_channel(),'ajaxchat'))
$nav['usermenu'][] = Array('chat/' . $channel['channel_address'], t('Chat'),"",t('Your chatrooms'),'chat_nav_btn');
//if((! $basic) && feature_enabled(local_channel(),'ajaxchat'))
// $nav['usermenu'][] = Array('chat/' . $channel['channel_address'], t('Chat'),"",t('Your chatrooms'),'chat_nav_btn');
require_once('include/menu.php');
$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
if(($has_bookmarks) && (! $basic)) {
$nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks'),'bookmarks_nav_btn');
}
//require_once('include/menu.php');
//$has_bookmarks = menu_list_count(local_channel(),'',MENU_BOOKMARK) + menu_list_count(local_channel(),'',MENU_SYSTEM|MENU_BOOKMARK);
//if(($has_bookmarks) && (! $basic)) {
// $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks'),'bookmarks_nav_btn');
//}
if(feature_enabled($channel['channel_id'],'webpages') && (! $basic))
$nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'),'webpages_nav_btn');
if(feature_enabled($channel['channel_id'],'wiki') && (! $basic))
$nav['usermenu'][] = Array('wiki/' . $channel['channel_address'],t('Wikis'),"",t('Your wikis'),'wiki_nav_btn');
//if(feature_enabled($channel['channel_id'],'webpages') && (! $basic))
// $nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'),'webpages_nav_btn');
//if(feature_enabled($channel['channel_id'],'wiki') && (! $basic))
// $nav['usermenu'][] = Array('wiki/' . $channel['channel_address'],t('Wikis'),"",t('Your wikis'),'wiki_nav_btn');
}
else {
if(! get_account_id()) {
$nav['login'] = login(true,'main-login',false,false);
$nav['loginmenu'][] = Array('login',t('Login'),'',t('Sign in'),'login_nav_btn');
App::$page['content'] .= replace_macros(get_markup_template('nav_login.tpl'),
[
'$nav' => $nav,
'userinfo' => $userinfo
]
);
}
else
$nav['alogout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn');
@@ -120,16 +142,6 @@ EOT;
}
if($observer) {
$userinfo = array(
'icon' => $observer['xchan_photo_m'],
'name' => $observer['xchan_addr'],
);
}
elseif(! $_SESSION['authenticated']) {
$nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn');
}
$homelink = get_my_url();
if(! $homelink) {
@@ -180,9 +192,11 @@ EOT;
$nav['network'] = array('network', t('Grid'), "", t('Your grid'),'network_nav_btn');
$nav['network']['all'] = [ 'network', t('View your network/grid'), '','' ];
$nav['network']['mark'] = array('', t('Mark all grid notifications seen'), '','');
$nav['home'] = array('channel/' . $channel['channel_address'], t('Channel Home'), "", t('Channel home'),'home_nav_btn');
$nav['home']['all'] = [ 'channel/' . $channel['channel_address'], t('View your channel home'), '' , '' ];
$nav['home']['mark'] = array('', t('Mark all channel notifications seen'), '','');
@@ -190,11 +204,11 @@ EOT;
$nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'),'notifications_nav_btn');
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
$nav['notifications']['all']=array('notifications/system', t('View all notifications'), "", "");
$nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '','');
$nav['messages'] = array('mail/combined', t('Mail'), "", t('Private mail'),'mail_nav_btn');
$nav['messages']['all']=array('mail/combined', t('See all private messages'), "", "");
$nav['messages']['all']=array('mail/combined', t('View your private messages'), "", "");
$nav['messages']['mark'] = array('', t('Mark all private messages seen'), '','');
$nav['messages']['inbox'] = array('mail/inbox', t('Inbox'), "", t('Inbox'));
$nav['messages']['outbox']= array('mail/outbox', t('Outbox'), "", t('Outbox'));
@@ -202,7 +216,7 @@ EOT;
$nav['all_events'] = array('events', t('Events'), "", t('Event Calendar'),'events_nav_btn');
$nav['all_events']['all']=array('events', t('See all events'), "", "");
$nav['all_events']['all']=array('events', t('View events'), "", "");
$nav['all_events']['mark'] = array('', t('Mark all events seen'), '','');
if(! $basic)
@@ -234,16 +248,44 @@ EOT;
$x = array('nav' => $nav, 'usermenu' => $userinfo );
call_hooks('nav', $x);
// Not sure the best place to put this on the page. So I'm implementing it but leaving it
// turned off until somebody discovers this and figures out a good location for it.
$powered_by = '';
// Not sure the best place to put this on the page. So I'm implementing it but leaving it
// turned off until somebody discovers this and figures out a good location for it.
$powered_by = '';
// $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>';
// $powered_by = '<strong>red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="r#" />matrix</strong>';
//app bin
if(local_channel()) {
if(get_pconfig(local_channel(), 'system','initial_import_system_apps') === false) {
Zlib\Apps::import_system_apps();
set_pconfig(local_channel(), 'system','initial_import_system_apps', 1);
}
$syslist = array();
$list = Zlib\Apps::app_list(local_channel(), false, 'nav_featured_app');
if($list) {
foreach($list as $li) {
$syslist[] = Zlib\Apps::app_encode($li);
}
}
Zlib\Apps::translate_system_apps($syslist);
}
else {
$syslist = Zlib\Apps::get_system_apps(true);
}
usort($syslist,'Zotlabs\\Lib\\Apps::app_name_compare');
foreach($syslist as $app) {
$navapps[] = Zlib\Apps::app_render($app,'nav');
}
$tpl = get_markup_template('nav.tpl');
App::$page['nav'] .= replace_macros($tpl, array(
'$baseurl' => z_root(),
'$fulldocs' => t('Help'),
'$sitelocation' => $sitelocation,
'$nav' => $x['nav'],
'$banner' => $banner,
@@ -253,10 +295,11 @@ $powered_by = '';
'$sel' => App::$nav_sel,
'$powered_by' => $powered_by,
'$help' => t('@name, #tag, ?doc, content'),
'$pleasewait' => t('Please wait...')
'$pleasewait' => t('Please wait...'),
'$navapps' => $navapps,
'$addapps' => t('Add Apps')
));
if(x($_SESSION, 'reload_avatar') && $observer) {
// The avatar has been changed on the server but the browser doesn't know that,
// force the browser to reload the image from the server instead of its cache.
+41 -31
View File
@@ -51,7 +51,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
@curl_setopt($ch, CURLOPT_CAINFO, get_capath());
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
@curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; Red)");
@curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)");
$ciphers = @get_config('system','curl_ssl_ciphers');
if($ciphers)
@@ -84,7 +84,7 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
@curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $opts['custom']);
if(x($opts,'timeout') && intval($opts['timeout'])) {
@curl_setopt($ch, CURLOPT_TIMEOUT, $opts['timeout']);
@curl_setopt($ch, CURLOPT_TIMEOUT, intval($opts['timeout']));
}
else {
$curl_time = intval(@get_config('system','curl_timeout'));
@@ -218,7 +218,7 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
@curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
@curl_setopt($ch, CURLOPT_POST,1);
@curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
@curl_setopt($ch, CURLOPT_USERAGENT, "Red");
@curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; zot)");
$ciphers = @get_config('system','curl_ssl_ciphers');
if($ciphers)
@@ -714,6 +714,10 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
if($i['success']) {
$ph = photo_factory($i['body'], $type);
if(! is_object($ph))
continue;
if($ph->is_valid()) {
$orig_width = $ph->getWidth();
$orig_height = $ph->getHeight();
@@ -1117,16 +1121,17 @@ function discover_by_url($url,$arr = null) {
if(! $photo)
$photo = z_root() . '/images/rss_icon.png';
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($guid),
dbesc($guid),
dbesc($pubkey),
dbesc($addr),
dbesc($profile),
dbesc($name),
dbesc($network),
dbesc(z_root()),
dbesc(datetime_convert())
$r = xchan_store_lowlevel(
[
'xchan_hash' => $guid,
'xchan_guid' => $guid,
'xchan_pubkey' => $pubkey,
'xchan_addr' => $addr,
'xchan_url' => $profile,
'xchan_name' => $name,
'xchan_name_date' => datetime_convert(),
'xchan_network' => $network
]
);
$photos = import_xchan_photo($photo,$guid);
@@ -1445,15 +1450,17 @@ function discover_by_webbie($webbie) {
);
}
else {
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($address),
dbesc(($diaspora_guid) ? $diaspora_guid : $location),
dbesc($pubkey),
dbesc($address),
dbesc($location),
dbesc($fullname),
dbesc($network),
dbescdate(datetime_convert())
$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
]
);
}
@@ -1462,15 +1469,18 @@ function discover_by_webbie($webbie) {
);
if(! $r) {
$r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)",
dbesc(($diaspora_guid) ? $diaspora_guid : $location),
dbesc($address),
dbesc($address),
dbesc($network),
dbesc($base),
dbesc($host),
dbesc($notify),
dbescdate(datetime_convert())
$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);
+5 -12
View File
@@ -2,8 +2,6 @@
use Zotlabs\Lib as Zlib;
require_once('include/hubloc.php');
function oembed_replacecb($matches){
@@ -107,7 +105,7 @@ function oembed_action($embedurl) {
function oembed_process($url) {
$j = oembed_fetch_url($url);
logger('oembed_process: ' . print_r($j,true));
logger('oembed_process: ' . print_r($j,true), LOGGER_DATA, LOG_DEBUG);
if($j && $j['type'] !== 'error')
return '[embed]' . $url . '[/embed]';
return false;
@@ -138,19 +136,15 @@ function oembed_fetch_url($embedurl){
// we should try to cache this and avoid a lookup on each render
$zrl = is_matrix_url($embedurl);
$furl = ((local_channel() && $zrl) ? zid($embedurl) : $embedurl);
if($action !== 'block') {
$txt = Zlib\Cache::get('[' . App::$videowidth . '] ' . $embedurl);
$txt = Zlib\Cache::get('[' . App::$videowidth . '] ' . $furl);
}
if(is_null($txt)) {
$txt = "";
$furl = $embedurl;
logger('local_channel: ' . local_channel());
if(local_channel() && $zrl)
$furl = zid($furl);
if ($action !== 'block') {
// try oembed autodiscovery
@@ -209,11 +203,10 @@ function oembed_fetch_url($embedurl){
//save in cache
if(! get_config('system','oembed_cache_disable'))
Zlib\Cache::set('[' . App::$videowidth . '] ' . $embedurl,$txt);
Zlib\Cache::set('[' . App::$videowidth . '] ' . $furl, $txt);
}
$j = json_decode($txt,true);
if(! $j)
+3 -1
View File
@@ -11,8 +11,10 @@ function photo_factory($data, $type = null) {
'image/svg+xml'
);
if($type && in_array(strtolower($type),$unsupported_types))
if($type && in_array(strtolower($type),$unsupported_types)) {
logger('photo_factory: unsupported image type');
return null;
}
$ignore_imagick = get_config('system', 'ignore_imagick');
+65 -8
View File
@@ -402,7 +402,7 @@ function photo_upload($channel, $observer, $args) {
$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=' . $arr['mid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$arr['body'] = $summary;
@@ -464,10 +464,15 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
$sort_key = dbesc($sort_key);
$direction = dbesc($direction);
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction",
intval($channel_id),
intval(PHOTO_NORMAL),
intval(PHOTO_PROFILE)
//$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and photo_usage IN ( %d, %d ) $sql_extra group by album order by $sort_key $direction",
// intval($channel_id),
// intval(PHOTO_NORMAL),
// intval(PHOTO_PROFILE)
//);
// this query provides the same results but might perform better
$albums = q("SELECT count( distinct resource_id ) as total, album from photo where uid = %d and os_storage = 1 $sql_extra group by album order by $sort_key $direction",
intval($channel_id)
);
// add various encodings to the array so we can just loop through and pick them out in a template
@@ -480,6 +485,7 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
foreach($albums as $k => $album) {
$entry = array(
'text' => (($album['album']) ? $album['album'] : '/'),
'jstext' => (($album['album']) ? addslashes($album['album']) : '/'),
'total' => $album['total'],
'url' => z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album['album']),
'urlencode' => urlencode($album['album']),
@@ -489,6 +495,8 @@ function photos_albums_list($channel, $observer, $sort_key = 'album', $direction
}
}
App::$data['albums'] = $ret;
return $ret;
}
@@ -663,7 +671,7 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) {
$arr['deny_cid'] = $photo['deny_cid'];
$arr['deny_gid'] = $photo['deny_gid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
$arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo['resource_id'] . ']'
. '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]'
@@ -710,10 +718,59 @@ function gps2Num($coordPart) {
return floatval($parts[0]) / floatval($parts[1]);
}
function photo_profile_setperms($channel_id,$resource_id,$profile_id) {
if(! $profile_id)
return;
$r = q("select profile_guid, is_default from profile where id = %d and uid = %d limit 1",
dbesc($profile_id),
intval($channel_id)
);
if(! $r)
return;
$is_default = $r[0]['is_default'];
$profile_guid = $r[0]['profile_guid'];
if($is_default) {
$r = q("update photo set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = ''
where resource_id = '%s' and uid = %d",
dbesc($resource_id),
intval($channel_id)
);
$r = q("update attach set allow_cid = '', allow_gid = '', deny_cid = '', deny_gid = ''
where hash = '%s' and uid = %d",
dbesc($resource_id),
intval($channel_id)
);
}
else {
$r = q("update photo set allow_cid = '', allow_gid = '%s', deny_cid = '', deny_gid = ''
where resource_id = '%s' and uid = %d",
dbesc('<vp.' . $profile_guid . '>'),
dbesc($resource_id),
intval($channel_id)
);
$r = q("update attach set allow_cid = '', allow_gid = '%s', deny_cid = '', deny_gid = ''
where hash = '%s' and uid = %d",
dbesc('<vp.' . $profile_guid . '>'),
dbesc($resource_id),
intval($channel_id)
);
}
}
function profile_photo_set_profile_perms($uid, $profileid = 0) {
$allowcid = '';
if($profileid) {
$allowcid = '';
if($profileid) {
$r = q("SELECT photo, profile_guid, id, is_default, uid
FROM profile WHERE uid = %d and ( profile.id = %d OR profile.profile_guid = '%s') LIMIT 1",
intval($uid),
+54 -16
View File
@@ -471,6 +471,8 @@ function get_theme_info($theme){
'description' => '',
'author' => array(),
'version' => '',
'minversion' => '',
'maxversion' => '',
'compat' => '',
'credits' => '',
'maintainer' => array(),
@@ -556,32 +558,65 @@ function head_add_css($src, $media = 'screen') {
function head_remove_css($src, $media = 'screen') {
$index = array_search(array($src, $media), App::$css_sources);
if ($index !== false)
if($index !== false)
unset(App::$css_sources[$index]);
}
function head_get_css() {
$str = '';
$sources = App::$css_sources;
if (count($sources)) {
foreach ($sources as $source)
if(count($sources)) {
foreach($sources as $source)
$str .= format_css_if_exists($source);
}
return $str;
}
function format_css_if_exists($source) {
$path_prefix = script_path() . '/';
function head_add_link($arr) {
if($arr) {
App::$linkrel[] = $arr;
}
}
if (strpos($source[0], '/') !== false) {
// The source is a URL
$path = $source[0];
function head_get_links() {
$str = '';
$sources = App::$linkrel;
if(count($sources)) {
foreach($sources as $source) {
if(is_array($source) && count($source)) {
$str .= '<link';
foreach($source as $k => $v) {
$str .= ' ' . $k . '="' . $v . '"';
}
$str .= ' />' . "\r\n";
}
}
}
return $str;
}
function format_css_if_exists($source) {
// script_path() returns https://yoursite.tld
$path_prefix = script_path();
$script = $source[0];
if(strpos($script, '/') !== false) {
// The script is a path relative to the server root
$path = $script;
// If the url starts with // then it's an absolute URL
if($source[0][0] === '/' && $source[0][1] === '/') $path_prefix = '';
if(substr($script,0,2) === '//') {
$path_prefix = '';
}
} else {
// It's a file from the theme
$path = theme_include($source[0]);
$path = '/' . theme_include($script);
}
if($path) {
@@ -651,7 +686,7 @@ function head_get_js() {
foreach(App::$js_sources as $sources) {
if(count($sources)) {
foreach($sources as $source) {
if($src === 'main.js')
if($source === 'main.js')
continue;
$str .= format_js_if_exists($source);
}
@@ -671,16 +706,19 @@ function head_get_main_js() {
}
function format_js_if_exists($source) {
$path_prefix = script_path() . '/';
$path_prefix = script_path();
if(strpos($source,'/') !== false) {
// The source is a URL
// The source is a known path on the system
$path = $source;
// If the url starts with // then it's an absolute URL
if($source[0] === '/' && $source[1] === '/') $path_prefix = '';
} else {
if(substr($source,0,2) === '//') {
$path_prefix = '';
}
}
else {
// It's a file from the theme
$path = theme_include($source);
$path = '/' . theme_include($source);
}
if($path) {
$qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION;
+57 -4
View File
@@ -2,9 +2,57 @@
function update_queue_item($id, $add_priority = 0) {
logger('queue: requeue item ' . $id,LOGGER_DEBUG);
q("UPDATE outq SET outq_updated = '%s', outq_priority = outq_priority + %d WHERE outq_hash = '%s'",
$x = q("select outq_created, outq_posturl from outq where outq_hash = '%s' limit 1",
dbesc($id)
);
if(! $x)
return;
$y = q("select min(outq_created) as earliest from outq where outq_posturl = '%s'",
dbesc($x[0]['outq_posturl'])
);
// look for the oldest queue entry with this destination URL. If it's older than a couple of days,
// the destination is considered to be down and only scheduled once an hour, regardless of the
// age of the current queue item.
$might_be_down = false;
if($y)
$might_be_down = ((datetime_convert('UTC','UTC',$y[0]['earliest']) < datetime_convert('UTC','UTC','now - 2 days')) ? true : false);
// Set all other records for this destination way into the future.
// The queue delivers by destination. We'll keep one queue item for
// this destination (this one) with a shorter delivery. If we succeed
// once, we'll try to deliver everything for that destination.
// The delivery will be set to at most once per hour, and if the
// queue item is less than 12 hours old, we'll schedule for fifteen
// minutes.
$r = q("UPDATE outq SET outq_scheduled = '%s' WHERE outq_posturl = '%s'",
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
dbesc($x[0]['outq_posturl'])
);
$since = datetime_convert('UTC','UTC',$x[0]['outq_created']);
if(($might_be_down) || ($since < datetime_convert('UTC','UTC','now - 12 hour'))) {
$next = datetime_convert('UTC','UTC','now + 1 hour');
}
else {
$next = datetime_convert('UTC','UTC','now + 15 minutes');
}
q("UPDATE outq SET outq_updated = '%s',
outq_priority = outq_priority + %d,
outq_scheduled = '%s'
WHERE outq_hash = '%s'",
dbesc(datetime_convert()),
intval($add_priority),
dbesc($next),
dbesc($id)
);
}
@@ -33,8 +81,12 @@ function queue_set_delivered($id,$channel = 0) {
logger('queue: set delivered ' . $id,LOGGER_DEBUG);
$sql_extra = (($channel_id) ? " and outq_channel = " . intval($channel_id) . " " : '');
q("update outq set outq_delivered = 1, outq_updated = '%s' where outq_hash = '%s' $sql_extra ",
// Set the next scheduled run date so far in the future that it will be expired
// long before it ever makes it back into the delivery chain.
q("update outq set outq_delivered = 1, outq_updated = '%s', outq_scheduled = '%s' where outq_hash = '%s' $sql_extra ",
dbesc(datetime_convert()),
dbesc(datetime_convert('UTC','UTC','now + 5 days')),
dbesc($id)
);
}
@@ -44,8 +96,8 @@ function queue_set_delivered($id,$channel = 0) {
function queue_insert($arr) {
$x = q("insert into outq ( outq_hash, outq_account, outq_channel, outq_driver, outq_posturl, outq_async, outq_priority,
outq_created, outq_updated, outq_notify, outq_msg )
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' )",
outq_created, outq_updated, outq_scheduled, outq_notify, outq_msg )
values ( '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s' )",
dbesc($arr['hash']),
intval($arr['account_id']),
intval($arr['channel_id']),
@@ -55,6 +107,7 @@ function queue_insert($arr) {
intval(($arr['priority']) ? $arr['priority'] : 0),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($arr['notify']),
dbesc(($arr['msg']) ? $arr['msg'] : '')
);
+25 -14
View File
@@ -171,19 +171,16 @@ function atoken_create_xchan($xchan) {
if($r)
return;
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_photo_mimetype, xchan_photo_l, xchan_photo_m, xchan_photo_s )
values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($xchan['xchan_hash']),
dbesc($xchan['xchan_hash']),
dbesc($xchan['xchan_addr']),
dbesc($xchan['xchan_url']),
dbesc($xchan['xchan_name']),
dbesc($xchan['xchan_network']),
dbesc($xchan['xchan_photo_mimetype']),
dbesc($xchan['xchan_photo_l']),
dbesc($xchan['xchan_photo_m']),
dbesc($xchan['xchan_photo_s'])
);
$xchan['xchan_guid'] = $xchan['xchan_hash'];
$store = [];
foreach($xchan as $k => $v) {
if(strpos($k,'xchan_') === 0) {
$store[$k] = $v;
}
}
$r = xchan_store_lowlevel($store);
return true;
}
@@ -556,7 +553,21 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f
// var $contact_id = xchan_hash of connection
function init_groups_visitor($contact_id) {
$groups = array();
$groups = [];
// private profiles are treated as a virtual group
$r = q("SELECT abook_profile from abook where abook_xchan = '%s' and abook_profile != '' ",
dbesc($contact_id)
);
if($r) {
foreach($r as $rv) {
$groups[] = 'vp.' . $rv['abook_profile'];
}
}
// physical groups this channel is a member of
$r = q("SELECT hash FROM groups left join group_member on groups.id = group_member.gid WHERE xchan = '%s' ",
dbesc($contact_id)
);
+85 -9
View File
@@ -4,7 +4,7 @@
*/
require_once("include/bbcode.php");
require_once('include/hubloc.php');
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
@@ -586,8 +586,10 @@ function photo_new_resource() {
* @return boolean true if found
*/
function attribute_contains($attr, $s) {
// remove quotes
$attr = str_replace([ '"',"'" ],['',''],$attr);
$a = explode(' ', $attr);
if(count($a) && in_array($s, $a))
if($a && in_array($s, $a))
return true;
return false;
@@ -655,12 +657,28 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
*/
function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
if(! defined('BTLOGGER_DEBUG_FILE'))
define('BTLOGGER_DEBUG_FILE','btlogger.out');
logger($msg, $level, $priority);
if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) {
$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;
@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 ++) {
logger('stack: ' . basename($stack[$x]['file']) . ':' . $stack[$x]['line'] . ':' . $stack[$x]['function'] . '()',$level, $priority);
$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);
}
}
}
}
@@ -1565,11 +1583,6 @@ function prepare_body(&$item,$attach = false) {
$photo = $prep_arr['photo'];
$event = $prep_arr['event'];
// q("update item set html = '%s' where id = %d",
// dbesc($s),
// intval($item['id'])
// );
if(! $attach) {
return $s;
}
@@ -3061,4 +3074,67 @@ function create_table_from_array($table, $arr) {
}
return $r;
}
}
function cleanup_bbcode($body) {
/**
* fix naked links by passing through a callback to see if this is a hubzilla site
* (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both.
* First protect any url inside certain bbcode tags so we don't double link it.
*/
$body = preg_replace_callback('/\[code(.*?)\[\/(code)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[url(.*?)\[\/(url)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback('/\[zrl(.*?)\[\/(zrl)\]/ism','\red_escape_codeblock',$body);
$body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\
+\,\(\)]+)/ism", '\nakedoembed', $body);
$body = preg_replace_callback("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\\
+\,\(\)]+)/ism", '\red_zrl_callback', $body);
$body = preg_replace_callback('/\[\$b64zrl(.*?)\[\/(zrl)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body);
// fix any img tags that should be zmg
$body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body);
$body = bb_translate_video($body);
/**
* Fold multi-line [code] sequences
*/
$body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
$body = scale_external_images($body,false);
return $body;
}
function gen_link_id($mid) {
if(strpbrk($mid,':/&?<>"\'') !== false)
return 'b64.' . base64url_encode($mid);
return $mid;
}
// callback for array_walk
function array_trim(&$v,$k) {
$v = trim($v);
}
function array_escape_tags(&$v,$k) {
$v = escape_tags($v);
}
+46 -30
View File
@@ -96,19 +96,6 @@ function widget_collections($args) {
return group_side($every, $each, $edit, $current, $abook_id, $wmode);
}
function widget_appselect($arr) {
return replace_macros(get_markup_template('app_select.tpl'),array(
'$title' => t('Apps'),
'$system' => t('System'),
'$authed' => ((local_channel()) ? true : false),
'$personal' => t('Personal'),
'$new' => t('New App'),
'$edit' => t('Edit App')
));
}
function widget_suggestions($arr) {
if((! local_channel()) || (! feature_enabled(local_channel(),'suggest')))
@@ -441,11 +428,13 @@ function widget_appcategories($arr) {
if(! local_channel())
return '';
$cat = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
$srchurl = App::$query_string;
$selected = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
$srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
$srchurl = z_root() . '/apps';
$terms = array();
$r = q("select distinct(term.term)
@@ -453,6 +442,7 @@ function widget_appcategories($arr) {
where app_channel = %d
and term.uid = app_channel
and term.otype = %d
and term.term != 'nav_featured_app'
order by term.term asc",
intval(local_channel()),
intval(TERM_OBJ_APP)
@@ -518,9 +508,16 @@ function widget_affinity($arr) {
if(! local_channel())
return '';
$cmin = ((x($_REQUEST,'cmin')) ? intval($_REQUEST['cmin']) : 0);
$cmax = ((x($_REQUEST,'cmax')) ? intval($_REQUEST['cmax']) : 99);
// Get default cmin value from pconfig, but allow GET parameter to override
$cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
$cmin = (($cmin) ? $cmin : 0);
$cmin = ((x($_REQUEST,'cmin')) ? intval($_REQUEST['cmin']) : $cmin);
// Get default cmax value from pconfig, but allow GET parameter to override
$cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
$cmax = (($cmax) ? $cmax : 99);
$cmax = ((x($_REQUEST,'cmax')) ? intval($_REQUEST['cmax']) : $cmax);
if(feature_enabled(local_channel(),'affinity')) {
@@ -650,6 +647,14 @@ function widget_settings_menu($arr) {
);
}
if(feature_enabled(local_channel(),'permcats')) {
$tabs[] = array(
'label' => t('Permission Groups'),
'url' => z_root() . '/settings/permcats',
'selected' => ((argv(1) === 'permcats') ? 'active' : ''),
);
}
if($role === false || $role === 'custom') {
$tabs[] = array(
@@ -898,9 +903,11 @@ function widget_chatroom_members() {
}
function widget_wiki_list($arr) {
require_once("include/wiki.php");
$channel = channelx_by_n(App::$profile_uid);
$wikis = wiki_list($channel, get_observer_hash());
$wikis = Zotlabs\Lib\NativeWiki::listwikis($channel,get_observer_hash());
if($wikis) {
return replace_macros(get_markup_template('wikilist_widget.tpl'), array(
'$header' => t('Wiki List'),
@@ -913,8 +920,9 @@ function widget_wiki_list($arr) {
function widget_wiki_pages($arr) {
require_once("include/wiki.php");
$channelname = ((array_key_exists('channel',$arr)) ? $arr['channel'] : '');
$c = channelx_by_nick($channelname);
$wikiname = '';
if (array_key_exists('refresh', $arr)) {
$not_refresh = (($arr['refresh']=== true) ? false : true);
@@ -922,11 +930,12 @@ function widget_wiki_pages($arr) {
$not_refresh = true;
}
$pages = array();
if (!array_key_exists('resource_id', $arr)) {
if (! array_key_exists('resource_id', $arr)) {
$hide = true;
} else {
$p = wiki_page_list($arr['resource_id']);
if ($p['pages']) {
$p = Zotlabs\Lib\NativeWikiPage::page_list($c['channel_id'],get_observer_hash(),$arr['resource_id']);
if($p['pages']) {
$pages = $p['pages'];
$w = $p['wiki'];
// Wiki item record is $w['wiki']
@@ -936,31 +945,38 @@ function widget_wiki_pages($arr) {
}
}
}
$can_create = perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'write_pages');
$can_create = perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'write_wiki');
$can_delete = ((local_channel() && (local_channel() == \App::$profile['uid'])) ? true : false);
return replace_macros(get_markup_template('wiki_page_list.tpl'), array(
'$hide' => $hide,
'$resource_id' => $arr['resource_id'],
'$not_refresh' => $not_refresh,
'$header' => t('Wiki Pages'),
'$channel' => $channelname,
'$wikiname' => $wikiname,
'$pages' => $pages,
'$canadd' => $can_create,
'$candel' => $can_delete,
'$addnew' => t('Add new page'),
'$pageName' => array('pageName', t('Page name')),
));
}
function widget_wiki_page_history($arr) {
require_once("include/wiki.php");
$pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : '');
$pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
return replace_macros(get_markup_template('wiki_page_history.tpl'), array(
'$pageHistory' => $pageHistory['history'],
'$permsWrite' => $arr['permsWrite']
$pageHistory = Zotlabs\Lib\NativeWikiPage::page_history(array('channel_id' => App::$profile_uid, 'observer_hash' => get_observer_hash(), 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
return replace_macros(get_markup_template('nwiki_page_history.tpl'), array(
'$pageHistory' => $pageHistory['history'],
'$permsWrite' => $arr['permsWrite'],
'$name_lbl' => t('Name'),
'$msg_label' => t('Message','wiki_history')
));
}
function widget_bookmarkedchats($arr) {
-664
View File
@@ -1,664 +0,0 @@
<?php
/**
* @file include/wiki.php
* @brief Wiki related functions.
*/
use \Zotlabs\Storage\GitRepo as GitRepo;
define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' );
function wiki_list($channel, $observer_hash) {
$sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash);
$wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra",
dbesc(WIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
if($wikis) {
foreach($wikis as &$w) {
$w['rawName'] = get_iconfig($w, 'wiki', 'rawName');
$w['htmlName'] = get_iconfig($w, 'wiki', 'htmlName');
$w['urlName'] = get_iconfig($w, 'wiki', 'urlName');
$w['path'] = get_iconfig($w, 'wiki', 'path');
$w['mimeType'] = get_iconfig($w, 'wiki', 'mimeType');
$w['lock'] = (($w['allow_cid'] || $w['allow_gid'] || $w['deny_cid'] || $w['deny_gid']) ? true : false);
}
}
// TODO: query db for wikis the observer can access. Return with two lists, for read and write access
return array('wikis' => $wikis);
}
function wiki_page_list($resource_id) {
// TODO: Create item table records for pages so that metadata like title can be applied
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('pages' => null, 'wiki' => null);
}
$pages[] = [
'resource_id' => '',
'title' => 'Home',
'url' => 'Home',
'link_id' => 'id_wiki_home_0'
];
if (is_dir($w['path']) === true) {
$files = array_diff(scandir($w['path']), array('.', '..', '.git'));
// TODO: Check that the files are all text files
$i = 1;
foreach($files as $file) {
// strip the file extension and unwrap URL encoding to leave HTML encoded name
$title = substr($file, 0, strrpos($file,'.'));
if(urldecode($title) !== 'Home') {
$pages[] = [
'resource_id' => $resource_id,
'title' => urldecode($title),
'url' => $title,
'link_id' => 'id_' . substr($resource_id, 0, 10) . '_' . $i
];
$i++;
}
}
}
return array('pages' => $pages, 'wiki' => $w);
}
function wiki_init_wiki($channel, $wiki) {
// Store the path as a relative path, but pass absolute path to mkdir
$path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$wiki['urlName'];
if (!os_mkdir(__DIR__ . '/../' . $path, 0770, true)) {
logger('Error creating wiki path: ' . $path);
return null;
}
// Create GitRepo object
$git = new GitRepo($channel['channel_address'], null, false, $wiki['urlName'], __DIR__ . '/../' . $path);
if(!$git->initRepo()) {
logger('Error creating new git repo in ' . $git->path);
return null;
}
return array('path' => $path);
}
function wiki_create_wiki($channel, $observer_hash, $wiki, $acl) {
$wikiinit = wiki_init_wiki($channel, $wiki);
if (!$wikiinit['path']) {
notice('Error creating wiki');
return array('item' => null, 'success' => false);
}
$path = $wikiinit['path'];
// Generate unique resource_id using the same method as item_message_id()
do {
$dups = false;
$resource_id = random_string();
$r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1",
dbesc($resource_id),
dbesc(WIKI_ITEM_RESOURCE_TYPE),
intval($channel['channel_id'])
);
if (count($r))
$dups = true;
} while ($dups == true);
$ac = $acl->get();
$mid = item_message_id();
$arr = array(); // Initialize the array of parameters for the post
$item_hidden = ((intval($wiki['postVisible']) === 0) ? 1 : 0);
$wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName'];
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
$arr['item_hidden'] = $item_hidden;
$arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE;
$arr['resource_id'] = $resource_id;
$arr['owner_xchan'] = $channel['channel_hash'];
$arr['author_xchan'] = $observer_hash;
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['llink'] = $arr['plink'];
$arr['title'] = $wiki['htmlName']; // name of new wiki;
$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['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$arr['verb'] = ACTIVITY_CREATE;
$arr['obj_type'] = ACTIVITY_OBJ_WIKI;
$arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]';
// Save the path using iconfig. The file path should not be shared with other hubs
if (!set_iconfig($arr, 'wiki', 'path', $path, false)) {
return array('item' => null, 'success' => false);
}
// Save the wiki name information using iconfig. This is shareable.
if (!set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) {
return array('item' => null, 'success' => false);
}
if (!set_iconfig($arr, 'wiki', 'htmlName', $wiki['htmlName'], true)) {
return array('item' => null, 'success' => false);
}
if (!set_iconfig($arr, 'wiki', 'urlName', $wiki['urlName'], true)) {
return array('item' => null, 'success' => false);
}
if (!set_iconfig($arr, 'wiki', 'mimeType', $wiki['mimeType'], true)) {
return array('item' => null, 'success' => false);
}
$post = item_store($arr);
$item_id = $post['item_id'];
if ($item_id) {
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'activity', $item_id));
return array('item' => $post['item'], 'success' => true);
} else {
return array('item' => null, 'success' => false);
}
}
function wiki_delete_wiki($resource_id) {
$w = wiki_get_wiki($resource_id);
$item = $w['wiki'];
if (!$item || !$w['path']) {
return array('item' => null, 'success' => false);
} else {
$drop = drop_item($item['id'], false, DROPITEM_NORMAL, true);
$pathdel = rrmdir($w['path']);
if ($pathdel) {
info('Wiki files deleted successfully');
}
return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false));
}
}
function wiki_get_wiki($resource_id) {
$item = q("SELECT * FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1",
dbesc(WIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if (!$item) {
return array('wiki' => null, 'path' => null);
} else {
$w = $item[0]; // wiki item table record
// Get wiki metadata
$rawName = get_iconfig($w, 'wiki', 'rawName');
$htmlName = get_iconfig($w, 'wiki', 'htmlName');
$urlName = get_iconfig($w, 'wiki', 'urlName');
$mimeType = get_iconfig($w, 'wiki', 'mimeType');
$path = get_iconfig($w, 'wiki', 'path');
if (!realpath(__DIR__ . '/../' . $path)) {
return array('wiki' => null, 'path' => null);
}
// Path to wiki exists
$abs_path = realpath(__DIR__ . '/../' . $path);
return array(
'wiki' => $w,
'path' => $abs_path,
'rawName' => $rawName,
'htmlName' => $htmlName,
'urlName' => $urlName,
'mimeType' => $mimeType
);
}
}
function wiki_exists_by_name($uid, $urlName) {
$item = q("SELECT id,resource_id FROM item WHERE resource_type = '%s' AND title = '%s' AND uid = '%s' AND item_deleted = 0 limit 1",
dbesc(WIKI_ITEM_RESOURCE_TYPE),
dbesc(escape_tags(urldecode($urlName))),
dbesc($uid)
);
if (!$item) {
return array('id' => null, 'resource_id' => null);
} else {
return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']);
}
}
function wiki_get_permissions($resource_id, $owner_id, $observer_hash) {
// TODO: For now, only the owner can edit
$sql_extra = item_permissions_sql($owner_id, $observer_hash);
if(local_channel() && local_channel == $owner_id) {
return [ 'read' => true, 'write' => true, 'success' => true ];
}
$r = q("SELECT * FROM item WHERE uid = %d and resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1",
intval($owner_id),
dbesc(WIKI_ITEM_RESOURCE_TYPE),
dbesc($resource_id)
);
if (!$r) {
return array('read' => false, 'write' => false, 'success' => true);
} else {
// TODO: Create a new permission setting for wiki analogous to webpages. Until
// then, use webpage permissions
$write = perm_is_allowed($owner_id, $observer_hash,'write_pages');
return array('read' => true, 'write' => $write, 'success' => true);
}
}
function wiki_create_page($name, $resource_id) {
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('page' => null, 'wiki' => null, 'message' => 'Wiki not found.', 'success' => false);
}
$page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => urlencode(escape_tags($name)) . wiki_get_file_ext($w));
$page_path = $w['path'] . '/' . $page['fileName'];
if (is_file($page_path)) {
return array('page' => null, 'wiki' => null, 'message' => 'Page already exists.', 'success' => false);
}
// Create the page file in the wiki repo
if(!touch($page_path)) {
return array('page' => null, 'wiki' => null, 'message' => 'Page file cannot be created.', 'success' => false);
} else {
return array('page' => $page, 'wiki' => $w, 'message' => '', 'success' => true);
}
}
function wiki_rename_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$pageNewName = ((array_key_exists('pageNewName',$arr)) ? $arr['pageNewName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('message' => 'Wiki not found.', 'success' => false);
}
$page_path_old = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (!is_readable($page_path_old) === true) {
return array('message' => 'Cannot read wiki page: ' . $page_path_old, 'success' => false);
}
$page = array('rawName' => $pageNewName, 'htmlName' => escape_tags($pageNewName), 'urlName' => urlencode(escape_tags($pageNewName)), 'fileName' => urlencode(escape_tags($pageNewName)) . wiki_get_file_ext($w));
$page_path_new = $w['path'] . '/' . $page['fileName'] ;
if (is_file($page_path_new)) {
return array('message' => 'Page already exists.', 'success' => false);
}
// Rename the page file in the wiki repo
if(!rename($page_path_old, $page_path_new)) {
return array('message' => 'Error renaming page file.', 'success' => false);
} else {
return array('page' => $page, 'message' => '', 'success' => true);
}
}
function wiki_get_page_content($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_readable($page_path) === true) {
if(filesize($page_path) === 0) {
$content = '';
} else {
$content = file_get_contents($page_path);
if(!$content) {
return array('content' => null, 'message' => 'Error reading page content', 'success' => false);
}
}
// TODO: Check that the files are all text files
return array('content' => json_encode($content), 'mimeType' => $w['mimeType'], 'message' => '', 'success' => true);
}
}
function wiki_page_history($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('history' => null, 'message' => 'Error reading wiki', 'success' => false);
}
$page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (!is_readable($page_path) === true) {
return array('history' => null, 'message' => 'Cannot read wiki page: ' . $page_path, 'success' => false);
}
$reponame = ((array_key_exists('title', $w['wiki'])) ? $w['wiki']['title'] : 'repo');
if($reponame === '') {
$reponame = 'repo';
}
$git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']);
try {
$gitlog = $git->git->log('', $page_path , array('limit' => 500));
return array('history' => $gitlog, 'message' => '', 'success' => true);
} catch (\PHPGit\Exception\GitException $e) {
return array('history' => null, 'message' => 'GitRepo error thrown', 'success' => false);
}
}
function wiki_prepare_content($s) {
$text = preg_replace_callback('{
(?:\n\n|\A\n?)
( # $1 = the code block -- one or more lines, starting with a space/tab
(?>
[ ]{'.'4'.'} # Lines must start with a tab or a tab-width of spaces
.*\n+
)+
)
((?=^[ ]{0,'.'4'.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
}xm',
'wiki_prepare_content_callback', $s);
return $text;
}
function wiki_prepare_content_callback($matches) {
$codeblock = $matches[1];
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES, UTF8, false);
return "\n\n" . $codeblock ;
}
function wiki_save_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$content = ((array_key_exists('content',$arr)) ? purify_html(wiki_prepare_content($arr['content'])) : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
$fileName = $pageUrlName . wiki_get_file_ext($w);
$page_path = $w['path'] . '/' . $fileName;
if (is_writable($page_path) === true) {
if(!file_put_contents($page_path, $content)) {
return array('message' => 'Error writing to page file', 'success' => false);
}
return array('message' => '', 'filename' => $filename, 'success' => true);
} else {
return array('message' => 'Page file not writable', 'success' => false);
}
}
function wiki_delete_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
$page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_writable($page_path) === true) {
if(!unlink($page_path)) {
return array('message' => 'Error deleting page file', 'success' => false);
}
return array('message' => '', 'success' => true);
} else {
return array('message' => 'Page file not writable', 'success' => false);
}
}
function wiki_revert_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null);
if (! $commitHash) {
return array('content' => $content, 'message' => 'No commit was provided', 'success' => false);
}
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false);
}
$page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_writable($page_path) === true) {
$reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo');
if($reponame === '') {
$reponame = 'repo';
}
$git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']);
$content = null;
try {
$git->setIdentity($observer['xchan_name'], $observer['xchan_addr']);
foreach ($git->git->tree($commitHash) as $object) {
if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$content = $git->git->cat->blob($object['hash']);
}
}
} catch (\PHPGit\Exception\GitException $e) {
return array('content' => $content, 'message' => 'GitRepo error thrown', 'success' => false);
}
return array('content' => $content, 'message' => '', 'success' => true);
} else {
return array('content' => $content, 'message' => 'Page file not writable', 'success' => false);
}
}
function wiki_compare_page($arr) {
$pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : '');
$resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : '');
$currentCommit = ((array_key_exists('currentCommit',$arr)) ? $arr['currentCommit'] : 'HEAD');
$compareCommit = ((array_key_exists('compareCommit',$arr)) ? $arr['compareCommit'] : null);
if (! $compareCommit) {
return array('message' => 'No compare commit was provided', 'success' => false);
}
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
$page_path = $w['path'] . '/' . $pageUrlName . wiki_get_file_ext($w);
if (is_readable($page_path) === true) {
$reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo');
if($reponame === '') {
$reponame = 'repo';
}
$git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']);
$compareContent = $currentContent = '';
try {
foreach ($git->git->tree($currentCommit) as $object) {
if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$currentContent = $git->git->cat->blob($object['hash']);
}
}
foreach ($git->git->tree($compareCommit) as $object) {
if ($object['type'] == 'blob' && $object['file'] === $pageUrlName . wiki_get_file_ext($w)) {
$compareContent = $git->git->cat->blob($object['hash']);
}
}
require_once('library/class.Diff.php');
$diff = Diff::toTable(Diff::compare($currentContent, $compareContent));
} catch (\PHPGit\Exception\GitException $e) {
return array('message' => 'GitRepo error thrown', 'success' => false);
}
return array('diff' => $diff, 'message' => '', 'success' => true);
} else {
return array('message' => 'Page file not writable', 'success' => false);
}
}
function wiki_git_commit($arr) {
$files = ((array_key_exists('files', $arr)) ? $arr['files'] : null);
$all = ((array_key_exists('all', $arr)) ? $arr['all'] : false);
$commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated');
if(array_key_exists('resource_id', $arr)) {
$resource_id = $arr['resource_id'];
} else {
return array('message' => 'Wiki resource_id required for git commit', 'success' => false);
}
if(array_key_exists('observer', $arr)) {
$observer = $arr['observer'];
} else {
return array('message' => 'Observer required for git commit', 'success' => false);
}
$w = wiki_get_wiki($resource_id);
if (!$w['path']) {
return array('message' => 'Error reading wiki', 'success' => false);
}
$reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo');
if($reponame === '') {
$reponame = 'repo';
}
$git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']);
try {
$git->setIdentity($observer['xchan_name'], $observer['xchan_addr']);
if ($files === null) {
$options = array('all' => true); // git commit option to include all changes
} else {
$options = array('all' => $all); // git commit options\
foreach ($files as $file) {
if (!$git->git->add($file)) { // add specified files to the git repo stage
if (!$git->git->reset->hard()) {
return array('message' => 'Error adding file to git stage: ' . $file . '. Error resetting git repo.', 'success' => false);
}
return array('message' => 'Error adding file to git stage: ' . $file, 'success' => false);
}
}
}
if ($git->commit($commit_msg, $options)) {
return array('message' => 'Wiki repo commit succeeded', 'success' => true);
} else {
return array('message' => 'Wiki repo commit failed', 'success' => false);
}
} catch (\PHPGit\Exception\GitException $e) {
return array('message' => 'GitRepo error thrown', 'success' => false);
}
}
function wiki_convert_links($s, $wikiURL) {
if (strpos($s,'[[') !== false) {
preg_match_all("/\[\[(.*?)\]\]/", $s, $match);
$pages = $pageURLs = array();
foreach ($match[1] as $m) {
// TODO: Why do we need to double urlencode for this to work?
$pageURLs[] = urlencode(urlencode(escape_tags($m)));
$pages[] = $m;
}
$idx = 0;
while(strpos($s,'[[') !== false) {
$replace = '<a href="'.$wikiURL.'/'.$pageURLs[$idx].'">'.$pages[$idx].'</a>';
$s = preg_replace("/\[\[(.*?)\]\]/", $replace, $s, 1);
$idx++;
}
}
return $s;
}
/**
* Replace the instances of the string [toc] with a list element that will be populated by
* a table of contents by the JavaScript library
* @param string $s
* @return string
*/
function wiki_generate_toc($s) {
if (strpos($s,'[toc]') !== false) {
//$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render
$toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/
$s = preg_replace("/\[toc\]/", $toc_md, $s, -1);
}
return $s;
}
/**
* Converts a select set of bbcode tags. Much of the code is copied from include/bbcode.php
* @param string $s
* @return string
*/
function wiki_bbcode($s) {
$s = str_replace(array('[baseurl]', '[sitename]'), array(z_root(), get_config('system', 'sitename')), $s);
$observer = App::get_observer();
if ($observer) {
$s1 = '<span class="bb_observer" title="' . t('Different viewers will see this text differently') . '">';
$s2 = '</span>';
$obsBaseURL = $observer['xchan_connurl'];
$obsBaseURL = preg_replace("/\/poco\/.*$/", '', $obsBaseURL);
$s = str_replace('[observer.baseurl]', $obsBaseURL, $s);
$s = str_replace('[observer.url]', $observer['xchan_url'], $s);
$s = str_replace('[observer.name]', $s1 . $observer['xchan_name'] . $s2, $s);
$s = str_replace('[observer.address]', $s1 . $observer['xchan_addr'] . $s2, $s);
$s = str_replace('[observer.webname]', substr($observer['xchan_addr'], 0, strpos($observer['xchan_addr'], '@')), $s);
$s = str_replace('[observer.photo]', '', $s);
} else {
$s = str_replace('[observer.baseurl]', '', $s);
$s = str_replace('[observer.url]', '', $s);
$s = str_replace('[observer.name]', '', $s);
$s = str_replace('[observer.address]', '', $s);
$s = str_replace('[observer.webname]', '', $s);
$s = str_replace('[observer.photo]', '', $s);
}
return $s;
}
function wiki_get_file_ext($arr) {
if($arr['mimeType'] == 'text/bbcode')
return '.bb';
else
return '.md';
}
// This function is derived from
// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php
function wiki_toc($content) {
// ensure using only "\n" as line-break
$source = str_replace(["\r\n", "\r"], "\n", $content);
// look for markdown TOC items
preg_match_all(
'/^(?:=|-|#).*$/m',
$source,
$matches,
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE
);
// preprocess: iterate matched lines to create an array of items
// where each item is an array(level, text)
$file_size = strlen($source);
foreach ($matches[0] as $item) {
$found_mark = substr($item[0], 0, 1);
if ($found_mark == '#') {
// text is the found item
$item_text = $item[0];
$item_level = strrpos($item_text, '#') + 1;
$item_text = substr($item_text, $item_level);
} else {
// text is the previous line (empty if <hr>)
$item_offset = $item[1];
$prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2));
$item_text =
substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1);
$item_text = trim($item_text);
$item_level = $found_mark == '=' ? 1 : 2;
}
if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) {
// item is an horizontal separator or a table header, don't mind
continue;
}
$raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)];
}
$o = '';
foreach($raw_toc as $t) {
$level = intval($t['level']);
$text = $t['text'];
switch ($level) {
case 1:
$li = '* ';
break;
case 2:
$li = ' * ';
break;
case 3:
$li = ' * ';
break;
case 4:
$li = ' * ';
break;
default:
$li = '* ';
break;
}
$o .= $li . $text . "\n";
}
return $o;
}
+139
View File
@@ -0,0 +1,139 @@
<?php
function xchan_store_lowlevel($arr) {
$store = [
'xchan_hash' => ((array_key_exists('xchan_hash',$arr)) ? $arr['xchan_hash'] : ''),
'xchan_guid' => ((array_key_exists('xchan_guid',$arr)) ? $arr['xchan_guid'] : ''),
'xchan_guid_sig' => ((array_key_exists('xchan_guid_sig',$arr)) ? $arr['xchan_guid_sig'] : ''),
'xchan_pubkey' => ((array_key_exists('xchan_pubkey',$arr)) ? $arr['xchan_pubkey'] : ''),
'xchan_photo_mimetype' => ((array_key_exists('xchan_photo_mimetype',$arr)) ? $arr['xchan_photo_mimetype'] : ''),
'xchan_photo_l' => ((array_key_exists('xchan_photo_l',$arr)) ? $arr['xchan_photo_l'] : ''),
'xchan_photo_m' => ((array_key_exists('xchan_photo_m',$arr)) ? $arr['xchan_photo_m'] : ''),
'xchan_photo_s' => ((array_key_exists('xchan_photo_s',$arr)) ? $arr['xchan_photo_s'] : ''),
'xchan_addr' => ((array_key_exists('xchan_addr',$arr)) ? $arr['xchan_addr'] : ''),
'xchan_url' => ((array_key_exists('xchan_url',$arr)) ? $arr['xchan_url'] : ''),
'xchan_connurl' => ((array_key_exists('xchan_connurl',$arr)) ? $arr['xchan_connurl'] : ''),
'xchan_follow' => ((array_key_exists('xchan_follow',$arr)) ? $arr['xchan_follow'] : ''),
'xchan_connpage' => ((array_key_exists('xchan_connpage',$arr)) ? $arr['xchan_connpage'] : ''),
'xchan_name' => ((array_key_exists('xchan_name',$arr)) ? $arr['xchan_name'] : ''),
'xchan_network' => ((array_key_exists('xchan_network',$arr)) ? $arr['xchan_network'] : ''),
'xchan_instance_url' => ((array_key_exists('xchan_instance_url',$arr)) ? $arr['xchan_instance_url'] : ''),
'xchan_flags' => ((array_key_exists('xchan_flags',$arr)) ? intval($arr['xchan_flags']) : 0),
'xchan_photo_date' => ((array_key_exists('xchan_photo_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_photo_date']) : NULL_DATE),
'xchan_name_date' => ((array_key_exists('xchan_name_date',$arr)) ? datetime_convert('UTC','UTC',$arr['xchan_name_date']) : NULL_DATE),
'xchan_hidden' => ((array_key_exists('xchan_hidden',$arr)) ? intval($arr['xchan_hidden']) : 0),
'xchan_orphan' => ((array_key_exists('xchan_orphan',$arr)) ? intval($arr['xchan_orphan']) : 0),
'xchan_censored' => ((array_key_exists('xchan_censored',$arr)) ? intval($arr['xchan_censored']) : 0),
'xchan_selfcensored' => ((array_key_exists('xchan_selfcensored',$arr)) ? intval($arr['xchan_selfcensored']) : 0),
'xchan_system' => ((array_key_exists('xchan_system',$arr)) ? intval($arr['xchan_system']) : 0),
'xchan_pubforum' => ((array_key_exists('xchan_pubforum',$arr)) ? intval($arr['xchan_pubforum']) : 0),
'xchan_deleted' => ((array_key_exists('xchan_deleted',$arr)) ? intval($arr['xchan_deleted']) : 0)
];
return create_table_from_array('xchan',$store);
}
function xchan_store($arr) {
logger('xchan_store: ' . print_r($arr,true));
if(! $arr['hash'])
$arr['hash'] = $arr['guid'];
if(! $arr['hash'])
return false;
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['hash'])
);
if($r)
return true;
if(! $arr['network'])
$arr['network'] = 'unknown';
if(! $arr['name'])
$arr['name'] = 'unknown';
if(! $arr['url'])
$arr['url'] = z_root();
if(! $arr['photo'])
$arr['photo'] = z_root() . '/' . get_default_profile_photo();
if($arr['network'] === 'zot') {
if((! $arr['key']) || (! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key']))) {
logger('Unable to verify signature for ' . $arr['hash']);
return false;
}
}
$x = [];
foreach($arr as $k => $v) {
if($k === 'key') {
$x['xchan_pubkey'] = $v;
continue;
}
if($k === 'photo') {
continue;
}
$x['xchan_' . $k] = $v;
}
$x['xchan_name_date'] = datetime_convert();
$r = xchan_store_lowlevel($x);
if(! $r)
return $r;
$photos = import_xchan_photo($arr['photo'],$arr['hash']);
$r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
dbesc(datetime_convert()),
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc($photos[3]),
dbesc($arr['hash'])
);
return $r;
}
function xchan_fetch($arr) {
$key = '';
if($arr['hash']) {
$key = 'xchan_hash';
$v = $arr['hash'];
}
elseif($arr['guid']) {
$key = 'xchan_guid';
$v = $arr['guid'];
}
elseif($arr['address']) {
$key = 'xchan_addr';
$v = $arr['address'];
}
if(! $key)
return false;
$r = q("select * from xchan where $key = '$v' limit 1");
if(! $r)
return false;
$ret = array();
foreach($r[0] as $k => $v) {
if($k === 'xchan_addr')
$ret['address'] = $v;
else
$ret[str_replace('xchan_','',$k)] = $v;
}
return $ret;
}
+2 -2
View File
@@ -170,7 +170,7 @@ function zidify_text($s) {
* @return string
*/
function red_zrl_callback($matches) {
require_once('include/hubloc.php');
$zrl = is_matrix_url($matches[2]);
$t = strip_zids($matches[2]);
@@ -215,7 +215,7 @@ function red_unescape_codeblock($m) {
function red_zrlify_img_callback($matches) {
require_once('include/hubloc.php');
$zrl = is_matrix_url($matches[2]);
$t = strip_zids($matches[2]);
+91 -89
View File
@@ -10,7 +10,6 @@
require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/hubloc.php');
require_once('include/queue_fn.php');
require_once('include/perm_upgrade.php');
@@ -169,6 +168,11 @@ function zot_best_algorithm($methods) {
if(\Zotlabs\Lib\System::get_server_role() !== 'pro')
return 'aes256cbc';
$x = [ 'methods' => $methods, 'result' => '' ];
call_hooks('zot_best_algorithm',$x);
if($x['result'])
return $x['result'];
if($methods) {
$x = explode(',',$methods);
if($x) {
@@ -413,29 +417,13 @@ function zot_refresh($them, $channel = null, $force = false) {
}
else {
$p = \Zotlabs\Access\Permissions::connect_perms($channel['channel_id']);
$my_perms = $p['perms'];
$automatic = $p['automatic'];
// new connection
$my_perms = null;
$automatic = false;
$role = get_pconfig($channel['channel_id'],'system','permissions_role');
if($role) {
$xx = \Zotlabs\Access\PermissionRoles::role_perms($role);
if($xx['perms_auto']) {
$automatic = true;
$default_perms = $xx['perms_connect'];
$my_perms = \Zotlabs\Access\Permissions::FilledPerms($default_perms);
}
}
if(! $my_perms) {
$m = \Zotlabs\Access\Permissions::FilledAutoperms($channel['channel_id']);
if($m) {
$automatic = true;
$my_perms = $m;
}
}
if($my_perms) {
foreach($my_perms as $k => $v) {
set_abconfig($channel['channel_id'],$x['hash'],'my_perms',$k,$v);
@@ -446,15 +434,17 @@ function zot_refresh($them, $channel = null, $force = false) {
if($closeness === false)
$closeness = 80;
$y = q("insert into abook ( abook_account, abook_channel, abook_closeness, abook_xchan, abook_created, abook_updated, abook_dob, abook_pending ) values ( %d, %d, %d, '%s', '%s', '%s', '%s', %d )",
intval($channel['channel_account_id']),
intval($channel['channel_id']),
intval($closeness),
dbesc($x['hash']),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($next_birthday),
intval(($automatic) ? 0 : 1)
$y = abook_store_lowlevel(
[
'abook_account' => intval($channel['channel_account_id']),
'abook_channel' => intval($channel['channel_id']),
'abook_closeness' => intval($closeness),
'abook_xchan' => $x['hash'],
'abook_created' => datetime_convert(),
'abook_updated' => datetime_convert(),
'abook_dob' => $next_birthday,
'abook_pending' => intval(($automatic) ? 0 : 1)
]
);
if($y) {
@@ -563,7 +553,7 @@ function zot_gethub($arr, $multiple = false) {
}
logger('zot_gethub: not found: ' . print_r($arr,true), LOGGER_DEBUG);
return null;
return false;
}
/**
@@ -754,28 +744,28 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
&& ($arr['site']['url'] != z_root()))
$arr['searchable'] = false;
$x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,
xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_selfcensored, xchan_deleted, xchan_pubforum )
values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d) ",
dbesc($xchan_hash),
dbesc($arr['guid']),
dbesc($arr['guid_sig']),
dbesc($arr['key']),
dbesc($arr['photo_mimetype']),
dbesc($arr['photo']),
dbesc($arr['address']),
dbesc($arr['url']),
dbesc($arr['connections_url']),
dbesc($arr['follow_url']),
dbesc($arr['connect_url']),
dbesc(($arr['name']) ? $arr['name'] : '-'),
dbesc('zot'),
dbescdate($arr['photo_updated']),
dbescdate($arr['name_updated']),
intval(1 - intval($arr['searchable'])),
intval($arr['adult_content']),
intval($arr['deleted']),
intval($arr['public_forum'])
$x = xchan_store_lowlevel(
[
'xchan_hash' => $xchan_hash,
'xchan_guid' => $arr['guid'],
'xchan_guid_sig' => $arr['guid_sig'],
'xchan_pubkey' => $arr['key'],
'xchan_photo_mimetype' => $arr['photo_mimetype'],
'xchan_photo_l' => $arr['photo'],
'xchan_addr' => $arr['address'],
'xchan_url' => $arr['url'],
'xchan_connurl' => $arr['connections_url'],
'xchan_follow' => $arr['follow_url'],
'xchan_connpage' => $arr['connect_url'],
'xchan_name' => (($arr['name']) ? $arr['name'] : '-'),
'xchan_network' => 'zot',
'xchan_photo_date' => $arr['photo_updated'],
'xchan_name_date' => $arr['name_updated'],
'xchan_hidden' => intval(1 - intval($arr['searchable'])),
'xchan_selfcensored' => $arr['adult_content'],
'xchan_deleted' => $arr['deleted'],
'xchan_pubforum' => $arr['public_forum']
]
);
$what .= 'new_xchan';
@@ -1946,6 +1936,7 @@ function update_imported_item($sender, $item, $orig, $uid, $tag_delivery) {
return;
}
$x = item_store_update($item);
// If we're updating an event that we've saved locally, we store the item info first
@@ -2463,22 +2454,25 @@ function sync_locations($sender, $arr, $absolute = false) {
);
}
logger('sync_locations: new hub: ' . $location['url']);
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_updated, hubloc_connected)
values ( '%s','%s','%s','%s', '%s', %d ,'%s','%s','%s','%s','%s','%s','%s')",
dbesc($sender['guid']),
dbesc($sender['guid_sig']),
dbesc($sender['hash']),
dbesc($location['address']),
dbesc('zot'),
intval($location['primary']),
dbesc($location['url']),
dbesc($location['url_sig']),
dbesc($location['host']),
dbesc($location['callback']),
dbesc($location['sitekey']),
dbesc(datetime_convert()),
dbesc(datetime_convert())
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $sender['guid'],
'hubloc_guid_sig' => $sender['guid_sig'],
'hubloc_hash' => $sender['hash'],
'hubloc_addr' => $location['address'],
'hubloc_network' => 'zot',
'hubloc_primary' => $location['primary'],
'hubloc_url' => $location['url'],
'hubloc_url_sig' => $location['url_sig'],
'hubloc_host' => $location['host'],
'hubloc_callback' => $location['callback'],
'hubloc_sitekey' => $location['sitekey'],
'hubloc_updated' => datetime_convert(),
'hubloc_connected' => datetime_convert()
]
);
$what .= 'newhub ';
$changed = true;
@@ -3168,8 +3162,11 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
if(array_key_exists('menu',$arr) && $arr['menu'])
sync_menus($channel,$arr['menu']);
if(array_key_exists('file',$arr) && $arr['file'])
sync_files($channel,$arr['file']);
if(array_key_exists('menu',$arr) && $arr['menu'])
sync_menus($channel,$arr['menu']);
if(array_key_exists('wiki',$arr) && $arr['wiki'])
sync_items($channel,$arr['wiki'],((array_key_exists('relocate',$arr)) ? $arr['relocate'] : null));
if(array_key_exists('channel',$arr) && is_array($arr['channel']) && count($arr['channel'])) {
@@ -3312,10 +3309,12 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
logger('process_channel_sync_delivery: total_feeds service class limit exceeded');
continue;
}
q("insert into abook ( abook_xchan, abook_account, abook_channel ) values ('%s', %d, %d ) ",
dbesc($clean['abook_xchan']),
intval($channel['channel_account_id']),
intval($channel['channel_id'])
abook_store_lowlevel(
[
'abook_xchan' => $clean['abook_xchan'],
'abook_account' => $channel['channel_account_id'],
'abook_channel' => $channel['channel_id']
]
);
$total_friends ++;
if(intval($clean['abook_feed']))
@@ -4048,21 +4047,24 @@ function check_zotinfo($channel,$locations,&$ret) {
q("delete from hubloc where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
dbesc($channel['channel_guid']),
dbesc($channel['channel_guid_sig']),
dbesc($channel['channel_hash']),
dbesc(channel_reddress($channel)),
intval(1),
dbesc(z_root()),
dbesc(base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))),
dbesc(App::get_hostname()),
dbesc(z_root() . '/post'),
dbesc(get_config('system','pubkey')),
dbesc('zot')
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
'hubloc_guid_sig' => $channel['channel_guid_sig'],
'hubloc_hash' => $channel['channel_hash'],
'hubloc_addr' => channel_reddress($channel),
'hubloc_network' => 'zot',
'hubloc_primary' => 1,
'hubloc_url' => z_root(),
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
'hubloc_host' => App::get_hostname(),
'hubloc_callback' => z_root() . '/post',
'hubloc_sitekey' => get_config('system','pubkey'),
'hubloc_updated' => datetime_convert(),
]
);
if($r) {
$x = zot_encode_locations($channel);
if($x) {