diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/account.php | 3 | ||||
-rw-r--r-- | include/api.php | 39 | ||||
-rw-r--r-- | include/bb2diaspora.php | 34 | ||||
-rw-r--r-- | include/bbcode.php | 44 | ||||
-rw-r--r-- | include/config.php | 157 | ||||
-rwxr-xr-x | include/dba/dba_mysqli.php | 18 | ||||
-rw-r--r-- | include/help.php | 150 | ||||
-rw-r--r-- | include/import.php | 30 | ||||
-rwxr-xr-x | include/importdoc.php | 2 | ||||
-rwxr-xr-x | include/items.php | 166 | ||||
-rw-r--r-- | include/nav.php | 19 | ||||
-rw-r--r-- | include/network.php | 5 | ||||
-rw-r--r-- | include/notifier.php | 21 | ||||
-rw-r--r-- | include/photos.php | 44 | ||||
-rwxr-xr-x | include/plugin.php | 57 | ||||
-rw-r--r-- | include/text.php | 35 | ||||
-rw-r--r-- | include/zot.php | 13 |
17 files changed, 562 insertions, 275 deletions
diff --git a/include/account.php b/include/account.php index c64197b49..5998609d4 100644 --- a/include/account.php +++ b/include/account.php @@ -591,6 +591,7 @@ function service_class_allows($uid, $property, $usage = false) { if($limit === false) return true; // No service class set => everything is allowed + $limit = engr_units_to_bytes($limit); if($usage === false) { // We use negative values for not allowed properties in a subscriber plan return ((x($limit)) ? (bool) $limit : true); @@ -627,6 +628,8 @@ function account_service_class_allows($aid, $property, $usage = false) { if($limit === false) return true; // No service class is set => everything is allowed + $limit = engr_units_to_bytes($limit); + if($usage === false) { // We use negative values for not allowed properties in a subscriber plan return ((x($limit)) ? (bool) $limit : true); diff --git a/include/api.php b/include/api.php index fd644947c..e64c86695 100644 --- a/include/api.php +++ b/include/api.php @@ -772,13 +772,15 @@ require_once('include/api_auth.php'); $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo $_FILES['userfile'] = $_FILES['media']; - require_once('mod/wall_attach.php'); - $posted = wall_attach_post($a); - - //now that we have the img url in bbcode we can add it to the status and insert the wall item. + + $mod = new Zotlabs\Module\Wall_attach(); + $mod->post(); + + $_REQUEST['body']=$txt."\n\n".$posted; - require_once('mod/item.php'); - item_post($a); + + $mod = new Zotlabs\Module\Item(); + $mod->post(); // this should output the last post (the one we just posted). return api_status_show($a,$type); @@ -871,9 +873,9 @@ require_once('include/api_auth.php'); // upload each image if we have any $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo - require_once('mod/wall_attach.php'); + $mod = new Zotlabs\Module\Wall_attach(); App::$data['api_info'] = $user_info; - $media = wall_attach_post($a); + $media = $mod->post(); if(strlen($media)>0) $_REQUEST['body'] .= "\n\n" . $media; @@ -884,9 +886,9 @@ require_once('include/api_auth.php'); $_FILES['userfile'] = $_FILES['media']; // upload each image if we have any $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo - require_once('mod/wall_attach.php'); + $mod = new Zotlabs\Module\Wall_attach(); App::$data['api_info'] = $user_info; - $media = wall_attach_post($a); + $media = $mod->post(); if(strlen($media)>0) $_REQUEST['body'] .= "\n\n" . $media; @@ -896,8 +898,8 @@ require_once('include/api_auth.php'); // call out normal post function - require_once('mod/item.php'); - item_post($a); + $mod = new Zotlabs\Module\Item(); + $mod->post(); // this should output the last post (the one we just posted). return api_status_show($a,$type); @@ -926,14 +928,14 @@ require_once('include/api_auth.php'); $_FILES['userfile'] = $_FILES['media']; // upload the image if we have one $_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo - require_once('mod/wall_upload.php'); - $media = wall_upload_post($a); + $mod = new Zotlabs\Module\Wall_upload(); + $media = $mod->post(); if(strlen($media)>0) $_REQUEST['body'] .= "\n\n".$media; } - require_once('mod/item.php'); - $x = item_post($a); + $mod = new Zotlabs\Module\Item(); + $x = $mod->post(); json_return_and_die($x); } @@ -1423,9 +1425,8 @@ require_once('include/api_auth.php'); $_REQUEST['profile_uid'] = api_user(); $_REQUEST['type'] = 'wall'; $_REQUEST['api_source'] = true; - - require_once('mod/item.php'); - item_post($a); + $mod = new Zotlabs\Module\Item(); + $mod->post(); } } else diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 1ed57bfd4..9167cb5ad 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -270,7 +270,14 @@ function bb2dmention_callback($match) { function bb2diaspora_itemwallwall(&$item) { + // We will provide wallwall (embedded author on the Diaspora side) if + // 1. It is a wall-to-wall post + // 2. A comment arrived which has no Diaspora signature info + + + $wallwall = false; $author_exists = true; + if(! array_key_exists('author',$item)) { $author_exists = false; logger('bb2diaspora_itemwallwall: no author'); @@ -281,11 +288,21 @@ function bb2diaspora_itemwallwall(&$item) { $item['author'] = $r[0]; } - if(($item['mid'] == $item['parent_mid']) && ($item['author_xchan'] != $item['owner_xchan']) && (is_array($item['author']))) { - logger('bb2diaspora_itemwallwall: author: ' . print_r($item['author'],true), LOGGER_DATA); + $has_meta = false; + if($item['diaspora_meta'] || get_iconfig($item,'diaspora','fields')) + $has_meta = true; + + if($item['author_xchan'] != $item['owner_xchan']) { + if($item['mid'] == $item['parent_mid']) + $wallwall = true; + else { + if(! $has_meta) { + $wallwall = true; + } + } } - if(($item['mid'] == $item['parent_mid']) && ($item['author_xchan'] != $item['owner_xchan']) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_m']) { + if(($wallwall) && (is_array($item['author'])) && $item['author']['xchan_url'] && $item['author']['xchan_name'] && $item['author']['xchan_photo_m']) { logger('bb2diaspora_itemwallwall: wall to wall post',LOGGER_DEBUG); // post will come across with the owner's identity. Throw a preamble onto the post to indicate the true author. $item['body'] = "\n\n" @@ -301,7 +318,12 @@ function bb2diaspora_itemwallwall(&$item) { } -function bb2diaspora_itembody($item, $force_update = false) { +function bb2diaspora_itembody($item, $force_update = false, $have_channel = false) { + + + if(! get_iconfig($item,'diaspora','fields')) { + $force_update = true; + } $matches = array(); @@ -339,8 +361,8 @@ function bb2diaspora_itembody($item, $force_update = false) { } } - - bb2diaspora_itemwallwall($newitem); + if(! $have_channel) + bb2diaspora_itemwallwall($newitem); $title = $newitem['title']; $body = preg_replace('/\#\^http/i', 'http', $newitem['body']); diff --git a/include/bbcode.php b/include/bbcode.php index 78a2759c1..b8cd23f59 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -330,8 +330,19 @@ function bb_map_location($match) { } function bb_opentag($match) { + $openclose = (($match[2]) ? '<span class="bb-open" title="' . t('Click to open/close') . '">' . $match[1] . '</span>' : t('Click to open/close')); + $text = (($match[2]) ? $match[2] : $match[1]); $rnd = mt_rand(); - return "<br /><div onclick=\"openClose('opendiv-" . $rnd . "');return false;\" class=\"fakelink\">" . $match[1] . "</div><div id=\"opendiv-" . $rnd . "\" style=\"display: none;\">" . $match[2] . "</div>"; + + return '<div onclick="openClose(\'opendiv-' . $rnd . '\'); return false;" class="fakelink">' . $openclose . '</div><div id="opendiv-' . $rnd . '" style="display: none;">' . $text . '</div>'; +} + +function bb_spoilertag($match) { + $openclose = (($match[2]) ? '<span class="bb-spoiler" title="' . t('Click to open/close') . '">' . $match[1] . ' ' . t('spoiler') . '</span>' : t('Click to open/close')); + $text = (($match[2]) ? $match[2] : $match[1]); + $rnd = mt_rand(); + + return '<div onclick="openClose(\'opendiv-' . $rnd . '\'); return false;" class="fakelink">' . $openclose . '</div><blockquote id="opendiv-' . $rnd . '" style="display: none;">' . $text . '</blockquote>'; } /** @@ -748,33 +759,34 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) $Text = preg_replace("/\[code\](.*?)\[\/code\]/ism", "$CodeLayout", $Text); } - // Declare the format for [spoiler] layout - $SpoilerLayout = '<blockquote class="spoiler">$1</blockquote>'; - // Check for [spoiler] text - // handle nested quotes $endlessloop = 0; - while ((strpos($Text, "[/spoiler]") !== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) - $Text = preg_replace("/\[spoiler\](.*?)\[\/spoiler\]/ism", "$SpoilerLayout", $Text); + while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[spoiler\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); + } // Check for [spoiler=Author] text - - $t_wrote = t('$1 spoiler'); - - // handle nested quotes $endlessloop = 0; - while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) - $Text = preg_replace("/\[spoiler=[\"\']*(.*?)[\"\']*\](.*?)\[\/spoiler\]/ism", - "<br /><strong class=".'"spoiler"'.">" . $t_wrote . "</strong><blockquote class=".'"spoiler"'.">$2</blockquote>", - $Text); + while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler=") !== false) and (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[spoiler=(.*?)\](.*?)\[\/spoiler\]/ism", 'bb_spoilertag', $Text); + } + // Check for [open] text + $endlessloop = 0; + while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open]") !== false) and (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[open\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); + } + // Check for [open=Title] text $endlessloop = 0; while ((strpos($Text, "[/open]")!== false) and (strpos($Text, "[open=") !== false) and (++$endlessloop < 20)) { $Text = preg_replace_callback("/\[open=(.*?)\](.*?)\[\/open\]/ism", 'bb_opentag', $Text); } + + + // Declare the format for [quote] layout $QuoteLayout = '<blockquote>$1</blockquote>'; @@ -792,7 +804,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) $endlessloop = 0; while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20)) $Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism", - "<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>", + "<span class=".'"bb-quote"'.">" . $t_wrote . "</span><blockquote>$2</blockquote>", $Text); // Images diff --git a/include/config.php b/include/config.php index 712b4ca11..12768f4da 100644 --- a/include/config.php +++ b/include/config.php @@ -625,3 +625,160 @@ function del_abconfig($chash,$xhash,$family,$key) { return $r; } + + + + + + +function get_iconfig(&$item, $family, $key) { + + $is_item = false; + if(is_array($item)) { + $is_item = true; + if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) + $item['iconfig'] = array(); + + if(array_key_exists('item_id',$item)) + $iid = $item['item_id']; + else + $iid = $item['id']; + } + elseif(intval($item)) + $iid = $item; + + if(! $iid) + return false; + + if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) { + foreach($item['iconfig'] as $c) { + if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key) + return $c['v']; + } + } + + $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1", + intval($iid), + dbesc($family), + dbesc($key) + ); + if($r) { + $r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']); + if($is_item) + $item['iconfig'][] = $r[0]; + return $r[0]['v']; + } + return false; + +} + +/** + * set_iconfig(&$item, $family, $key, $value, $sharing = false); + * + * $item - item array or item id. If passed an array the iconfig meta information is + * added to the item structure (which will need to be saved with item_store eventually). + * If passed an id, the DB is updated, but may not be federated and/or cloned. + * $family - namespace of meta variable + * $key - key of meta variable + * $value - value of meta variable + * $sharing - boolean (default false); if true the meta information is propagated with the item + * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered. + * If the meta information is added after delivery and you wish it to be shared, it may be necessary to + * alter the item edited timestamp and invoke the delivery process on the updated item. The edited + * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end. + */ + + +function set_iconfig(&$item, $family, $key, $value, $sharing = false) { + + $dbvalue = ((is_array($value)) ? serialize($value) : $value); + $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); + + $is_item = false; + $idx = null; + + if(is_array($item)) { + $is_item = true; + if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) + $item['iconfig'] = array(); + elseif($item['iconfig']) { + for($x = 0; $x < count($item['iconfig']); $x ++) { + if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { + $idx = $x; + } + } + } + $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing); + + if(is_null($idx)) + $item['iconfig'][] = $entry; + else + $item['iconfig'][$idx] = $entry; + return $value; + } + + if(intval($item)) + $iid = intval($item); + + if(! $iid) + return false; + + if(get_iconfig($item, $family, $key) === false) { + $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ", + intval($iid), + dbesc($family), + dbesc($key), + dbesc($dbvalue), + intval($sharing) + ); + } + else { + $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ", + dbesc($dbvalue), + intval($sharing), + intval($iid), + dbesc($family), + dbesc($key) + ); + } + + if(! $r) + return false; + + return $value; +} + + + +function del_iconfig(&$item, $family, $key) { + + + $is_item = false; + $idx = null; + + if(is_array($item)) { + $is_item = true; + if(is_array($item['iconfig'])) { + for($x = 0; $x < count($item['iconfig']); $x ++) { + if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { + unset($item['iconfig'][$x]); + } + } + } + return true; + } + + if(intval($item)) + $iid = intval($item); + + if(! $iid) + return false; + + return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ", + intval($iid), + dbesc($family), + dbesc($key) + ); + +} + diff --git a/include/dba/dba_mysqli.php b/include/dba/dba_mysqli.php index 6986d4586..57a7559a1 100755 --- a/include/dba/dba_mysqli.php +++ b/include/dba/dba_mysqli.php @@ -4,20 +4,26 @@ require_once('include/dba/dba_driver.php'); class dba_mysqli extends dba_driver { - function connect($server, $port, $user,$pass,$db) { + function connect($server,$port,$user,$pass,$db) { if($port) $this->db = new mysqli($server,$user,$pass,$db, $port); else $this->db = new mysqli($server,$user,$pass,$db); - if(! mysqli_connect_errno()) { - $this->connected = true; + if($this->db->connect_error) { + $this->connected = false; + $this->error = $this->db->connect_error; + + if(file_exists('dbfail.out')) { + file_put_contents('dbfail.out', datetime_convert() . "\nConnect: " . $this->error . "\n", FILE_APPEND); + } + + return false; } - if($this->connected) { + else { + $this->connected = true; return true; } - $this->error = $this->db->connect_error; - return false; } function q($sql) { diff --git a/include/help.php b/include/help.php new file mode 100644 index 000000000..13473164d --- /dev/null +++ b/include/help.php @@ -0,0 +1,150 @@ +<?php + +function load_doc_file($s) { + $lang = \App::$language; + if(! isset($lang)) + $lang = 'en'; + $b = basename($s); + $d = dirname($s); + + $c = find_doc_file("$d/$lang/$b"); + if($c) + return $c; + $c = find_doc_file($s); + if($c) + return $c; + return ''; +} + +function find_doc_file($s) { + if(file_exists($s)) + return file_get_contents($s); + return ''; +} + +function search_doc_files($s) { + + $a = get_app(); + + $itemspage = get_pconfig(local_channel(),'system','itemspage'); + \App::set_pager_itemspage(((intval($itemspage)) ? $itemspage : 20)); + $pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']), intval(\App::$pager['start'])); + + $regexop = db_getfunc('REGEXP'); + + $r = q("select item_id.sid, item.* from item left join item_id on item.id = item_id.iid where service = 'docfile' and + body $regexop '%s' and item_type = %d $pager_sql", + dbesc($s), + intval(ITEM_TYPE_DOC) + ); + + $r = fetch_post_tags($r,true); + + for($x = 0; $x < count($r); $x ++) { + + $r[$x]['text'] = $r[$x]['body']; + + $r[$x]['rank'] = 0; + if($r[$x]['term']) { + foreach($r[$x]['term'] as $t) { + if(stristr($t['term'],$s)) { + $r[$x]['rank'] ++; + } + } + } + if(stristr($r[$x]['sid'],$s)) + $r[$x]['rank'] ++; + $r[$x]['rank'] += substr_count(strtolower($r[$x]['text']),strtolower($s)); + // bias the results to the observer's native language + if($r[$x]['lang'] === \App::$language) + $r[$x]['rank'] = $r[$x]['rank'] + 10; + + } + usort($r,'doc_rank_sort'); + return $r; +} + + +function doc_rank_sort($s1,$s2) { + if($s1['rank'] == $s2['rank']) + return 0; + return (($s1['rank'] < $s2['rank']) ? 1 : (-1)); +} + + +function load_context_help() { + + $path = App::$cmd; + $args = App::$argv; + $lang = App::$language; + + if(! isset($lang) || !is_dir('doc/context/' . $lang . '/')) { + $lang = 'en'; + } + while($path) { + $context_help = load_doc_file('doc/context/' . $lang . '/' . $path . '/help.html'); + if(!$context_help) { + // Fallback to English if the translation is absent + $context_help = load_doc_file('doc/context/en/' . $path . '/help.html'); + } + if($context_help) + break; + array_pop($args); + $path = implode($args,'/'); + } + + return $context_help; +} + + +function store_doc_file($s) { + + if(is_dir($s)) + return; + + $item = array(); + $sys = get_sys_channel(); + + $item['aid'] = 0; + $item['uid'] = $sys['channel_id']; + + + if(strpos($s,'.md')) + $mimetype = 'text/markdown'; + elseif(strpos($s,'.html')) + $mimetype = 'text/html'; + else + $mimetype = 'text/bbcode'; + + require_once('include/html2plain.php'); + + $item['body'] = html2plain(prepare_text(file_get_contents($s),$mimetype, true)); + $item['mimetype'] = 'text/plain'; + + $item['plink'] = z_root() . '/' . str_replace('doc','help',$s); + $item['owner_xchan'] = $item['author_xchan'] = $sys['channel_hash']; + $item['item_type'] = ITEM_TYPE_DOC; + + $r = q("select item.* from item left join item_id on item.id = item_id.iid where service = 'docfile' and + sid = '%s' and item_type = %d limit 1", + dbesc($s), + intval(ITEM_TYPE_DOC) + ); + + if($r) { + $item['id'] = $r[0]['id']; + $item['mid'] = $item['parent_mid'] = $r[0]['mid']; + $x = item_store_update($item); + } + else { + $item['mid'] = $item['parent_mid'] = item_message_id(); + $x = item_store($item); + } + + if($x['success']) { + update_remote_id($sys,$x['item_id'],ITEM_TYPE_DOC,$s,'docfile',0,$item['mid']); + } + + +} + diff --git a/include/import.php b/include/import.php index 3b5c8508c..f6e62f9e0 100644 --- a/include/import.php +++ b/include/import.php @@ -482,7 +482,7 @@ function sync_chatrooms($channel,$chatrooms) { -function import_items($channel,$items) { +function import_items($channel,$items,$sync = false) { if($channel && $items) { $allow_code = false; @@ -499,6 +499,7 @@ function import_items($channel,$items) { $deliver = false; // Don't deliver any messages or notifications when importing foreach($items as $i) { + $item_result = false; $item = get_item_elements($i,$allow_code); if(! $item) continue; @@ -511,7 +512,13 @@ function import_items($channel,$items) { if($item['edited'] > $r[0]['edited']) { $item['id'] = $r[0]['id']; $item['uid'] = $channel['channel_id']; - item_store_update($item,$allow_code,$deliver); + $item_result = item_store_update($item,$allow_code,$deliver); + if($sync && $item['item_wall']) { + // deliver singletons if we have any + if($item_result && $item_result['success']) { + proc_run('php','include/notifier.php','single_activity',$item_result['item_id']); + } + } continue; } } @@ -520,13 +527,19 @@ function import_items($channel,$items) { $item['uid'] = $channel['channel_id']; $item_result = item_store($item,$allow_code,$deliver); } + if($sync && $item['item_wall']) { + // deliver singletons if we have any + if($item_result && $item_result['success']) { + proc_run('php','include/notifier.php','single_activity',$item_result['item_id']); + } + } } } } function sync_items($channel,$items) { - import_items($channel,$items); + import_items($channel,$items,true); } @@ -839,7 +852,7 @@ function import_conv($channel,$convs) { -function import_mail($channel,$mails) { +function import_mail($channel,$mails,$sync = false) { if($channel && $mails) { foreach($mails as $mail) { if(array_key_exists('flags',$mail) && in_array('deleted',$mail['flags'])) { @@ -863,12 +876,17 @@ function import_mail($channel,$mails) { $m['aid'] = $channel['channel_account_id']; $m['uid'] = $channel['channel_id']; - mail_store($m); + $mail_id = mail_store($m); + if($sync && $mail_id) { + proc_run('php','include/notifier.php','single_mail',$mail_id); + } } } } - +function sync_mail($channel,$mails) { + import_mail($channel,$mails,true); +} function sync_files($channel,$files) { diff --git a/include/importdoc.php b/include/importdoc.php index 10f868697..90dfb2fc4 100755 --- a/include/importdoc.php +++ b/include/importdoc.php @@ -9,7 +9,7 @@ function importdoc_run($argv, $argc){ cli_startup(); - require_once('mod/help.php'); + require_once('include/help.php'); update_docs_dir('doc/*'); diff --git a/include/items.php b/include/items.php index 95822c0ba..2720dd841 100755 --- a/include/items.php +++ b/include/items.php @@ -555,8 +555,8 @@ function get_public_feed($channel, $params) { // put a sane lower limit on feed requests if not specified - if($params['begin'] === NULL_DATE) - $params['begin'] = datetime_convert('UTC','UTC','now - 1 month'); +// if($params['begin'] === NULL_DATE) +// $params['begin'] = datetime_convert('UTC','UTC','now - 1 month'); switch($params['type']) { case 'json': @@ -4235,10 +4235,10 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $obj = ((is_array($item['obj'])) ? $item['object'] : json_decode($item['object'],true)); $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n"; - $o .= '<summary>' . xmlify(bbcode($obj['title'])) . '</summary>' . "\r\n"; + $o .= '<summary xmlns="urn:ietf:params:xml:ns:xcal">' . xmlify(bbcode($obj['title'])) . '</summary>' . "\r\n"; $o .= '<dtstart xmlns="urn:ietf:params:xml:ns:xcal">' . datetime_convert('UTC','UTC', $obj['start'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '</dtstart>' . "\r\n"; $o .= '<dtend xmlns="urn:ietf:params:xml:ns:xcal">' . datetime_convert('UTC','UTC', $obj['finish'],'Ymd\\THis' . (($obj['adjust']) ? '\\Z' : '')) . '</dtend>' . "\r\n"; - $o .= '<location>' . bbcode($obj['location']) . '</location>' . "\r\n"; + $o .= '<location xmlns="urn:ietf:params:xml:ns:xcal">' . xmlify(bbcode($obj['location'])) . '</location>' . "\r\n"; $o .= '<content type="' . $type . '" >' . xmlify(bbcode($obj['description'])) . '</content>' . "\r\n"; } else { @@ -5617,157 +5617,17 @@ function send_profile_photo_activity($channel,$photo,$profile) { } +function sync_an_item($channel_id,$item_id) { - - -function get_iconfig(&$item, $family, $key) { - - $is_item = false; - if(is_array($item)) { - $is_item = true; - if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) - $item['iconfig'] = array(); - - if(array_key_exists('item_id',$item)) - $iid = $item['item_id']; - else - $iid = $item['id']; - } - elseif(intval($item)) - $iid = $item; - - if(! $iid) - return false; - - if(is_array($item) && array_key_exists('iconfig',$item) && is_array($item['iconfig'])) { - foreach($item['iconfig'] as $c) { - if($c['iid'] == $iid && $c['cat'] == $family && $c['k'] == $key) - return $c['v']; - } - } - - $r = q("select * from iconfig where iid = %d and cat = '%s' and k = '%s' limit 1", - intval($iid), - dbesc($family), - dbesc($key) + $r = q("select * from item where id = %d", + intval($item_id) ); if($r) { - $r[0]['v'] = ((preg_match('|^a:[0-9]+:{.*}$|s',$r[0]['v'])) ? unserialize($r[0]['v']) : $r[0]['v']); - if($is_item) - $item['iconfig'][] = $r[0]; - return $r[0]['v']; - } - return false; - -} - -/** - * set_iconfig(&$item, $family, $key, $value, $sharing = false); - * - * $item - item array or item id. If passed an array the iconfig meta information is - * added to the item structure (which will need to be saved with item_store eventually). - * If passed an id, the DB is updated, but may not be federated and/or cloned. - * $family - namespace of meta variable - * $key - key of meta variable - * $value - value of meta variable - * $sharing - boolean (default false); if true the meta information is propagated with the item - * to other sites/channels, mostly useful when $item is an array and has not yet been stored/delivered. - * If the meta information is added after delivery and you wish it to be shared, it may be necessary to - * alter the item edited timestamp and invoke the delivery process on the updated item. The edited - * timestamp needs to be altered in order to trigger an item_store_update() at the receiving end. - */ - - -function set_iconfig(&$item, $family, $key, $value, $sharing = false) { - - $dbvalue = ((is_array($value)) ? serialize($value) : $value); - $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue); - - $is_item = false; - $idx = null; - - if(is_array($item)) { - $is_item = true; - if((! array_key_exists('iconfig',$item)) || (! is_array($item['iconfig']))) - $item['iconfig'] = array(); - elseif($item['iconfig']) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - $idx = $x; - } - } - } - $entry = array('cat' => $family, 'k' => $key, 'v' => $value, 'sharing' => $sharing); - - if(is_null($idx)) - $item['iconfig'][] = $entry; - else - $item['iconfig'][$idx] = $entry; - return $value; - } - - if(intval($item)) - $iid = intval($item); - - if(! $iid) - return false; - - if(get_iconfig($item, $family, $key) === false) { - $r = q("insert into iconfig( iid, cat, k, v, sharing ) values ( %d, '%s', '%s', '%s', %d ) ", - intval($iid), - dbesc($family), - dbesc($key), - dbesc($dbvalue), - intval($sharing) - ); - } - else { - $r = q("update iconfig set v = '%s', sharing = %d where iid = %d and cat = '%s' and k = '%s' ", - dbesc($dbvalue), - intval($sharing), - intval($iid), - dbesc($family), - dbesc($key) + xchan_query($r); + $sync_item = fetch_post_tags($r); + $rid = q("select * from item_id where iid = %d", + intval($item_id) ); + build_sync_packet($channel_d,array('item' => array(encode_item($sync_item[0],true)),'item_id' => $rid)); } - - if(! $r) - return false; - - return $value; -} - - - -function del_iconfig(&$item, $family, $key) { - - - $is_item = false; - $idx = null; - - if(is_array($item)) { - $is_item = true; - if(is_array($item['iconfig'])) { - for($x = 0; $x < count($item['iconfig']); $x ++) { - if($item['iconfig'][$x]['cat'] == $family && $item['iconfig'][$x]['k'] == $key) { - unset($item['iconfig'][$x]); - } - } - } - return true; - } - - if(intval($item)) - $iid = intval($item); - - if(! $iid) - return false; - - return q("delete from iconfig where iid = %d and cat = '%s' and k = '%s' ", - intval($iid), - dbesc($family), - dbesc($key) - ); - -} - +}
\ No newline at end of file diff --git a/include/nav.php b/include/nav.php index 541ab3aed..70faec598 100644 --- a/include/nav.php +++ b/include/nav.php @@ -143,16 +143,20 @@ EOT; if((App::$module != 'home') && (! (local_channel()))) $nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn'); - if((App::$config['system']['register_policy'] == REGISTER_OPEN) && (! local_channel()) && (! remote_channel())) $nav['register'] = array('register',t('Register'), "", t('Create an account'),'register_nav_btn'); - $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; - if(! get_config('system','hide_help')) { - require_once('mod/help.php'); - $context_help = load_context_help(); - $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'),'help_nav_btn',$context_help); + $help_url = z_root() . '/help?f=&cmd=' . App::$cmd; + $context_help = ''; + $enable_context_help = ((intval(get_config('system','enable_context_help')) === 1 || get_config('system','enable_context_help') === false) ? true : false); + if($enable_context_help === true) { + require_once('include/help.php'); + $context_help = load_context_help(); + //point directly to /help if $context_help is empty - this can be removed once we have context help for all modules + $enable_context_help = (($context_help) ? true : false); + } + $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'), 'help_nav_btn', $context_help, $enable_context_help); } if(! UNO) @@ -160,7 +164,6 @@ EOT; $nav['search'] = array('search', t('Search'), "", t('Search site @name, #tag, ?docs, content')); - $nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn'); @@ -237,7 +240,7 @@ $powered_by = ''; $tpl = get_markup_template('nav.tpl'); App::$page['nav'] .= replace_macros($tpl, array( - '$baseurl' => z_root(), + '$baseurl' => z_root(), '$sitelocation' => $sitelocation, '$nav' => $x['nav'], '$banner' => $banner, diff --git a/include/network.php b/include/network.php index ec255581d..395641b73 100644 --- a/include/network.php +++ b/include/network.php @@ -2114,8 +2114,9 @@ function check_channelallowed($hash) { return $retvalue; } -function deliverable_singleton($xchan) { - $r = q("select abook_instance from abook where abook_xchan = '%s' limit 1", +function deliverable_singleton($channel_id,$xchan) { + $r = q("select abook_instance from abook where abook_channel = %d and abook_xchan = '%s' limit 1", + intval($channel_id), dbesc($xchan['xchan_hash']) ); if($r) { diff --git a/include/notifier.php b/include/notifier.php index 628847d54..f0c6d7275 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -118,7 +118,7 @@ function notifier_run($argv, $argc){ $normal_mode = true; $packet_type = 'undefined'; - if($cmd === 'mail') { + if($cmd === 'mail' || $cmd === 'single_mail') { $normal_mode = false; $mail = true; $private = true; @@ -280,7 +280,7 @@ function notifier_run($argv, $argc){ logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG); return; } - if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed'])) { + if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed']) || intval($target_item['item_hidden'])) { logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG); return; } @@ -450,11 +450,11 @@ function notifier_run($argv, $argc){ 'target_item' => $target_item, 'top_level_post' => $top_level_post, 'private' => $private, - 'followup' => $followup, 'relay_to_owner' => $relay_to_owner, 'uplink' => $uplink, 'cmd' => $cmd, 'mail' => $mail, + 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false), 'location' => $location, 'request' => $request, 'normal_mode' => $normal_mode, @@ -547,11 +547,11 @@ function notifier_run($argv, $argc){ 'hub' => $hub, 'top_level_post' => $top_level_post, 'private' => $private, - 'followup' => $followup, 'relay_to_owner' => $relay_to_owner, 'uplink' => $uplink, 'cmd' => $cmd, 'mail' => $mail, + 'single' => (($cmd === 'single_mail' || $cmd === 'single_activity') ? true : false), 'location' => $location, 'request' => $request, 'normal_mode' => $normal_mode, @@ -570,6 +570,19 @@ function notifier_run($argv, $argc){ } + // singleton deliveries by definition 'not got zot'. + // Single deliveries are other federated networks (plugins) and we're essentially + // delivering only to those that have this site url in their abook_instance + // and only from within a sync operation. This means if you post from a clone, + // and a connection is connected to one of your other clones; assuming that hub + // is running it will receive a sync packet. On receipt of this sync packet it + // will invoke a delivery to those connections which are connected to just that + // hub instance. + + if($cmd === 'single_mail' || $cmd === 'single_activity') { + continue; + } + // default: zot protocol $hash = random_string(); diff --git a/include/photos.php b/include/photos.php index 943d7d503..73a29d8eb 100644 --- a/include/photos.php +++ b/include/photos.php @@ -131,7 +131,7 @@ function photo_upload($channel, $observer, $args) { intval($account_id) ); - $limit = service_class_fetch($channel_id,'photo_upload_limit'); + $limit = engr_units_to_bytes(service_class_fetch($channel_id,'photo_upload_limit')); if (($r) && ($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { $ret['message'] = upgrade_message(); @@ -296,7 +296,7 @@ function photo_upload($channel, $observer, $args) { $photo_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']' . t('a new photo') . '[/zrl]'; - $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album) . ']' . $album . '[/zrl]'; + $album_link = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/album/' . bin2hex($album) . ']' . ((strlen($album)) ? $album : '/') . '[/zrl]'; $activity_format = sprintf(t('%1$s posted %2$s to %3$s','photo_upload'), $author_link, $photo_link, $album_link); @@ -706,3 +706,43 @@ function gps2Num($coordPart) { return floatval($parts[0]) / floatval($parts[1]); } + +function profile_photo_set_profile_perms($profileid = '') { + + $allowcid = ''; + if (x($profileid)) { + + $r = q("SELECT photo, profile_guid, id, is_default, uid FROM profile WHERE profile.id = %d OR profile.profile_guid = '%s' LIMIT 1", intval($profileid), dbesc($profileid)); + + } else { + + logger('Resetting permissions on default-profile-photo for user'.local_channel()); + $r = q("SELECT photo, profile_guid, id, is_default, uid FROM profile WHERE profile.uid = %d AND is_default = 1 LIMIT 1", intval(local_channel()) ); //If no profile is given, we update the default profile + } + + $profile = $r[0]; + if(x($profile['id']) && x($profile['photo'])) { + preg_match("@\w*(?=-\d*$)@i", $profile['photo'], $resource_id); + $resource_id = $resource_id[0]; + + if (intval($profile['is_default']) != 1) { + $r0 = q("SELECT channel_hash FROM channel WHERE channel_id = %d LIMIT 1", intval(local_channel()) ); + $r1 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%d' ", intval($profile['id'])); //Should not be needed in future. Catches old int-profile-ids. + $r2 = q("SELECT abook.abook_xchan FROM abook WHERE abook_profile = '%s'", dbesc($profile['profile_guid'])); + $allowcid = "<" . $r0[0]['channel_hash'] . ">"; + foreach ($r1 as $entry) { + $allowcid .= "<" . $entry['abook_xchan'] . ">"; + } + foreach ($r2 as $entry) { + $allowcid .= "<" . $entry['abook_xchan'] . ">"; + } + + q("UPDATE `photo` SET allow_cid = '%s' WHERE resource_id = '%s' AND uid = %d",dbesc($allowcid),dbesc($resource_id),intval($profile['uid'])); + + } else { + q("UPDATE `photo` SET allow_cid = '' WHERE profile = 1 AND uid = %d",intval($profile['uid'])); //Reset permissions on default profile picture to public + } + } + + return; + } diff --git a/include/plugin.php b/include/plugin.php index 8dceb8fb1..8dd67bb0c 100755 --- a/include/plugin.php +++ b/include/plugin.php @@ -185,7 +185,7 @@ function register_hook($hook, $file, $function, $priority = 0) { dbesc($file), dbesc($function) ); - if(count($r)) + if($r) return true; $r = q("INSERT INTO `hook` (`hook`, `file`, `function`, `priority`) VALUES ( '%s', '%s', '%s', '%s' )", @@ -226,9 +226,8 @@ function unregister_hook($hook, $file, $function) { function load_hooks() { - $a = get_app(); -// if(! is_array(App::$hooks)) - App::$hooks = array(); + + App::$hooks = array(); $r = q("SELECT * FROM hook WHERE true ORDER BY priority DESC"); if($r) { @@ -236,10 +235,10 @@ function load_hooks() { if(! array_key_exists($rr['hook'],App::$hooks)) App::$hooks[$rr['hook']] = array(); - App::$hooks[$rr['hook']][] = array($rr['file'],$rr['function']); + App::$hooks[$rr['hook']][] = array($rr['file'],$rr['function'],$rr['priority'],$rr['hook_version']); } } -//logger('hooks: ' . print_r(App::$hooks,true)); + //logger('hooks: ' . print_r(App::$hooks,true)); } /** @@ -259,15 +258,15 @@ function load_hooks() { * @param string $fn * function name of callback handler */ -function insert_hook($hook, $fn) { - $a = get_app(); +function insert_hook($hook, $fn, $version = 0, $priority = 0) { + if(! is_array(App::$hooks)) App::$hooks = array(); if(! array_key_exists($hook, App::$hooks)) App::$hooks[$hook] = array(); - App::$hooks[$hook][] = array('', $fn); + App::$hooks[$hook][] = array('', $fn, $priority, $version); } /** @@ -280,22 +279,34 @@ function insert_hook($hook, $fn) { * @param string|array &$data to transmit to the callback handler */ function call_hooks($name, &$data = null) { - $a = get_app(); - + $a = 0; if((is_array(App::$hooks)) && (array_key_exists($name, App::$hooks))) { foreach(App::$hooks[$name] as $hook) { + $origfn = $hook[1]; if($hook[0]) @include_once($hook[0]); + if(preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) { + $hook[1] = unserialize($hook[1]); + } + elseif(strpos($hook[1],'::')) { + // We shouldn't need to do this, but it appears that PHP + // isn't able to directly execute a string variable with a class + // method in the manner we are attempting it, so we'll + // turn it into an array. + $hook[1] = explode('::',$hook[1]); + } - if(function_exists($hook[1])) { + if(is_callable($hook[1])) { $func = $hook[1]; - $func($a, $data); + if($hook[3]) + $func($data); + else + $func($a, $data); } else { - q("DELETE FROM hook WHERE hook = '%s' AND file = '%s' AND function = '%s'", dbesc($name), dbesc($hook[0]), - dbesc($hook[1]) + dbesc($origfn) ); } } @@ -535,8 +546,11 @@ function format_css_if_exists($source) { else $path = theme_include($source[0]); - if($path) - return '<link rel="stylesheet" href="' . script_path() . '/' . $path . '" type="text/css" media="' . $source[1] . '">' . "\r\n"; + if($path) { + $path = script_path() . '/' . $path; + $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; + return '<link rel="stylesheet" href="' . $path . $qstring . '" type="text/css" media="' . $source[1] . '">' . "\r\n"; + } } /* @@ -612,8 +626,11 @@ function format_js_if_exists($source) { $path = $source; else $path = theme_include($source); - if($path) - return '<script src="' . script_path() . '/' . $path . '" ></script>' . "\r\n" ; + if($path) { + $path = script_path() . '/' . $path; + $qstring = ((parse_url($path, PHP_URL_QUERY)) ? '&' : '?') . 'v=' . STD_VERSION; + return '<script src="' . $path . $qstring . '" ></script>' . "\r\n" ; + } } @@ -678,4 +695,4 @@ function folder_exists($folder) // If it exist, check if it's a directory return (($path !== false) && is_dir($path)) ? $path : false; -}
\ No newline at end of file +} diff --git a/include/text.php b/include/text.php index 0a7f84b01..f8bc4b6b0 100644 --- a/include/text.php +++ b/include/text.php @@ -1532,35 +1532,6 @@ function prepare_body(&$item,$attach = false) { $s = sslify($s); - // Look for spoiler - $spoilersearch = '<blockquote class="spoiler">'; - - // Remove line breaks before the spoiler - while ((strpos($s, "\n".$spoilersearch) !== false)) - $s = str_replace("\n".$spoilersearch, $spoilersearch, $s); - while ((strpos($s, "<br />".$spoilersearch) !== false)) - $s = str_replace("<br />".$spoilersearch, $spoilersearch, $s); - - while ((strpos($s, $spoilersearch) !== false)) { - - $pos = strpos($s, $spoilersearch); - $rnd = random_string(8); - $spoilerreplace = '<br /> <span id="spoiler-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'spoiler-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'. - '<blockquote class="spoiler" id="spoiler-'.$rnd.'" style="display: none;">'; - $s = substr($s, 0, $pos).$spoilerreplace.substr($s, $pos+strlen($spoilersearch)); - } - - // Look for quote with author - $authorsearch = '<blockquote class="author">'; - - while ((strpos($s, $authorsearch) !== false)) { - $pos = strpos($s, $authorsearch); - $rnd = random_string(8); - $authorreplace = '<br /> <span id="author-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'author-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'. - '<blockquote class="author" id="author-'.$rnd.'" style="display: block;">'; - $s = substr($s, 0, $pos).$authorreplace.substr($s, $pos+strlen($authorsearch)); - } - $prep_arr = array( 'item' => $item, 'photo' => $photo, @@ -1854,8 +1825,10 @@ function lang_selector() { } -function return_bytes ($size_str) { - switch (substr ($size_str, -1)) { +function engr_units_to_bytes ($size_str) { + if(! $size_str) + return $size_str; + switch (substr(trim($size_str), -1)) { case 'M': case 'm': return (int)$size_str * 1048576; case 'K': case 'k': return (int)$size_str * 1024; case 'G': case 'g': return (int)$size_str * 1073741824; diff --git a/include/zot.php b/include/zot.php index 0cdf7fc87..1ca1b862b 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3121,7 +3121,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { import_conv($channel,$arr['conv']); if(array_key_exists('mail',$arr) && $arr['mail']) - import_mail($channel,$arr['mail']); + sync_mail($channel,$arr['mail']); if(array_key_exists('event',$arr) && $arr['event']) sync_events($channel,$arr['event']); @@ -4048,6 +4048,17 @@ function delivery_report_is_storable($dr) { if(($dr['location'] !== z_root()) && ($dr['sender'] === $rxchan) && ($dr['status'] === 'recipient_not_found')) return false; + // If you have a private post with a recipient list, every single site is going to report + // back a failed delivery for anybody on that list that isn't local to them. We're only + // concerned about this if we have a local hubloc record which says we expected them to + // have a channel on that site. + + $r = q("select hubloc_id from hubloc where hubloc_hash = '%s' and hubloc_url = '%s'", + dbesc($rxchan), + dbesc($dr['location']) + ); + if((! $r) && ($dr['status'] === 'recipient_not_found')) + return false; $r = q("select abook_id from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($rxchan), |