Merge branch 'master' into z6
This commit is contained in:
@@ -1,81 +0,0 @@
|
||||
<?php /** @file */
|
||||
|
||||
namespace Hubzilla\Import;
|
||||
|
||||
/**
|
||||
* @brief Class Import
|
||||
*
|
||||
*/
|
||||
class Import {
|
||||
|
||||
private $credentials = null;
|
||||
|
||||
protected $itemlist = null;
|
||||
protected $src_items = null;
|
||||
protected $items = null;
|
||||
|
||||
function get_credentials() {
|
||||
return $this->credentials;
|
||||
}
|
||||
|
||||
function get_itemlist() {
|
||||
return $this->itemlist;
|
||||
}
|
||||
|
||||
function get_item_ident($item) {
|
||||
|
||||
}
|
||||
|
||||
function get_item($item_ident) {
|
||||
|
||||
}
|
||||
|
||||
function get_taxonomy($item_ident) {
|
||||
|
||||
}
|
||||
|
||||
function get_children($item_ident) {
|
||||
|
||||
}
|
||||
|
||||
function convert_item($item_ident) {
|
||||
|
||||
}
|
||||
|
||||
function convert_taxonomy($item_ident) {
|
||||
|
||||
}
|
||||
|
||||
function convert_child($child) {
|
||||
|
||||
}
|
||||
|
||||
function store($item, $update = false) {
|
||||
|
||||
}
|
||||
|
||||
function run() {
|
||||
$this->credentials = $this->get_credentials();
|
||||
$this->itemlist = $this->get_itemlist();
|
||||
if($this->itemlist) {
|
||||
$this->src_items = array();
|
||||
$this->items = array();
|
||||
$cnt = 0;
|
||||
foreach($this->itemlist as $item) {
|
||||
$ident = $item->get_item_ident($item);
|
||||
$this->src_items[$ident]['item'] = $this->get_item($ident);
|
||||
$this->src_items[$ident]['taxonomy'] = $this->get_taxonomy($ident);
|
||||
$this->src_items[$ident]['children'] = $this->get_children($ident);
|
||||
$this->items[$cnt]['item'] = $this->convert_item($ident);
|
||||
$this->items[$cnt]['item']['term'] = $this->convert_taxonomy($ident);
|
||||
if($this->src_items[$ident]['children']) {
|
||||
$this->items[$cnt]['children'] = array();
|
||||
foreach($this->src_items[$ident]['children'] as $child) {
|
||||
$this[$cnt]['children'][] = $this->convert_child($child);
|
||||
}
|
||||
}
|
||||
$cnt ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once('include/html2bbcode.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
|
||||
// the user table to search for avatars. Importation was also batched in sets of 20 posts per page
|
||||
// visit so as to survive shared hosting process limits. This provides some clues as how to handle
|
||||
// WordPress imports, which use a somewhat similar DB structure. The batching and individual files
|
||||
// might not be needed in VPS environments. As such this could be considered an extreme test case, but
|
||||
// the importation was successful in all regards using this code. The module URL was visited repeatedly
|
||||
// with a browser until all the posts had been imported.
|
||||
|
||||
|
||||
define('REDMATRIX_IMPORTCHANNEL','mike');
|
||||
define('REFLECT_EXPORTUSERNAME','mike');
|
||||
define('REFLECT_BLOGNAME','Diary and Other Rantings');
|
||||
define('REFLECT_BASEURL','http://example.com/');
|
||||
define('REFLECT_USERFILE','user.json');
|
||||
|
||||
// set to true if you need to process everything again
|
||||
define('REFLECT_OVERWRITE',false);
|
||||
|
||||
// we'll only process a small number of posts at a time on a shared host.
|
||||
|
||||
define('REFLECT_MAXPERRUN',30);
|
||||
|
||||
function reflect_get_channel() {
|
||||
|
||||
// this will be the channel_address or nickname of the red channel
|
||||
|
||||
$c = q("select * from channel left join xchan on channel_hash = xchan_hash
|
||||
where channel_address = '%s' limit 1",
|
||||
dbesc(REDMATRIX_IMPORTCHANNEL)
|
||||
);
|
||||
return $c[0];
|
||||
}
|
||||
|
||||
|
||||
function refimport_content(&$a) {
|
||||
|
||||
$channel = reflect_get_channel();
|
||||
|
||||
// load the user file. We need that to find the commenter's avatars
|
||||
|
||||
$u = file_get_contents(REFLECT_USERFILE);
|
||||
if($u) {
|
||||
$users = json_decode($u,true);
|
||||
}
|
||||
|
||||
$ignored = 0;
|
||||
$processed = 0;
|
||||
|
||||
$files = glob('article/*');
|
||||
if(! $files)
|
||||
return;
|
||||
|
||||
foreach($files as $f) {
|
||||
$s = file_get_contents($f);
|
||||
$j = json_decode($s,true);
|
||||
|
||||
if(! $j)
|
||||
continue;
|
||||
|
||||
$arr = array();
|
||||
|
||||
// see if this article was already processed
|
||||
$r = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($j['guid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
if(REFLECT_OVERWRITE)
|
||||
$arr['id'] = $r[0]['id'];
|
||||
else {
|
||||
$ignored ++;
|
||||
rename($f,str_replace('article','done',$f));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$arr['uid'] = $channel['channel_account_id'];
|
||||
$arr['aid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $arr['parent_mid'] = $j['guid'];
|
||||
$arr['created'] = $j['created'];
|
||||
$arr['edited'] = $j['edited'];
|
||||
$arr['author_xchan'] = $channel['channel_hash'];
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['app'] = REFLECT_BLOGNAME;
|
||||
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_thread_top'] = 1;
|
||||
|
||||
$arr['verb'] = ACTIVITY_POST;
|
||||
|
||||
// this is an assumption
|
||||
$arr['comment_policy'] = 'contacts';
|
||||
|
||||
|
||||
// import content. In this case the content is XHTML.
|
||||
|
||||
$arr['title'] = html2bbcode($j['title']);
|
||||
$arr['title'] = htmlspecialchars($arr['title'],ENT_COMPAT,'UTF-8',false);
|
||||
|
||||
|
||||
$arr['body'] = html2bbcode($j['body']);
|
||||
$arr['body'] = htmlspecialchars($arr['body'],ENT_COMPAT,'UTF-8',false);
|
||||
|
||||
|
||||
// convert relative urls to other posts on that service to absolute url on our service.
|
||||
$arr['body'] = preg_replace_callback("/\[url\=\/+article\/(.*?)\](.*?)\[url\]/",'reflect_article_callback',$arr['body']);
|
||||
|
||||
// also import any photos
|
||||
$arr['body'] = preg_replace_callback("/\[img(.*?)\](.*?)\[\/img\]/",'reflect_photo_callback',$arr['body']);
|
||||
|
||||
|
||||
// add categories
|
||||
|
||||
if($j['taxonomy'] && is_array($j['taxonomy']) && count($j['taxonomy'])) {
|
||||
$arr['term'] = array();
|
||||
foreach($j['taxonomy'] as $tax) {
|
||||
$arr['term'][] = array(
|
||||
'uid' => $channel['channel_id'],
|
||||
'type' => TERM_CATEGORY,
|
||||
'otype' => TERM_OBJ_POST,
|
||||
'term' => trim($tax['name']),
|
||||
'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($tax['name']))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// store the item
|
||||
|
||||
if($arr['id'])
|
||||
item_store_update($arr);
|
||||
else
|
||||
item_store($arr);
|
||||
|
||||
// if there are any comments, process them
|
||||
// $comment['registered'] is somebody with an account on the system. Others are mostly anonymous
|
||||
|
||||
if($j['comments']) {
|
||||
foreach($j['comments'] as $comment) {
|
||||
$user = (($comment['registered']) ? reflect_find_user($users,$comment['author']) : null);
|
||||
reflect_comment_store($channel,$arr,$comment,$user);
|
||||
}
|
||||
}
|
||||
$processed ++;
|
||||
|
||||
if(REFLECT_MAXPERRUN && $processed > REFLECT_MAXPERRUN)
|
||||
break;
|
||||
}
|
||||
return 'processed: ' . $processed . EOL . 'completed: ' . $ignored . EOL;
|
||||
|
||||
}
|
||||
|
||||
function reflect_article_callback($matches) {
|
||||
return '[zrl=' . z_root() . '/display/'. $matches[1] . ']' . $matches[2] . '[/zrl]';
|
||||
}
|
||||
|
||||
function reflect_photo_callback($matches) {
|
||||
|
||||
if(strpos($matches[2],'http') !== false)
|
||||
return $matches[0];
|
||||
|
||||
$prefix = REFLECT_BASEURL;
|
||||
$x = z_fetch_url($prefix.$matches[2],true);
|
||||
|
||||
$hash = basename($matches[2]);
|
||||
|
||||
if($x['success']) {
|
||||
$channel = reflect_get_channel();
|
||||
require_once('include/photos.php');
|
||||
$p = photo_upload($channel,$channel,
|
||||
array('data' => $x['body'],
|
||||
'resource_id' => str_replace('-','',$hash),
|
||||
'filename' => $hash . '.jpg',
|
||||
'type' => 'image/jpeg',
|
||||
'visible' => false
|
||||
)
|
||||
);
|
||||
|
||||
if($p['success'])
|
||||
$newlink = $p['resource_id'] . '-0.jpg';
|
||||
|
||||
|
||||
// import photo and locate the link for it.
|
||||
return '[zmg]' . z_root() . '/photo/' . $newlink . '[/zmg]';
|
||||
|
||||
}
|
||||
// no replacement. Leave it alone.
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
function reflect_find_user($users,$name) {
|
||||
if($users) {
|
||||
foreach($users as $x) {
|
||||
if($x['name'] === $name) {
|
||||
return $x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function reflect_comment_store($channel,$post,$comment,$user) {
|
||||
|
||||
// if the commenter was the channel owner, use their hubzilla xchan
|
||||
|
||||
if($comment['author'] === REFLECT_EXPORTUSERNAME && $comment['registered'])
|
||||
$hash = $channel['xchan_hash'];
|
||||
else {
|
||||
// we need a unique hash for the commenter. We don't know how many may have supplied
|
||||
// http://yahoo.com as their URL, so we'll use their avatar guid if they have one.
|
||||
// anonymous folks may get more than one xchan_hash if they commented more than once.
|
||||
|
||||
$hash = (($comment['registered'] && $user) ? $user['avatar'] : '');
|
||||
if(! $hash)
|
||||
$hash = random_string() . '.unknown';
|
||||
|
||||
// create an xchan for them which will also import their profile photo
|
||||
// they will have a network type 'unknown'.
|
||||
|
||||
$x = array(
|
||||
'hash' => $hash,
|
||||
'guid' => $hash,
|
||||
'url' => (($comment['url']) ? $comment['url'] : z_root()),
|
||||
'photo' => (($user) ? REFLECT_BASEURL . $user['avatar'] : z_root() . '/' . get_default_profile_photo()),
|
||||
'name' => $comment['author']
|
||||
);
|
||||
xchan_store($x);
|
||||
|
||||
}
|
||||
|
||||
$arr = array();
|
||||
|
||||
$r = q("select * from item where mid = '%s' and uid = %d limit 1",
|
||||
dbesc($comment['guid']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
if(REFLECT_OVERWRITE)
|
||||
$arr['id'] = $r[0]['id'];
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
// this is a lot like storing the post except for subtle differences, like parent_mid, flags, author_xchan,
|
||||
// and we don't have a comment edited field so use creation date
|
||||
|
||||
$arr['uid'] = $channel['channel_account_id'];
|
||||
$arr['aid'] = $channel['channel_id'];
|
||||
$arr['mid'] = $comment['guid'];
|
||||
$arr['parent_mid'] = $post['mid'];
|
||||
$arr['created'] = $comment['created'];
|
||||
$arr['edited'] = $comment['created'];
|
||||
$arr['author_xchan'] = $hash;
|
||||
$arr['owner_xchan'] = $channel['channel_hash'];
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['verb'] = ACTIVITY_POST;
|
||||
$arr['comment_policy'] = 'contacts';
|
||||
|
||||
|
||||
$arr['title'] = html2bbcode($comment['title']);
|
||||
$arr['title'] = htmlspecialchars($arr['title'],ENT_COMPAT,'UTF-8',false);
|
||||
|
||||
|
||||
$arr['body'] = html2bbcode($comment['body']);
|
||||
$arr['body'] = htmlspecialchars($arr['body'],ENT_COMPAT,'UTF-8',false);
|
||||
$arr['body'] = preg_replace_callback("/\[url\=\/+article\/(.*?)\](.*?)\[url\]/",'reflect_article_callback',$arr['body']);
|
||||
$arr['body'] = preg_replace_callback("/\[img(.*?)\](.*?)\[\/img\]/",'reflect_photo_callback',$arr['body']);
|
||||
|
||||
// logger('comment: ' . print_r($arr,true));
|
||||
|
||||
if($arr['id'])
|
||||
item_store_update($arr);
|
||||
else
|
||||
item_store($arr);
|
||||
|
||||
}
|
||||
@@ -262,24 +262,46 @@ function create_account($arr) {
|
||||
|
||||
function verify_email_address($arr) {
|
||||
|
||||
$hash = random_string();
|
||||
if(array_key_exists('resend',$arr)) {
|
||||
$email = $arr['email'];
|
||||
$a = q("select * from account where account_email = '%s' limit 1",
|
||||
dbesc($arr['email'])
|
||||
);
|
||||
if(! ($a && ($a[0]['account_flags'] & ACCOUNT_UNVERIFIED))) {
|
||||
return false;
|
||||
}
|
||||
$account = $a[0];
|
||||
$v = q("select * from register where uid = %d and password = 'verify' limit 1",
|
||||
intval($account['account_id'])
|
||||
);
|
||||
if($v) {
|
||||
$hash = $v[0]['hash'];
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$hash = random_string(24);
|
||||
|
||||
$r = q("INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ",
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert()),
|
||||
intval($arr['account']['account_id']),
|
||||
dbesc('verify'),
|
||||
dbesc($arr['account']['account_language'])
|
||||
);
|
||||
$r = q("INSERT INTO register ( hash, created, uid, password, lang ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ",
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert()),
|
||||
intval($arr['account']['account_id']),
|
||||
dbesc('verify'),
|
||||
dbesc($arr['account']['account_language'])
|
||||
);
|
||||
$account = $arr['account'];
|
||||
}
|
||||
|
||||
push_lang(($arr['account']['account_language']) ? $arr['account']['account_language'] : 'en');
|
||||
push_lang(($account['account_language']) ? $account['account_language'] : 'en');
|
||||
|
||||
$email_msg = replace_macros(get_intltext_template('register_verify_member.tpl'),
|
||||
[
|
||||
'$sitename' => get_config('system','sitename'),
|
||||
'$siteurl' => z_root(),
|
||||
'$email' => $arr['email'],
|
||||
'$uid' => $arr['account']['account_id'],
|
||||
'$uid' => $account['account_id'],
|
||||
'$hash' => $hash,
|
||||
'$details' => $details
|
||||
]
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
api_register_func('api/export/basic','api_export_basic', true);
|
||||
api_register_func('api/red/channel/export/basic','api_export_basic', true);
|
||||
api_register_func('api/z/1.0/channel/export/basic','api_export_basic', true);
|
||||
api_register_func('api/red/channel/list','api_channel_list', true);
|
||||
api_register_func('api/z/1.0/channel/list','api_channel_list', true);
|
||||
api_register_func('api/red/channel/stream','api_channel_stream', true);
|
||||
api_register_func('api/z/1.0/channel/stream','api_channel_stream', true);
|
||||
api_register_func('api/red/files','api_attach_list', true);
|
||||
@@ -111,9 +113,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
function api_channel_list($type) {
|
||||
if(api_user() === false) {
|
||||
logger('api_channel_stream: no user');
|
||||
return false;
|
||||
}
|
||||
|
||||
$channel = channelx_by_n(api_user());
|
||||
if(! $channel)
|
||||
return false;
|
||||
|
||||
$ret = [];
|
||||
|
||||
$r = q("select channel_address from channel where channel_account_id = %d",
|
||||
intval($channel['channel_account_id'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
$ret[] = $rv['channel_address'];
|
||||
}
|
||||
}
|
||||
|
||||
json_return_and_die($ret);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function api_channel_stream($type) {
|
||||
|
||||
@@ -261,6 +261,7 @@ else {
|
||||
$verify = account_verify_password($_POST['username'], $_POST['password']);
|
||||
if($verify && array_key_exists('reason',$verify) && $verify['reason'] === 'unvalidated') {
|
||||
notice( t('Email validation is incomplete. Please check your email.'));
|
||||
goaway(z_root() . '/email_validation/' . bin2hex(trim(escape_tags($_POST['username']))));
|
||||
}
|
||||
elseif($verify) {
|
||||
$atoken = $verify['xchan'];
|
||||
|
||||
@@ -108,7 +108,11 @@ function tryzrlvideo($match) {
|
||||
if($zrl)
|
||||
$link = zid($link);
|
||||
|
||||
return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
|
||||
$static_link = get_config('system','video_default_poster','images/video_poster.jpg');
|
||||
if($static_link)
|
||||
$poster = 'poster="' . escape_tags($static_link) . '" ' ;
|
||||
|
||||
return '<video ' . $poster . ' controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
|
||||
}
|
||||
|
||||
// [noparse][i]italic[/i][/noparse] turns into
|
||||
@@ -610,11 +614,23 @@ function bb_observer($Text) {
|
||||
return $Text;
|
||||
}
|
||||
|
||||
function bb_code_protect($s) {
|
||||
return 'b64.^9e%.' . base64_encode($s) . '.b64.$9e%';
|
||||
}
|
||||
|
||||
function bb_code_unprotect($s) {
|
||||
return preg_replace_callback('|b64\.\^9e\%\.(.*?)\.b64\.\$9e\%|ism','bb_code_unprotect_sub',$s);
|
||||
}
|
||||
|
||||
function bb_code_unprotect_sub($match) {
|
||||
return base64_decode($match[1]);
|
||||
}
|
||||
|
||||
function bb_code($match) {
|
||||
if(strpos($match[0], "<br />"))
|
||||
return '<code>' . trim($match[1]) . '</code>';
|
||||
return '<code>' . bb_code_protect(trim($match[1])) . '</code>';
|
||||
else
|
||||
return '<code class="inline-code">' . trim($match[1]) . '</code>';
|
||||
return '<code class="inline-code">' . bb_code_protect(trim($match[1])) . '</code>';
|
||||
}
|
||||
|
||||
function bb_code_options($match) {
|
||||
@@ -628,11 +644,11 @@ function bb_code_options($match) {
|
||||
} else {
|
||||
$style = "";
|
||||
}
|
||||
return '<code class="'. $class .'" style="'. $style .'">' . trim($match[2]) . '</code>';
|
||||
return '<code class="'. $class .'" style="'. $style .'">' . bb_code_protect(trim($match[2])) . '</code>';
|
||||
}
|
||||
|
||||
function bb_highlight($match) {
|
||||
return text_highlight($match[2],strtolower($match[1]));
|
||||
return bb_code_protect(text_highlight($match[2],strtolower($match[1])));
|
||||
}
|
||||
|
||||
function bb_fixtable_lf($match) {
|
||||
@@ -822,6 +838,17 @@ function bbcode($Text, $options = []) {
|
||||
|
||||
$Text = str_replace(array("\t", " "), array(" ", " "), $Text);
|
||||
|
||||
|
||||
// Check for [code] text
|
||||
if (strpos($Text,'[code]') !== 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);
|
||||
}
|
||||
|
||||
// Set up the parameters for a URL search string
|
||||
$URLSearchString = "^\[\]";
|
||||
// Set up the parameters for a MAIL search string
|
||||
@@ -1062,16 +1089,6 @@ function bbcode($Text, $options = []) {
|
||||
$Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/sm", "<span style=\"font-family: $1;\">$2</span>", $Text);
|
||||
}
|
||||
|
||||
// Check for [code] text
|
||||
if (strpos($Text,'[code]') !== 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);
|
||||
}
|
||||
|
||||
|
||||
if(strpos($Text,'[/summary]') !== false) {
|
||||
$Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", 'bb_summary', $Text);
|
||||
@@ -1288,6 +1305,7 @@ function bbcode($Text, $options = []) {
|
||||
|
||||
// replace escaped links in code= blocks
|
||||
$Text = str_replace('%eY9-!','http', $Text);
|
||||
$Text = bb_code_unprotect($Text);
|
||||
|
||||
$Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
|
||||
|
||||
|
||||
@@ -321,6 +321,10 @@ function db_concat($fld, $sep) {
|
||||
return \DBA::$dba->concat($fld, $sep);
|
||||
}
|
||||
|
||||
function db_use_index($str) {
|
||||
return \DBA::$dba->use_index($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute a SQL query with printf style args.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,7 @@ class dba_pdo extends dba_driver {
|
||||
$dsn = $server;
|
||||
}
|
||||
else {
|
||||
$dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? '' : ';port=' . $port);
|
||||
$dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : '');
|
||||
}
|
||||
|
||||
$dsn .= ';dbname=' . $db;
|
||||
@@ -111,6 +111,15 @@ class dba_pdo extends dba_driver {
|
||||
}
|
||||
}
|
||||
|
||||
function use_index($str) {
|
||||
if($this->driver_dbtype === 'pgsql') {
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
return 'USE INDEX( ' . $str . ')';
|
||||
}
|
||||
}
|
||||
|
||||
function quote_interval($txt) {
|
||||
if($this->driver_dbtype === 'pgsql') {
|
||||
return "'$txt'";
|
||||
@@ -154,4 +163,4 @@ class dba_pdo extends dba_driver {
|
||||
return 'pdo';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,16 @@ function get_features($filtered = true) {
|
||||
feature_level('event_tz_select',2),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'premium_channel',
|
||||
t('Premium Channel'),
|
||||
t('Allows you to set restrictions and terms on those that connect with your channel'),
|
||||
false,
|
||||
get_config('feature_lock','premium_channel'),
|
||||
feature_level('premium_channel',4),
|
||||
],
|
||||
|
||||
[
|
||||
'advanced_dirsearch',
|
||||
t('Advanced Directory Search'),
|
||||
@@ -438,16 +448,10 @@ function get_features($filtered = true) {
|
||||
],
|
||||
];
|
||||
|
||||
$x = [ 'features' => $arr, ];
|
||||
call_hooks('get_features',$x);
|
||||
|
||||
$arr['general'][] = [
|
||||
'premium_channel',
|
||||
t('Premium Channel'),
|
||||
t('Allows you to set restrictions and terms on those that connect with your channel'),
|
||||
false,
|
||||
get_config('feature_lock','premium_channel'),
|
||||
feature_level('premium_channel',4),
|
||||
];
|
||||
|
||||
$arr = $x['features'];
|
||||
|
||||
$techlevel = get_account_techlevel();
|
||||
|
||||
@@ -482,7 +486,5 @@ function get_features($filtered = true) {
|
||||
$narr = $arr;
|
||||
}
|
||||
|
||||
$x = [ 'features' => $narr, 'filtered' => $filtered, 'techlevel' => $techlevel ];
|
||||
call_hooks('get_features',$x);
|
||||
return $x['features'];
|
||||
return $narr;
|
||||
}
|
||||
|
||||
@@ -15,15 +15,6 @@
|
||||
*/
|
||||
function get_public_feed($channel, $params) {
|
||||
|
||||
/* $type = 'xml';
|
||||
$begin = NULL_DATE;
|
||||
$end = '';
|
||||
$start = 0;
|
||||
$records = 40;
|
||||
$direction = 'desc';
|
||||
$pages = 0;
|
||||
*/
|
||||
|
||||
if(! $params)
|
||||
$params = [];
|
||||
|
||||
@@ -106,23 +97,15 @@ function get_feed_for($channel, $observer_hash, $params) {
|
||||
$owner = atom_render_author('zot:owner',$channel);
|
||||
|
||||
$atom .= replace_macros($feed_template, array(
|
||||
'$version' => xmlify(Zotlabs\Lib\System::get_project_version()),
|
||||
'$red' => xmlify(Zotlabs\Lib\System::get_platform_name()),
|
||||
'$feed_id' => xmlify($channel['xchan_url']),
|
||||
'$feed_title' => xmlify($channel['channel_name']),
|
||||
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
|
||||
'$author' => $feed_author,
|
||||
'$owner' => $owner,
|
||||
'$name' => xmlify($channel['channel_name']),
|
||||
'$profile_page' => xmlify($channel['xchan_url']),
|
||||
'$mimephoto' => xmlify($channel['xchan_photo_mimetype']),
|
||||
'$photo' => xmlify($channel['xchan_photo_l']),
|
||||
'$thumb' => xmlify($channel['xchan_photo_m']),
|
||||
'$picdate' => '',
|
||||
'$uridate' => '',
|
||||
'$namdate' => '',
|
||||
'$birthday' => '',
|
||||
'$community' => '',
|
||||
'$version' => xmlify(Zotlabs\Lib\System::get_project_version()),
|
||||
'$generator' => xmlify(Zotlabs\Lib\System::get_platform_name()),
|
||||
'$generator_uri' => 'https://hubzilla.org',
|
||||
'$feed_id' => xmlify($channel['xchan_url']),
|
||||
'$feed_title' => xmlify($channel['channel_name']),
|
||||
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', 'now', ATOM_TIME)),
|
||||
'$author' => $feed_author,
|
||||
'$owner' => $owner,
|
||||
'$profile_page' => xmlify($channel['xchan_url']),
|
||||
));
|
||||
|
||||
|
||||
@@ -270,19 +253,18 @@ function construct_activity_target($item) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return an array with a parsed atom item.
|
||||
* @brief Return an array with a parsed atom author.
|
||||
*
|
||||
* @param SimplePie $feed
|
||||
* @param array $item
|
||||
* @param[out] array $author
|
||||
* @return array Associative array with the parsed item data
|
||||
* @param SimplePie $item
|
||||
* @return array $author
|
||||
*/
|
||||
function get_atom_elements($feed, $item, &$author) {
|
||||
|
||||
require_once('include/html2bbcode.php');
|
||||
function get_atom_author($feed, $item) {
|
||||
|
||||
$res = array();
|
||||
$author = [];
|
||||
|
||||
$found_author = $item->get_author();
|
||||
if($found_author) {
|
||||
@@ -307,52 +289,6 @@ function get_atom_elements($feed, $item, &$author) {
|
||||
if(substr($author['author_link'],-1,1) == '/')
|
||||
$author['author_link'] = substr($author['author_link'],0,-1);
|
||||
|
||||
$res['mid'] = normalise_id(unxmlify($item->get_id()));
|
||||
$res['title'] = unxmlify($item->get_title());
|
||||
$res['body'] = unxmlify($item->get_content());
|
||||
$res['plink'] = unxmlify($item->get_link(0));
|
||||
$res['item_rss'] = 1;
|
||||
|
||||
|
||||
$summary = unxmlify($item->get_description(true));
|
||||
|
||||
// removing the content of the title if its identically to the body
|
||||
// This helps with auto generated titles e.g. from tumblr
|
||||
|
||||
if (title_is_body($res['title'], $res['body']))
|
||||
$res['title'] = "";
|
||||
|
||||
if($res['plink'])
|
||||
$base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
|
||||
else
|
||||
$base_url = '';
|
||||
|
||||
|
||||
$rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published');
|
||||
if($rawcreated)
|
||||
$res['created'] = unxmlify($rawcreated[0]['data']);
|
||||
|
||||
$rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated');
|
||||
if($rawedited)
|
||||
$res['edited'] = unxmlify($rawedited[0]['data']);
|
||||
|
||||
if((x($res,'edited')) && (! (x($res,'created'))))
|
||||
$res['created'] = $res['edited'];
|
||||
|
||||
if(! $res['created'])
|
||||
$res['created'] = $item->get_date('c');
|
||||
|
||||
if(! $res['edited'])
|
||||
$res['edited'] = $item->get_date('c');
|
||||
|
||||
$rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
|
||||
|
||||
// select between supported verbs
|
||||
|
||||
if($rawverb) {
|
||||
$res['verb'] = unxmlify($rawverb[0]['data']);
|
||||
}
|
||||
|
||||
|
||||
// look for a photo. We should check media size and find the best one,
|
||||
// but for now let's just find any author photo
|
||||
@@ -431,6 +367,112 @@ function get_atom_elements($feed, $item, &$author) {
|
||||
}
|
||||
}
|
||||
|
||||
$rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
|
||||
if(! $rawowner)
|
||||
$rawowner = $item->get_item_tags(NAMESPACE_ZOT, 'owner');
|
||||
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
|
||||
$author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
|
||||
elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
|
||||
$author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
|
||||
$author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
|
||||
elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
|
||||
$author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
|
||||
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
|
||||
$base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
|
||||
|
||||
foreach($base as $link) {
|
||||
if(!x($author, 'owner_photo') || ! $author['owner_photo']) {
|
||||
if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
|
||||
$author['owner_photo'] = unxmlify($link['attribs']['']['href']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build array to pass to hook
|
||||
$arr = [
|
||||
'feed' => $feed,
|
||||
'item' => $item,
|
||||
'author' => $author
|
||||
];
|
||||
/**
|
||||
* @hooks parse_atom
|
||||
* * \e SimplePie \b feed - The original SimplePie feed
|
||||
* * \e SimplePie \b item
|
||||
* * \e array \b result - the result array that will also get returned
|
||||
*/
|
||||
call_hooks('parse_atom_author', $arr);
|
||||
|
||||
logger('author: ' . print_r($arr['author'], true), LOGGER_DATA);
|
||||
|
||||
return $arr['author'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return an array with a parsed atom item.
|
||||
*
|
||||
* @param SimplePie $feed
|
||||
* @param SimplePie $item
|
||||
* @param[out] array $author
|
||||
* @return array Associative array with the parsed item data
|
||||
*/
|
||||
|
||||
function get_atom_elements($feed, $item) {
|
||||
|
||||
require_once('include/html2bbcode.php');
|
||||
|
||||
$res = array();
|
||||
|
||||
|
||||
$res['mid'] = normalise_id(unxmlify($item->get_id()));
|
||||
$res['title'] = unxmlify($item->get_title());
|
||||
$res['body'] = unxmlify($item->get_content());
|
||||
$res['plink'] = unxmlify($item->get_link(0));
|
||||
$res['item_rss'] = 1;
|
||||
|
||||
|
||||
$summary = unxmlify($item->get_description(true));
|
||||
|
||||
// removing the content of the title if its identically to the body
|
||||
// This helps with auto generated titles e.g. from tumblr
|
||||
|
||||
if (title_is_body($res['title'], $res['body']))
|
||||
$res['title'] = "";
|
||||
|
||||
if($res['plink'])
|
||||
$base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
|
||||
else
|
||||
$base_url = '';
|
||||
|
||||
|
||||
$rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published');
|
||||
if($rawcreated)
|
||||
$res['created'] = unxmlify($rawcreated[0]['data']);
|
||||
|
||||
$rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated');
|
||||
if($rawedited)
|
||||
$res['edited'] = unxmlify($rawedited[0]['data']);
|
||||
|
||||
if((x($res,'edited')) && (! (x($res,'created'))))
|
||||
$res['created'] = $res['edited'];
|
||||
|
||||
if(! $res['created'])
|
||||
$res['created'] = $item->get_date('c');
|
||||
|
||||
if(! $res['edited'])
|
||||
$res['edited'] = $item->get_date('c');
|
||||
|
||||
$rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
|
||||
|
||||
// select between supported verbs
|
||||
|
||||
if($rawverb) {
|
||||
$res['verb'] = unxmlify($rawverb[0]['data']);
|
||||
}
|
||||
|
||||
$rawcnv = $item->get_item_tags(NAMESPACE_OSTATUS, 'conversation');
|
||||
if($rawcnv) {
|
||||
// new style
|
||||
@@ -588,29 +630,6 @@ function get_atom_elements($feed, $item, &$author) {
|
||||
$res['created'] = datetime_convert('UTC','UTC',$res['created']);
|
||||
$res['edited'] = datetime_convert('UTC','UTC',$res['edited']);
|
||||
|
||||
$rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
|
||||
if(! $rawowner)
|
||||
$rawowner = $item->get_item_tags(NAMESPACE_ZOT, 'owner');
|
||||
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
|
||||
$author['owner_name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
|
||||
elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
|
||||
$author['owner_name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
|
||||
$author['owner_link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
|
||||
elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
|
||||
$author['owner_link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
|
||||
|
||||
if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
|
||||
$base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
|
||||
|
||||
foreach($base as $link) {
|
||||
if(!x($author, 'owner_photo') || ! $author['owner_photo']) {
|
||||
if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
|
||||
$author['owner_photo'] = unxmlify($link['attribs']['']['href']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point');
|
||||
if($rawgeo)
|
||||
@@ -773,19 +792,16 @@ function get_atom_elements($feed, $item, &$author) {
|
||||
$arr = [
|
||||
'feed' => $feed,
|
||||
'item' => $item,
|
||||
'author' => $author,
|
||||
'result' => $res
|
||||
];
|
||||
/**
|
||||
* @hooks parse_atom
|
||||
* * \e SimplePie \b feed - The original SimplePie feed
|
||||
* * \e array \b item
|
||||
* * \e array \b author
|
||||
* * \e SimplePie \b item
|
||||
* * \e array \b result - the result array that will also get returned
|
||||
*/
|
||||
call_hooks('parse_atom', $arr);
|
||||
|
||||
logger('author: ' .print_r($arr['author'], true), LOGGER_DATA);
|
||||
logger('result: ' .print_r($arr['result'], true), LOGGER_DATA);
|
||||
|
||||
return $arr['result'];
|
||||
@@ -1074,8 +1090,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
|
||||
// Have we seen it? If not, import it.
|
||||
|
||||
$author = array();
|
||||
$datarray = get_atom_elements($feed,$item,$author);
|
||||
$author = get_atom_author($feed,$item);
|
||||
$datarray = get_atom_elements($feed,$item);
|
||||
|
||||
if(! $datarray['mid'])
|
||||
continue;
|
||||
@@ -1327,8 +1343,8 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
||||
|
||||
// Head post of a conversation. Have we seen it? If not, import it.
|
||||
|
||||
$author = array();
|
||||
$datarray = get_atom_elements($feed,$item,$author);
|
||||
$author = get_atom_author($feed,$item);
|
||||
$datarray = get_atom_elements($feed,$item);
|
||||
|
||||
if(! $datarray['mid'])
|
||||
continue;
|
||||
@@ -1530,11 +1546,11 @@ function normalise_id($id) {
|
||||
*/
|
||||
function process_salmon_feed($xml, $importer) {
|
||||
|
||||
$ret = array();
|
||||
$ret = [];
|
||||
|
||||
if(! strlen($xml)) {
|
||||
logger('process_feed: empty input');
|
||||
return;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$feed = new SimplePie();
|
||||
@@ -1548,8 +1564,10 @@ function process_salmon_feed($xml, $importer) {
|
||||
|
||||
$feed->init();
|
||||
|
||||
if($feed->error())
|
||||
if($feed->error()) {
|
||||
logger('Error parsing XML: ' . $feed->error());
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$permalink = $feed->get_permalink();
|
||||
|
||||
@@ -1576,16 +1594,13 @@ function process_salmon_feed($xml, $importer) {
|
||||
if($is_reply)
|
||||
$ret['parent_mid'] = $parent_mid;
|
||||
|
||||
$ret['author'] = array();
|
||||
|
||||
$datarray = get_atom_elements($feed, $item, $ret['author']);
|
||||
$ret['author'] = get_atom_author($feed,$item);
|
||||
$ret['item'] = get_atom_elements($feed,$item);
|
||||
|
||||
// reset policies which are restricted by default for RSS connections
|
||||
// This item is likely coming from GNU-social via salmon and allows public interaction
|
||||
$datarray['public_policy'] = '';
|
||||
$datarray['comment_policy'] = 'authenticated';
|
||||
|
||||
$ret['item'] = $datarray;
|
||||
$ret['item']['public_policy'] = '';
|
||||
$ret['item']['comment_policy'] = 'authenticated';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1843,10 +1858,24 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
|
||||
|
||||
create_export_photo_body($item);
|
||||
|
||||
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
|
||||
$body = fix_private_photos($item['body'],$owner['uid'],$item,$cid);
|
||||
// provide separate summary and content unless compat is true; as summary represents a content-warning on some networks
|
||||
|
||||
$matches = false;
|
||||
if(preg_match('|\[summary\](.*?)\[/summary\]|ism',$item['body'],$matches))
|
||||
$summary = $matches[1];
|
||||
else
|
||||
$body = $item['body'];
|
||||
$summary = '';
|
||||
|
||||
$body = $item['body'];
|
||||
|
||||
if($summary)
|
||||
$body = preg_replace('|^(.*?)\[summary\](.*?)\[/summary\](.*?)$|ism','$1$3',$item['body']);
|
||||
|
||||
if($compat)
|
||||
$summary = '';
|
||||
|
||||
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
|
||||
$body = fix_private_photos($body,$owner['uid'],$item,$cid);
|
||||
|
||||
if($compat) {
|
||||
$compat_photos = compat_photos_list($body);
|
||||
@@ -1887,6 +1916,8 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
|
||||
}
|
||||
else {
|
||||
$o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n";
|
||||
if($summary)
|
||||
$o .= '<summary type="' . $type . '" >' . xmlify(prepare_text($summary,$item['mimetype'])) . '</summary>' . "\r\n";
|
||||
$o .= '<content type="' . $type . '" >' . xmlify(prepare_text($body,$item['mimetype'])) . '</content>' . "\r\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,24 @@ function hubloc_mark_as_down($posturl) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief return comma separated string of non-dead clone locations (net addresses) for a given netid
|
||||
*
|
||||
* @param string $netid network identity (typically xchan_hash or hubloc_hash)
|
||||
* @return string
|
||||
*/
|
||||
|
||||
function locations_by_netid($netid) {
|
||||
|
||||
$locs = q("select hubloc_addr as location from hubloc left join site on hubloc_url = site_url where hubloc_hash = '%s' and hubloc_deleted = 0 and site_dead = 0",
|
||||
dbesc($netid)
|
||||
);
|
||||
|
||||
return array_elm_to_str($locs,'location',', ');
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ping_site($url) {
|
||||
|
||||
|
||||
@@ -82,7 +82,8 @@ function import_channel($channel, $account_id, $seize) {
|
||||
'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall',
|
||||
'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall',
|
||||
'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish',
|
||||
'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt'
|
||||
'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt',
|
||||
'channel_moved'
|
||||
];
|
||||
|
||||
$clean = array();
|
||||
|
||||
@@ -390,7 +390,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
|
||||
$arr['comment_policy'] = map_scope(\Zotlabs\Access\PermissionLimits::Get($channel['channel_id'],'post_comments'));
|
||||
|
||||
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
|
||||
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']);
|
||||
$arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']),0,190);
|
||||
}
|
||||
|
||||
|
||||
@@ -3009,14 +3009,17 @@ function check_item_source($uid, $item) {
|
||||
$words = explode("\n",$r[0]['src_patt']);
|
||||
if($words) {
|
||||
foreach($words as $word) {
|
||||
if(substr($word,0,1) === '#' && $tags) {
|
||||
$w = trim($word);
|
||||
if(! $w)
|
||||
continue;
|
||||
if(substr($w,0,1) === '#' && $tags) {
|
||||
foreach($tags as $t)
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($word,1)) || (substr($word,1) === '*')))
|
||||
if((($t['ttype'] == TERM_HASHTAG) || ($t['ttype'] == TERM_COMMUNITYTAG)) && (($t['term'] === substr($w,1)) || (substr($w,1) === '*')))
|
||||
return true;
|
||||
}
|
||||
elseif((strpos($word,'/') === 0) && preg_match($word,$text))
|
||||
elseif((strpos($w,'/') === 0) && preg_match($w,$text))
|
||||
return true;
|
||||
elseif(stristr($text,$word) !== false)
|
||||
elseif(stristr($text,$w) !== false)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,35 @@ function get_best_language() {
|
||||
}
|
||||
}
|
||||
|
||||
if(! isset($preferred))
|
||||
|
||||
if(! isset($preferred)) {
|
||||
|
||||
/*
|
||||
* We could find no perfect match for any of the preferred languages.
|
||||
* For cases where the preference is fr-fr and we have fr but *not* fr-fr
|
||||
* run the test again and only look for the language base
|
||||
* which should provide an interface they can sort of understand
|
||||
*/
|
||||
|
||||
if(isset($langs) && count($langs)) {
|
||||
foreach ($langs as $lang => $v) {
|
||||
if(strlen($lang) === 2) {
|
||||
/* we have already checked this language */
|
||||
continue;
|
||||
}
|
||||
/* Check the base */
|
||||
$lang = strtolower(substr($lang,0,2));
|
||||
if(is_dir("view/$lang")) {
|
||||
$preferred = $lang;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(! isset($preferred)) {
|
||||
$preferred = 'unset';
|
||||
}
|
||||
|
||||
$arr = array('langs' => $langs, 'preferred' => $preferred);
|
||||
|
||||
@@ -86,6 +113,12 @@ function get_best_language() {
|
||||
return ((isset(App::$config['system']['language'])) ? App::$config['system']['language'] : 'en');
|
||||
}
|
||||
|
||||
/*
|
||||
* push_lang and pop_lang let you temporarily override the default language.
|
||||
* Often used to email the administrator during a session created in another language.
|
||||
* The stack is one level deep - so you must pop after every push.
|
||||
*/
|
||||
|
||||
|
||||
function push_lang($language) {
|
||||
|
||||
|
||||
@@ -100,38 +100,6 @@ EOT;
|
||||
|
||||
if(local_channel()) {
|
||||
|
||||
|
||||
|
||||
$nav['network'] = array('network', t('Activity'), "", t('Network Activity'),'network_nav_btn');
|
||||
$nav['network']['all'] = [ 'network', t('View your network activity'), '','' ];
|
||||
$nav['network']['mark'] = array('', t('Mark all activity 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'), '','');
|
||||
|
||||
|
||||
$nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections'),'connections_nav_btn');
|
||||
if(is_site_admin())
|
||||
$nav['registrations'] = array('admin/accounts', t('Registrations'), "", t('Registrations'),'registrations_nav_btn');
|
||||
|
||||
|
||||
$nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'),'notifications_nav_btn');
|
||||
$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('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'));
|
||||
$nav['messages']['new'] = array('mail/new', t('New Message'), "", t('New Message'));
|
||||
|
||||
|
||||
$nav['all_events'] = array('events', t('Events'), "", t('Event Calendar'),'events_nav_btn');
|
||||
$nav['all_events']['all']=array('events', t('View events'), "", "");
|
||||
$nav['all_events']['mark'] = array('', t('Mark all events seen'), '','');
|
||||
|
||||
if(! $_SESSION['delegate']) {
|
||||
$nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels'),'manage_nav_btn');
|
||||
}
|
||||
|
||||
@@ -1579,6 +1579,7 @@ function get_site_info() {
|
||||
$channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat'));
|
||||
$channels_active_monthly_stat = intval(get_config('system','channels_active_monthly_stat'));
|
||||
$local_posts_stat = intval(get_config('system','local_posts_stat'));
|
||||
$local_comments_stat = intval(get_config('system','local_comments_stat'));
|
||||
$hide_in_statistics = intval(get_config('system','hide_in_statistics'));
|
||||
$site_expire = intval(get_config('system', 'default_expire_days'));
|
||||
|
||||
@@ -1612,13 +1613,14 @@ function get_site_info() {
|
||||
'default_service_restrictions' => $service_class,
|
||||
'locked_features' => $locked_features,
|
||||
'admin' => $admin,
|
||||
'dbdriver' => DBA::$dba->getdriver(),
|
||||
'dbdriver' => DBA::$dba->getdriver() . ' ' . ((ACTIVE_DBTYPE == DBTYPE_POSTGRES) ? 'postgres' : 'mysql'),
|
||||
'lastpoll' => get_config('system','lastpoll'),
|
||||
'info' => (($site_info) ? $site_info : ''),
|
||||
'channels_total' => $channels_total_stat,
|
||||
'channels_active_halfyear' => $channels_active_halfyear_stat,
|
||||
'channels_active_monthly' => $channels_active_monthly_stat,
|
||||
'local_posts' => $local_posts_stat,
|
||||
'local_comments' => $local_comments_stat,
|
||||
'hide_in_statistics' => $hide_in_statistics
|
||||
];
|
||||
|
||||
|
||||
@@ -179,6 +179,66 @@ function reload_plugins() {
|
||||
}
|
||||
|
||||
|
||||
function plugins_installed_list() {
|
||||
|
||||
$r = q("select * from addon where installed = 1 order by aname asc");
|
||||
return(($r) ? ids_to_array($r,'aname') : []);
|
||||
}
|
||||
|
||||
|
||||
function plugins_sync() {
|
||||
|
||||
/**
|
||||
*
|
||||
* Synchronise plugins:
|
||||
*
|
||||
* App::$config['system']['addon'] contains a comma-separated list of names
|
||||
* of plugins/addons which are used on this system.
|
||||
* Go through the database list of already installed addons, and if we have
|
||||
* an entry, but it isn't in the config list, call the unload procedure
|
||||
* and mark it uninstalled in the database (for now we'll remove it).
|
||||
* Then go through the config list and if we have a plugin that isn't installed,
|
||||
* call the install procedure and add it to the database.
|
||||
*
|
||||
*/
|
||||
|
||||
$installed = plugins_installed_list();
|
||||
|
||||
$plugins = get_config('system', 'addon', '');
|
||||
|
||||
$plugins_arr = explode(',', $plugins);
|
||||
|
||||
// array_trim is in include/text.php
|
||||
|
||||
if(! array_walk($plugins_arr,'array_trim'))
|
||||
return;
|
||||
|
||||
App::$plugins = $plugins_arr;
|
||||
|
||||
$installed_arr = [];
|
||||
|
||||
if(count($installed)) {
|
||||
foreach($installed as $i) {
|
||||
if(! in_array($i, $plugins_arr)) {
|
||||
unload_plugin($i);
|
||||
}
|
||||
else {
|
||||
$installed_arr[] = $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($plugins_arr)) {
|
||||
foreach($plugins_arr as $p) {
|
||||
if(! in_array($p, $installed_arr)) {
|
||||
load_plugin($p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get a list of non hidden addons.
|
||||
*
|
||||
|
||||
@@ -313,39 +313,25 @@ function dir_tagadelic($count = 0, $hub = '') {
|
||||
|
||||
$count = intval($count);
|
||||
|
||||
$dirmode = get_config('system','directory_mode');
|
||||
|
||||
if(($dirmode == DIRECTORY_MODE_STANDALONE) && (! $hub)) {
|
||||
$hub = \App::get_hostname();
|
||||
}
|
||||
|
||||
if($hub)
|
||||
$hub_query = " and xtag_hash in (select hubloc_hash from hubloc where hubloc_host = '" . protect_sprintf(dbesc($hub)) . "') ";
|
||||
else
|
||||
$hub_query = '';
|
||||
|
||||
if($hub_query) {
|
||||
// Fetch tags
|
||||
if($hub) {
|
||||
$r = q("select xtag_term as term, count(xtag_term) as total from xtag
|
||||
left join hubloc on xtag_hash = hubloc_hash
|
||||
where xtag_flags = 0 $hub_query
|
||||
where xtag_flags = 0 and xtag_hash in (select hubloc_hash from hubloc where hubloc_host = '%s' )
|
||||
group by xtag_term order by total desc %s",
|
||||
dbesc($hub),
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Fetch tags
|
||||
$r = q("select xtag_term as term, count(xtag_term) as total from xtag where xtag_flags = 0
|
||||
group by xtag_term order by total desc %s",
|
||||
((intval($count)) ? "limit $count" : '')
|
||||
);
|
||||
}
|
||||
if(! $r)
|
||||
return array();
|
||||
|
||||
return [];
|
||||
|
||||
return Zotlabs\Text\Tagadelic::calc($r);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -973,7 +973,14 @@ function contact_block() {
|
||||
$contacts = t('Connections');
|
||||
$micropro = Array();
|
||||
foreach($r as $rr) {
|
||||
$rr['archived'] = (intval($rr['abook_archived']) ? true : false);
|
||||
|
||||
// There is no setting to discover if you are bi-directionally connected
|
||||
// Use the ability to post comments as an indication that this relationship is more
|
||||
// than wishful thinking; even though soapbox channels and feeds will disable it.
|
||||
|
||||
if(! intval(get_abconfig(App::$profile['uid'],$rr['xchan_hash'],'their_perms','post_comments'))) {
|
||||
$rr['archived'] = true;
|
||||
}
|
||||
$micropro[] = micropro($rr,true,'mpfriend');
|
||||
}
|
||||
}
|
||||
@@ -2152,6 +2159,35 @@ function ids_to_querystr($arr,$idx = 'id',$quote = false) {
|
||||
return(implode(',', $t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief array_elm_to_str($arr,$elm,$delim = ',') extract unique individual elements from an array of arrays and return them as a string separated by a delimiter
|
||||
* similar to ids_to_querystr, but allows a different delimiter instead of a db-quote option
|
||||
* empty elements (evaluated after trim()) are ignored.
|
||||
* @param $arr array
|
||||
* @param $elm array key to extract from sub-array
|
||||
* @param $delim string default ','
|
||||
* @returns string
|
||||
*/
|
||||
|
||||
function array_elm_to_str($arr,$elm,$delim = ',') {
|
||||
|
||||
$tmp = [];
|
||||
if($arr && is_array($arr)) {
|
||||
foreach($arr as $x) {
|
||||
if(is_array($x) && array_key_exists($elm,$x)) {
|
||||
$z = trim($x[$elm]);
|
||||
if(($z) && (! in_array($z,$tmp))) {
|
||||
$tmp[] = $z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return implode($delim,$tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fetches xchan and hubloc data for an array of items with only an
|
||||
* author_xchan and owner_xchan.
|
||||
@@ -3254,3 +3290,5 @@ function purify_filename($s) {
|
||||
return '';
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -127,8 +127,11 @@ function clean_query_string($s = '') {
|
||||
* @return string
|
||||
*/
|
||||
function zidify_callback($match) {
|
||||
$is_zid = ((feature_enabled(local_channel(), 'sendzid')) || (strpos($match[1], 'zrl')) ? true : false);
|
||||
$replace = '<a' . $match[1] . ' href="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
|
||||
|
||||
$arr = [ 'zid' => ((strpos($match[1],'zrl')) ? true : false), 'url' => $match[2] ];
|
||||
call_hooks('zidify', $arr);
|
||||
|
||||
$replace = '<a' . $match[1] . ' href="' . (intval($arr['zid']) ? zid($arr['url']) : $arr['url']) . '"';
|
||||
|
||||
$x = str_replace($match[0], $replace, $match[0]);
|
||||
|
||||
@@ -136,8 +139,11 @@ function zidify_callback($match) {
|
||||
}
|
||||
|
||||
function zidify_img_callback($match) {
|
||||
$is_zid = ((feature_enabled(local_channel(), 'sendzid')) || (strpos($match[1], 'zrl')) ? true : false);
|
||||
$replace = '<img' . $match[1] . ' src="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"';
|
||||
|
||||
$arr = [ 'zid' => ((strpos($match[1],'zrl')) ? true : false), 'url' => $match[2] ];
|
||||
call_hooks('zidify', $arr);
|
||||
|
||||
$replace = '<img' . $match[1] . ' src="' . (intval($arr['zid']) ? zid($arr['url']) : $arr['url']) . '"';
|
||||
|
||||
$x = str_replace($match[0], $replace, $match[0]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user