aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php3
-rw-r--r--include/ItemObject.php20
-rw-r--r--include/bbcode.php9
-rw-r--r--include/cli_startup.php1
-rw-r--r--include/config.php290
-rw-r--r--include/conversation.php82
-rw-r--r--include/directory.php16
-rw-r--r--include/enotify.php21
-rwxr-xr-xinclude/items.php116
-rw-r--r--include/network.php20
-rw-r--r--include/notifier.php6
-rw-r--r--include/poller.php3
-rw-r--r--include/settings.php99
-rw-r--r--include/taxonomy.php159
-rwxr-xr-xinclude/text.php370
-rw-r--r--include/zot.php77
16 files changed, 749 insertions, 543 deletions
diff --git a/include/Contact.php b/include/Contact.php
index b2d459ca4..245682454 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -76,6 +76,9 @@ function abook_toggle_flag($abook,$flag) {
intval($abook['abook_id']),
intval($abook['abook_channel'])
);
+ $a = get_app();
+ if($a->data['abook'])
+ $a->data['abook']['abook_flags'] = $a->data['abook']['abook_flags'] ^ $flag;
return $r;
}
diff --git a/include/ItemObject.php b/include/ItemObject.php
index ccd192ff5..e057936ae 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -44,14 +44,9 @@ class Item extends BaseObject {
$this->commentable = $this->writable;
if(($this->observer) && (! $this->writable)) {
- $this->commentable = perm_is_allowed($this->data['uid'],$this->observer['xchan_hash'],'post_comments');
+ $this->commentable = can_comment_on_post($this->observer['xchan_hash'],$data);
}
-// logger('writable: ' . $this->writable);
-// logger('commentable: ' . $this->commentable . ' uid=' . $this->data['uid'] . ' observer=' . $this->observer['xchan_hash']);
-// if(get_config('system','thread_allow') && $a->theme_thread_allow && !$this->is_toplevel())
-// $this->threaded = true;
-
// Prepare the children
if(count($data['children'])) {
foreach($data['children'] as $item) {
@@ -152,6 +147,7 @@ class Item extends BaseObject {
$this->check_wall_to_wall();
if($this->is_toplevel()) {
+ // FIXME check this permission
if($conv->get_profile_owner() == local_user()) {
// FIXME we don't need all this stuff, some can be done in the template
@@ -166,15 +162,19 @@ class Item extends BaseObject {
'starred' => t('starred'),
);
- $tagger = array(
- 'tagit' => t("add tag"),
- 'classtagger' => "",
- );
}
} else {
$indent = 'comment';
}
+ // FIXME - check this permission
+ if($conv->get_profile_owner() == local_user()) {
+ $tagger = array(
+ 'tagit' => t("add tag"),
+ 'classtagger' => "",
+ );
+ }
+
if($this->is_commentable()) {
$like = array( t("I like this \x28toggle\x29"), t("like"));
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
diff --git a/include/bbcode.php b/include/bbcode.php
index 4f99a8038..862570348 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -424,11 +424,14 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) {
$Text = preg_replace_callback("/\[video\](.*?)\[\/video\]/ism", 'tryoembed', $Text);
$Text = preg_replace_callback("/\[audio\](.*?)\[\/audio\]/ism", 'tryoembed', $Text);
- } else {
- $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '$1', $Text);
- $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '$1', $Text);
}
+ // if video couldn't be embedded, link to it instead.
+
+ $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1">$1</a>', $Text);
+
+
// html5 video and audio
diff --git a/include/cli_startup.php b/include/cli_startup.php
index 1d5861541..6bd4e7520 100644
--- a/include/cli_startup.php
+++ b/include/cli_startup.php
@@ -21,7 +21,6 @@ function cli_startup() {
require_once('include/session.php');
- load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','baseurl'));
diff --git a/include/config.php b/include/config.php
index dc4470823..1f7a4dbd7 100644
--- a/include/config.php
+++ b/include/config.php
@@ -17,20 +17,23 @@
function load_config($family) {
global $a;
- $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
- if($r) {
- foreach($r as $rr) {
- $k = $rr['k'];
- if ($family === 'config') {
- $a->config[$k] = $rr['v'];
- } else {
- $a->config[$family][$k] = $rr['v'];
+
+ if(! array_key_exists($family,$a->config))
+ $a->config[$family] = array();
+
+ if(! array_key_exists('config_loaded',$a->config[$family])) {
+
+ $r = q("SELECT * FROM config WHERE cat = '%s'", dbesc($family));
+ if($r !== false) {
+ if($r) {
+ foreach($r as $rr) {
+ $k = $rr['k'];
+ $a->config[$family][$k] = $rr['v'];
+ }
}
+ $a->config[$family]['config_loaded'] = true;
}
- } else if ($family != 'config') {
- // Negative caching
- $a->config[$family] = "!<unset>!";
- }
+ }
}
// get a particular config variable given the family name
@@ -42,54 +45,49 @@ function load_config($family) {
// to hit the DB again for this item.
-function get_config($family, $key, $instore = false) {
+function get_config($family, $key) {
global $a;
- if(! $instore) {
- // Looking if the whole family isn't set
- if(isset($a->config[$family])) {
- if($a->config[$family] === '!<unset>!') {
- return false;
- }
- }
+ if((! array_key_exists($family,$a->config)) || (! array_key_exists('config_loaded',$a->config[$family])))
+ load_config($family);
- if(isset($a->config[$family][$key])) {
- if($a->config[$family][$key] === '!<unset>!') {
- return false;
- }
- return $a->config[$family][$key];
+ if(array_key_exists('config_loaded',$a->config[$family])) {
+ if(! array_key_exists($key,$a->config[$family])) {
+ return false;
}
+ return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$family][$key]))
+ ? unserialize($a->config[$family][$key])
+ : $a->config[$family][$key]
+ );
}
- $ret = q("SELECT `v` FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
+ return false;
+}
+
+function get_config_from_storage($family,$key) {
+ $ret = q("select * from config where cat = '%s' and k = '%s' limit 1",
dbesc($family),
dbesc($key)
);
- if(count($ret)) {
- // manage array value
- $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
- $a->config[$family][$key] = $val;
- return $val;
- }
- else {
- $a->config[$family][$key] = '!<unset>!';
- }
- return false;
+ return $ret;
}
+
+
// Store a config value ($value) in the category ($family)
// under the key ($key)
// Return the value, or false if the database update failed
-
function set_config($family,$key,$value) {
global $a;
// manage array value
- $dbvalue = (is_array($value)?serialize($value):$value);
- $dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
- if(get_config($family,$key,true) === false) {
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(get_config($family,$key) === false || (! get_config_from_storage($family,$key))) {
$a->config[$family][$key] = $value;
- $ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
+
+ $ret = q("INSERT INTO config ( cat, k, v ) VALUES ( '%s', '%s', '%s' ) ",
dbesc($family),
dbesc($key),
dbesc($dbvalue)
@@ -99,7 +97,7 @@ function set_config($family,$key,$value) {
return $ret;
}
- $ret = q("UPDATE `config` SET `v` = '%s' WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
+ $ret = q("UPDATE config SET v = '%s' WHERE cat = '%s' AND k = '%s' LIMIT 1",
dbesc($dbvalue),
dbesc($family),
dbesc($key)
@@ -112,14 +110,11 @@ function set_config($family,$key,$value) {
return $ret;
}
-
-
function del_config($family,$key) {
-
global $a;
- if(x($a->config[$family],$key))
+ if(array_key_exists($family,$a->config) && array_key_exists($key,$a->config[$family]))
unset($a->config[$family][$key]);
- $ret = q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1",
+ $ret = q("DELETE FROM config WHERE cat = '%s' AND k = '%s' LIMIT 1",
dbesc($family),
dbesc($key)
);
@@ -127,11 +122,16 @@ function del_config($family,$key) {
}
-function load_pconfig($uid,$family) {
+function load_pconfig($uid,$family = '') {
global $a;
- if(($uid) && (! array_key_exists($uid,$a->config)))
+ if($uid === false)
+ return false;
+
+ if(! array_key_exists($uid,$a->config))
$a->config[$uid] = array();
+ if(($family) && (! array_key_exists($family,$a->config[$uid])))
+ $a->config[$uid][$family] = array();
if($family) {
$r = q("SELECT * FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
@@ -149,15 +149,13 @@ function load_pconfig($uid,$family) {
foreach($r as $rr) {
$k = $rr['k'];
$c = $rr['cat'];
- if(! array_key_exists($c,$a->config[$uid]))
+ if(! array_key_exists($c,$a->config[$uid])) {
$a->config[$uid][$c] = array();
+ $a->config[$uid][$c]['config_loaded'] = true;
+ }
$a->config[$uid][$c][$k] = $rr['v'];
}
}
-// else if ($family != 'config') {
- // Negative caching
-// $a->config[$uid][$family] = "!<unset>!";
-// }
}
@@ -167,74 +165,77 @@ function get_pconfig($uid,$family, $key, $instore = false) {
global $a;
- if(! $instore) {
- // Looking if the whole family isn't set
- if(isset($a->config[$uid][$family])) {
- if($a->config[$uid][$family] === '!<unset>!') {
- return false;
- }
- }
+ if($uid === false)
+ return false;
- if(isset($a->config[$uid][$family][$key])) {
- if($a->config[$uid][$family][$key] === '!<unset>!') {
- return false;
- }
- return $a->config[$uid][$family][$key];
- }
- }
+ if(! array_key_exists($uid,$a->config))
+ load_pconfig($uid);
- $ret = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
- intval($uid),
- dbesc($family),
- dbesc($key)
- );
+ if((! array_key_exists($family,$a->config[$uid])) || (! array_key_exists($key,$a->config[$uid][$family])))
+ return false;
- if(count($ret)) {
- $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
- $a->config[$uid][$family][$key] = $val;
- return $val;
- }
- else {
- $a->config[$uid][$family][$key] = '!<unset>!';
- }
- return false;
+ return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$uid][$family][$key]))
+ ? unserialize($a->config[$uid][$family][$key])
+ : $a->config[$uid][$family][$key]
+ );
}
+function set_pconfig($uid,$family,$key,$value) {
+ global $a;
+ // manage array value
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
-// Same as above functions except these are for personal config storage and take an
-// additional $uid argument.
-
-
-function set_pconfig($uid,$family,$key,$value) {
+ if(get_pconfig($uid,$family,$key) === false) {
+ if(! array_key_exists($uid,$a->config))
+ $a->config[$uid] = array();
+ if(! array_key_exists($family,$a->config[$uid]))
+ $a->config[$uid][$family] = array();
- global $a;
+ // keep a separate copy for all variables which were
+ // set in the life of this page. We need this to
+ // synchronise channel clones.
- // manage array value
- $dbvalue = (is_array($value)?serialize($value):$value);
+ if(! array_key_exists('transient',$a->config[$uid]))
+ $a->config[$uid]['transient'] = array();
+ if(! array_key_exists($family,$a->config[$uid]['transient']))
+ $a->config[$uid]['transient'][$family] = array();
- if(get_pconfig($uid,$family,$key,true) === false) {
$a->config[$uid][$family][$key] = $value;
- $ret = q("INSERT INTO `pconfig` ( `uid`, `cat`, `k`, `v` ) VALUES ( %d, '%s', '%s', '%s' ) ",
+ $a->config[$uid]['transient'][$family][$key] = $value;
+
+ $ret = q("INSERT INTO pconfig ( uid, cat, k, v ) VALUES ( %d, '%s', '%s', '%s' ) ",
intval($uid),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
- if($ret)
+ if($ret)
return $value;
return $ret;
}
- $ret = q("UPDATE `pconfig` SET `v` = '%s' WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
+
+ $ret = q("UPDATE pconfig SET v = '%s' WHERE uid = %d and cat = '%s' AND k = '%s' LIMIT 1",
dbesc($dbvalue),
intval($uid),
dbesc($family),
dbesc($key)
);
+ // keep a separate copy for all variables which were
+ // set in the life of this page. We need this to
+ // synchronise channel clones.
+
+ if(! array_key_exists('transient',$a->config[$uid]))
+ $a->config[$uid]['transient'] = array();
+ if(! array_key_exists($family,$a->config[$uid]['transient']))
+ $a->config[$uid]['transient'][$family] = array();
+
$a->config[$uid][$family][$key] = $value;
+ $a->config[$uid]['transient'][$family][$key] = $value;
if($ret)
return $value;
@@ -247,7 +248,7 @@ function del_pconfig($uid,$family,$key) {
global $a;
if(x($a->config[$uid][$family],$key))
unset($a->config[$uid][$family][$key]);
- $ret = q("DELETE FROM `pconfig` WHERE `uid` = %d AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
+ $ret = q("DELETE FROM pconfig WHERE uid = %d AND cat = '%s' AND k = '%s' LIMIT 1",
intval($uid),
dbesc($family),
dbesc($key)
@@ -257,61 +258,64 @@ function del_pconfig($uid,$family,$key) {
-function load_xconfig($xchan,$family) {
+function load_xconfig($xchan,$family = '') {
global $a;
- $r = q("SELECT * FROM `xconfig` WHERE `cat` = '%s' AND `xchan` = '%s'",
- dbesc($family),
- dbesc($xchan)
- );
- if(count($r)) {
+
+ if(! $xchan)
+ return false;
+
+ if(! array_key_exists($xchan,$a->config))
+ $a->config[$xchan] = array();
+ if(($family) && (! array_key_exists($family,$a->config[$xchan])))
+ $a->config[$xchan][$family] = array();
+
+ if($family) {
+ $r = q("SELECT * FROM `xconfig` WHERE `cat` = '%s' AND `xchan` = '%s'",
+ dbesc($family),
+ dbesc($xchan)
+ );
+ }
+ else {
+ $r = q("SELECT * FROM `xconfig` WHERE `xchan` = '%s'",
+ dbesc($xchan)
+ );
+ }
+
+ if($r) {
foreach($r as $rr) {
$k = $rr['k'];
- $a->config[$xchan][$family][$k] = $rr['v'];
+ $c = $rr['cat'];
+ if(! array_key_exists($c,$a->config[$xchan])) {
+ $a->config[$xchan][$c] = array();
+ $a->config[$xchan][$c]['config_loaded'] = true;
+ }
+ $a->config[$xchan][$c][$k] = $rr['v'];
}
- } else if ($family != 'config') {
- // Negative caching
- $a->config[$xchan][$family] = "!<unset>!";
- }
+ }
+
}
-function get_xconfig($xchan,$family, $key, $instore = false) {
+function get_xconfig($xchan,$family, $key) {
global $a;
- if(! $instore) {
- // Looking if the whole family isn't set
- if(isset($a->config[$xchan][$family])) {
- if($a->config[$xchan][$family] === '!<unset>!') {
- return false;
- }
- }
+ if(! $xchan)
+ return false;
- if(isset($a->config[$xchan][$family][$key])) {
- if($a->config[$xchan][$family][$key] === '!<unset>!') {
- return false;
- }
- return $a->config[$xchan][$family][$key];
- }
- }
+ if(! array_key_exists($xchan,$a->config))
+ load_xconfig($xchan);
- $ret = q("SELECT `v` FROM `xconfig` WHERE `xchan` = '%s' AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
- dbesc($xchan),
- dbesc($family),
- dbesc($key)
+ if((! array_key_exists($family,$a->config[$xchan])) || (! array_key_exists($key,$a->config[$xchan][$family])))
+ return false;
+
+ return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$xchan][$family][$key]))
+ ? unserialize($a->config[$xchan][$family][$key])
+ : $a->config[$xchan][$family][$key]
);
- if(count($ret)) {
- $val = (preg_match("|^a:[0-9]+:{.*}$|s", $ret[0]['v'])?unserialize( $ret[0]['v']):$ret[0]['v']);
- $a->config[$xchan][$family][$key] = $val;
- return $val;
- }
- else {
- $a->config[$xchan][$family][$key] = '!<unset>!';
- }
- return false;
}
@@ -320,21 +324,28 @@ function set_xconfig($xchan,$family,$key,$value) {
global $a;
// manage array value
- $dbvalue = (is_array($value)?serialize($value):$value);
+ $dbvalue = ((is_array($value)) ? serialize($value) : $value);
+ $dbvalue = ((is_bool($dbvalue)) ? intval($dbvalue) : $dbvalue);
+
+ if(get_xconfig($xchan,$family,$key) === false) {
+ if(! array_key_exists($xchan,$a->config))
+ $a->config[$xchan] = array();
+ if(! array_key_exists($family,$a->config[$xchan]))
+ $a->config[$xchan][$family] = array();
- if(get_xconfig($xchan,$family,$key,true) === false) {
$a->config[$xchan][$family][$key] = $value;
- $ret = q("INSERT INTO `xconfig` ( `xchan`, `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s', '%s' ) ",
+ $ret = q("INSERT INTO xconfig ( xchan, cat, k, v ) VALUES ( '%s', '%s', '%s', '%s' ) ",
dbesc($xchan),
dbesc($family),
dbesc($key),
dbesc($dbvalue)
);
- if($ret)
+ if($ret)
return $value;
return $ret;
}
- $ret = q("UPDATE `xconfig` SET `v` = '%s' WHERE `xchan` = '%s' AND `cat` = '%s' AND `k` = '%s' LIMIT 1",
+
+ $ret = q("UPDATE xconfig SET v = '%s' WHERE xchan = '%s' and cat = '%s' AND k = '%s' LIMIT 1",
dbesc($dbvalue),
dbesc($xchan),
dbesc($family),
@@ -346,6 +357,7 @@ function set_xconfig($xchan,$family,$key,$value) {
if($ret)
return $value;
return $ret;
+
}
diff --git a/include/conversation.php b/include/conversation.php
index 8e69e9ea3..410143a7a 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -6,7 +6,7 @@ require_once('include/items.php');
// is identical to the code in mod/message.php for 'item_extract_images' and
// 'item_redir_and_replace_images'
-if(! function_exists('item_extract_images')) {
+
function item_extract_images($body) {
$saved_image = array();
@@ -46,9 +46,9 @@ function item_extract_images($body) {
$new_body = $new_body . $orig_body;
return array('body' => $new_body, 'images' => $saved_image);
-}}
+}
+
-if(! function_exists('item_redir_and_replace_images')) {
function item_redir_and_replace_images($body, $images, $cid) {
$origbody = $body;
@@ -81,7 +81,7 @@ function item_redir_and_replace_images($body, $images, $cid) {
}
return $newbody;
-}}
+}
@@ -108,6 +108,44 @@ function localize_item(&$item){
$item_url = get_rel_link($obj['link'],'alternate');
+ $Bphoto = '';
+
+ switch($obj->type) {
+ case ACTIVITY_OBJ_PHOTO:
+ $post_type = t('photo');
+ break;
+ case ACTIVITY_OBJ_EVENT:
+ $post_type = t('event');
+ break;
+ case ACTIVITY_OBJ_PERSON:
+ $post_type = t('channel');
+ $author_name = $obj['title'];
+ if($obj['link']) {
+ $author_link = get_rel_link($obj['link'],'alternate');
+ $Bphoto = get_rel_link($obj['link'],'photo');
+ }
+ break;
+ case ACTIVITY_OBJ_THING:
+ $post_type = $obj['title'];
+ if($obj['owner']) {
+ if(array_key_exists('name',$obj['owner']))
+ $obj['owner']['name'];
+ if(array_key_exists('link',$obj['owner']))
+ $author_link = get_rel_link($obj['owner']['link'],'alternate');
+ }
+ if($obj['link']) {
+ $Bphoto = get_rel_link($obj['link'],'photo');
+ }
+ break;
+
+ case ACTIVITY_OBJ_NOTE:
+ default:
+ $post_type = t('status');
+ if($obj->id != $item['mid'])
+ $post_type = t('comment');
+ break;
+ }
+
// If we couldn't parse something useful, don't bother translating.
// We need something better than zid here, probably magic_link(), but it needs writing
@@ -117,21 +155,6 @@ function localize_item(&$item){
$author = '[zrl=' . chanlink_url($item['author']['xchan_url']) . ']' . $item['author']['xchan_name'] . '[/zrl]';
$objauthor = '[zrl=' . chanlink_url($author_link) . ']' . $author_name . '[/zrl]';
- switch($obj->type) {
- case ACTIVITY_OBJ_PHOTO:
- $post_type = t('photo');
- break;
- case ACTIVITY_OBJ_EVENT:
- $post_type = t('event');
- break;
- case ACTIVITY_OBJ_NOTE:
- default:
- $post_type = t('status');
- if($obj->id != $item['mid'])
- $post_type = t('comment');
- break;
- }
-
$plink = '[zrl=' . zid($item_url) . ']' . $post_type . '[/zrl]';
if(activity_match($item['verb'],ACTIVITY_LIKE)) {
@@ -141,6 +164,8 @@ function localize_item(&$item){
$bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
}
$item['body'] = $item['localize'] = sprintf($bodyverb, $author, $objauthor, $plink);
+ if($Bphoto != "")
+ $item['body'] .= "\n\n\n" . '[zrl=' . chanlink_url($author_link) . '][zmg=80x80]' . $Bphoto . '[/zmg][/zrl]';
}
@@ -148,7 +173,8 @@ function localize_item(&$item){
if (activity_match($item['verb'],ACTIVITY_FRIEND)) {
- if ($item['obj_type']=="" || $item['obj_type']!== ACTIVITY_OBJ_PERSON) return;
+
+// if ($item['obj_type']=="" || $item['obj_type']!== ACTIVITY_OBJ_PERSON) return;
$Aname = $item['author']['xchan_name'];
$Alink = $item['author']['xchan_url'];
@@ -349,7 +375,9 @@ function count_descendants($item) {
function visible_activity($item) {
- if(activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE))
+ // likes can apply to other things besides posts. Check if they are post children, in which case we handle them specially
+
+ if((activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)) && ($item['mid'] != $item['parent_mid']))
return false;
return true;
}
@@ -826,7 +854,7 @@ function best_link_url($item) {
}
-if(! function_exists('item_photo_menu')){
+
function item_photo_menu($item){
$a = get_app();
$contact = null;
@@ -893,9 +921,9 @@ function item_photo_menu($item){
elseif ($v!="") $o .= "<li><a href=\"$v\">$k</a></li>\n";
}
return $o;
-}}
+}
+
-if(! function_exists('like_puller')) {
function like_puller($a,$item,&$arr,$mode) {
$url = '';
@@ -923,7 +951,7 @@ function like_puller($a,$item,&$arr,$mode) {
$arr[$item['thr_parent'] . '-l'][] = '<a href="'. $url . '"'. $sparkle .'>' . $item['author']['xchan_name'] . '</a>';
}
return;
-}}
+}
// Format the like/dislike text for a profile item
// $cnt = number of people who like/dislike the item
@@ -932,7 +960,7 @@ function like_puller($a,$item,&$arr,$mode) {
// $id = item id
// returns formatted text
-if(! function_exists('format_like')) {
+
function format_like($cnt,$arr,$type,$id) {
$o = '';
if($cnt == 1)
@@ -956,7 +984,7 @@ function format_like($cnt,$arr,$type,$id) {
$o .= "\t" . '<div id="' . $type . 'list-' . $id . '" style="display: none;" >' . $str . '</div>';
}
return $o;
-}}
+}
function status_editor($a,$x,$popup=false) {
diff --git a/include/directory.php b/include/directory.php
index 5f3696a58..c286f5683 100644
--- a/include/directory.php
+++ b/include/directory.php
@@ -19,11 +19,6 @@ function directory_run($argv, $argc){
if($dirmode === false)
$dirmode = DIRECTORY_MODE_NORMAL;
- if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) {
- syncdirs($argv[1]);
- return;
- }
-
$x = q("select * from channel where channel_id = %d limit 1",
intval($argv[1])
);
@@ -32,6 +27,15 @@ function directory_run($argv, $argc){
$channel = $x[0];
+
+ if(($dirmode == DIRECTORY_MODE_PRIMARY) || ($dirmode == DIRECTORY_MODE_STANDALONE)) {
+ syncdirs($argv[1]);
+
+ // Now update all the connections
+ proc_run('php','include/notifier.php','refresh_all',$channel['channel_id']);
+ return;
+ }
+
$directory = find_upstream_directory($dirmode);
if($directory) {
@@ -49,7 +53,7 @@ function directory_run($argv, $argc){
// Now update all the connections
- proc_run('php','notifier','refresh_all',$channel['channel_id']);
+ proc_run('php','include/notifier.php','refresh_all',$channel['channel_id']);
}
diff --git a/include/enotify.php b/include/enotify.php
index 5728d054c..3b7a643ed 100644
--- a/include/enotify.php
+++ b/include/enotify.php
@@ -50,6 +50,8 @@ function notification($params) {
$additional_mail_header = "";
+ // We really should pass this through localize_item - but only if we have a complete item. We may only have a couple of elements.
+
if(array_key_exists('item',$params)) {
$title = $params['item']['title'];
$body = $params['item']['body'];
@@ -352,10 +354,27 @@ function notification($params) {
logger('notification: sending notification email');
+
$textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r", "\\n"), "\n",
$body))),ENT_QUOTES,'UTF-8'));
+
$htmlversion = html_entity_decode(bbcode(stripslashes(str_replace(array("\\r\\n", "\\r","\\n\\n" ,"\\n"),
- "<br />\n",$body))));
+ "<br />\n",$body))), ENT_QUOTES,'UTF-8');
+
+
+ // use $_SESSION['zid_override'] to force zid() to use
+ // the recipient address instead of the current observer
+
+ $_SESSION['zid_override'] = $recip['channel_address'] . '@' . get_app()->get_hostname();
+ $_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
+
+ $textversion = zidify_links($textversion);
+ $htmlversion = zidify_links($htmlversion);
+
+ // unset when done to revert to normal behaviour
+
+ unset($_SESSION['zid_override']);
+ unset($_SESSION['zrl_override']);
$datarray = array();
diff --git a/include/items.php b/include/items.php
index 64eeae4b4..c4ffcbca6 100755
--- a/include/items.php
+++ b/include/items.php
@@ -53,6 +53,37 @@ function collect_recipients($item,&$private) {
}
+
+function can_comment_on_post($observer_xchan,$item) {
+ if(! $observer_xchan)
+ return false;
+ if($item['comment_policy'] === 'none')
+ return false;
+ switch($item['comment_policy']) {
+ case 'self':
+ if($observer_xchan === $item['author_xchan'] || $observer_xchan === $item['owner_xchan'])
+ return true;
+ break;
+ case 'public':
+ return false;
+ break;
+ case 'contacts':
+ case '':
+ if(($item['owner']['abook_xchan']) && ($item['owner']['abook_their_perms'] & PERMS_W_COMMENT))
+ return true;
+ break;
+ default:
+ break;
+ }
+ if(strstr($item['comment_policy'],'network:') && strstr($item['comment_policy'],'red'))
+ return true;
+ if(strstr($item['comment_policy'],'site:') && strstr($item['comment_policy'],get_app()->get_hostname()))
+ return true;
+
+ return false;
+}
+
+
/**
* @function red_zrl_callback
* preg_match function when fixing 'naked' links in mod item.php
@@ -142,6 +173,7 @@ function post_activity_item($arr) {
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? $arr['deny_cid'] : $channel['channel_deny_cid']);
$arr['deny_gid'] = ((x($arr,'deny_gid')) ? $arr['deny_gid'] : $channel['channel_deny_gid']);
+ $arr['comment_policy'] = map_scope($channel['channel_w_comment']);
// for the benefit of plugins, we will behave as if this is an API call rather than a normal online post
@@ -481,7 +513,8 @@ function get_item_elements($x) {
$arr['mimetype'] = (($x['mimetype']) ? htmlentities($x['mimetype'], ENT_COMPAT,'UTF-8',false) : '');
$arr['obj_type'] = (($x['object_type']) ? htmlentities($x['object_type'], ENT_COMPAT,'UTF-8',false) : '');
$arr['tgt_type'] = (($x['target_type']) ? htmlentities($x['target_type'], ENT_COMPAT,'UTF-8',false) : '');
-
+ $arr['comment_policy'] = (($x['comment_scope']) ? htmlentities($x['comment_scope'], ENT_COMPAT,'UTF-8',false) : 'contacts');
+
$arr['object'] = activity_sanitise($x['object']);
$arr['target'] = activity_sanitise($x['target']);
@@ -545,17 +578,21 @@ function encode_item($item) {
logger('encode_item: ' . print_r($item,true));
- $r = q("select channel_r_stream from channel where channel_id = %d limit 1",
+ $r = q("select channel_r_stream, channel_w_comment from channel where channel_id = %d limit 1",
intval($item['uid'])
);
- if($r)
+ if($r) {
$public_scope = $r[0]['channel_r_stream'];
- else
+ $comment_scope = $r[0]['channel_w_comment'];
+ }
+ else {
$public_scope = 0;
+ $comment_scope = 0;
+ }
$scope = map_scope($public_scope);
-
+ $c_scope = map_scope($comment_scope);
if($item['item_restrict'] & ITEM_DELETED) {
$x['message_id'] = $item['mid'];
@@ -597,6 +634,11 @@ function encode_item($item) {
if(! in_array('private',$y))
$x['public_scope'] = $scope;
+ if($item['item_flags'] & ITEM_NOCOMMENT)
+ $x['comment_scope'] = 'none';
+ else
+ $x['comment_scope'] = $c_scope;
+
if($item['term'])
$x['tags'] = encode_item_terms($item['term']);
@@ -818,6 +860,7 @@ function get_profile_elements($x) {
$arr['desc'] = (($x['title']) ? htmlentities($x['title'],ENT_COMPAT,'UTF-8',false) : '');
$arr['dob'] = datetime_convert('UTC','UTC',$x['birthday'],'Y-m-d');
+ $arr['age'] = (($x['age']) ? intval($x['age']) : 0);
$arr['gender'] = (($x['gender']) ? htmlentities($x['gender'], ENT_COMPAT,'UTF-8',false) : '');
$arr['marital'] = (($x['marital']) ? htmlentities($x['marital'], ENT_COMPAT,'UTF-8',false) : '');
@@ -1323,10 +1366,17 @@ function item_store($arr,$force_parent = false) {
$arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : '');
$arr['app'] = ((x($arr,'app')) ? notags(trim($arr['app'])) : '');
$arr['item_restrict'] = ((x($arr,'item_restrict')) ? intval($arr['item_restrict']) : 0 );
+
+ $arr['comment_policy'] = ((x($arr,'comment_policy')) ? notags(trim($arr['comment_policy'])) : 'contacts' );
+
$arr['item_flags'] = ((x($arr,'item_flags')) ? intval($arr['item_flags']) : 0 );
$arr['item_flags'] = $arr['item_flags'] | ITEM_UNSEEN;
+ if($arr['comment_policy'] == 'none')
+ $arr['item_flags'] = $arr['item_flags'] | ITEM_NOCOMMENT;
+
+
// handle time travelers
// Allow a bit of fudge in case somebody just has a slightly slow/fast clock
@@ -1811,27 +1861,73 @@ function tag_deliver($uid,$item_id) {
// FIXME --- If the item is deleted, remove the tag from the parent.
// (First ensure that deleted items use this function, or else do that part separately.)
+ logger('tag_deliver: community tag activity received');
+
if(($item['owner_xchan'] === $u[0]['channel_hash']) && (! get_pconfig($u[0]['channel_id'],'system','blocktags'))) {
$j_tgt = json_decode($item['target'],true);
- if($j_tgt && $j_tgt['mid']) {
+ if($j_tgt && $j_tgt['id']) {
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
- dbesc($j_tgt['mid']),
+ dbesc($j_tgt['id']),
intval($u[0]['channel_id'])
);
if($p) {
$j_obj = json_decode($item['object'],true);
+ logger('tag_deliver: tag object: ' . print_r($j_obj,true), LOGGER_DATA);
if($j_obj && $j_obj['id'] && $j_obj['title']) {
- store_item_tag($u[0]['channel_id'],$p[0]['id'],TERM_OBJ_POST,TERM_HASHTAG,$j_obj['title'],$j['obj']['id']);
+ if(is_array($j_obj['link']))
+ $taglink = get_rel_link($j_obj['link'],'alternate');
+ store_item_tag($u[0]['channel_id'],$p[0]['id'],TERM_OBJ_POST,TERM_HASHTAG,$j_obj['title'],$j_obj['id']);
proc_run('php','include/notifier.php','edit_post',$p[0]['id']);
}
}
}
}
+ else
+ logger('tag_deliver: tag permission denied for ' . $u[0]['channel_address']);
+ }
+
+ // This might be a followup by the original post author to a tagged forum
+ // If so setup a second delivery chain
+
+ $r = null;
+
+ if( ! ($item['item_flags'] & ITEM_THREAD_TOP)) {
+ $x = q("select * from item where id = parent and parent = %d and uid = %d limit 1",
+ intval($item['parent']),
+ intval($uid)
+ );
+ if(($x) && ($x[0]['item_flags'] & ITEM_UPLINK) && ($x[0]['author_xchan'] == $item['author_xchan'])) {
+ logger('tag_deliver: creating second delivery chain for owner comment.');
+
+ // now change this copy of the post to a forum head message and deliver to all the tgroup members
+ // also reset all the privacy bits to the forum default permissions
+
+ $private = (($u[0]['allow_cid'] || $u[0]['allow_gid'] || $u[0]['deny_cid'] || $u[0]['deny_gid']) ? 1 : 0);
+
+ $flag_bits = ITEM_WALL|ITEM_ORIGIN;
+
+ $r = q("update item set item_flags = ( item_flags | %d ), owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s',
+ deny_cid = '%s', deny_gid = '%s', item_private = %d where id = %d limit 1",
+ intval($flag_bits),
+ dbesc($u[0]['channel_hash']),
+ dbesc($u[0]['allow_cid']),
+ dbesc($u[0]['allow_gid']),
+ dbesc($u[0]['deny_cid']),
+ dbesc($u[0]['deny_gid']),
+ intval($private),
+ intval($item_id)
+ );
+ if($r)
+ proc_run('php','include/notifier.php','tgroup',$item_id);
+ else
+ logger('tag_deliver: failed to update item');
+ }
}
$terms = get_terms_oftype($item['term'],TERM_MENTION);
- logger('tag_deliver: post mentions: ' . print_r($terms,true), LOGGER_DATA);
+ if($terms)
+ logger('tag_deliver: post mentions: ' . print_r($terms,true), LOGGER_DATA);
$link = normalise_link($a->get_baseurl() . '/channel/' . $u[0]['channel_address']);
@@ -4690,7 +4786,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
intval($uid)
);
if($r) {
- $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = " . dbesc($r[0]['abook_xchan']) . " or owner_xchan = " . dbesc($r[0]['abook_xchan']) . " ) and item_restrict = 0 ) ";
+ $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND uid = " . intval($arr['uid']) . " AND ( author_xchan = '" . dbesc($r[0]['abook_xchan']) . "' or owner_xchan = '" . dbesc($r[0]['abook_xchan']) . "' ) and item_restrict = 0 ) ";
}
else {
$result['message'] = t('Connection not found.');
diff --git a/include/network.php b/include/network.php
index f750fcfd8..8b9a8a6a6 100644
--- a/include/network.php
+++ b/include/network.php
@@ -1049,15 +1049,21 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
$s = htmlspecialchars_decode($s);
$matches = null;
- $c = preg_match_all('/\[img.*?\](.*?)\[\/img\]/ism',$s,$matches,PREG_SET_ORDER);
+ $c = preg_match_all('/\[img(.*?)\](.*?)\[\/img\]/ism',$s,$matches,PREG_SET_ORDER);
if($c) {
require_once('include/photo/photo_driver.php');
foreach($matches as $mtch) {
- logger('scale_external_image: ' . $mtch[1]);
+ logger('scale_external_image: ' . $mtch[1] . ' ' . $mtch[2]);
+
+ if(substr($mtch[1],0,1) == '=') {
+ $owidth = intval(substr($mtch[1],1));
+ if(intval($owidth) > 0 && intval($owidth) < 640)
+ continue;
+ }
$hostname = str_replace('www.','',substr($a->get_baseurl(),strpos($a->get_baseurl(),'://')+3));
- if(stristr($mtch[1],$hostname))
+ if(stristr($mtch[2],$hostname))
continue;
// $scale_replace, if passed, is an array of two elements. The
@@ -1066,9 +1072,9 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
// This allows Friendica to display the smaller remote image if
// one exists, while still linking to the full-size image
if($scale_replace)
- $scaled = str_replace($scale_replace[0], $scale_replace[1], $mtch[1]);
+ $scaled = str_replace($scale_replace[0], $scale_replace[1], $mtch[2]);
else
- $scaled = $mtch[1];
+ $scaled = $mtch[2];
$i = fetch_url($scaled);
$cache = get_config('system','itemcache');
@@ -1078,7 +1084,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
}
// guess mimetype from headers or filename
- $type = guess_image_type($mtch[1],true);
+ $type = guess_image_type($mtch[2],true);
if($i) {
$ph = photo_factory($i, $type);
@@ -1094,7 +1100,7 @@ function scale_external_images($s, $include_link = true, $scale_replace = false)
logger('scale_external_images: ' . $orig_width . '->' . $new_width . 'w ' . $orig_height . '->' . $new_height . 'h' . ' match: ' . $mtch[0], LOGGER_DEBUG);
$s = str_replace($mtch[0],'[img=' . $new_width . 'x' . $new_height. ']' . $scaled . '[/img]'
. "\n" . (($include_link)
- ? '[zrl=' . $mtch[1] . ']' . t('view full size') . '[/zrl]' . "\n"
+ ? '[zrl=' . $mtch[2] . ']' . t('view full size') . '[/zrl]' . "\n"
: ''),$s);
logger('scale_external_images: new string: ' . $s, LOGGER_DEBUG);
}
diff --git a/include/notifier.php b/include/notifier.php
index 7d107e4d4..96c0bf31f 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -189,6 +189,7 @@ function notifier_run($argv, $argc){
$item = $suggest[0];
}
elseif($cmd === 'refresh_all') {
+ logger('notifier: refresh_all: ' . $item_id);
$s = q("select * from channel where channel_id = %d limit 1",
intval($item_id)
);
@@ -196,10 +197,9 @@ function notifier_run($argv, $argc){
$channel = $s[0];
$uid = $item_id;
$recipients = array();
- $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d) and not (abook_flags & %d)",
+ $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d)",
intval($item_id),
- intval(ABOOK_FLAG_SELF),
- intval(ABOOK_FLAG_PENDING)
+ intval(ABOOK_FLAG_SELF)
);
if($r) {
foreach($r as $rr) {
diff --git a/include/poller.php b/include/poller.php
index dff16d3d7..f50bd4e3e 100644
--- a/include/poller.php
+++ b/include/poller.php
@@ -63,6 +63,9 @@ function poller_run($argv, $argc){
// once daily run birthday_updates and then expire in background
+ // FIXME: add birthday updates, both locally and for xprof for use
+ // by directory servers
+
$d1 = get_config('system','last_expire_day');
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
diff --git a/include/settings.php b/include/settings.php
new file mode 100644
index 000000000..26f375a42
--- /dev/null
+++ b/include/settings.php
@@ -0,0 +1,99 @@
+<?php /** @file */
+
+/**
+ * Send a zot packet to all hubs where this channel is duplicated, refreshing
+ * such things as personal settings, channel permissions, address book updates, etc.
+ */
+
+require_once('include/zot.php');
+
+function build_sync_packet($uid = 0, $packet = null) {
+ $a = get_app();
+
+ if(! $uid)
+ $uid = local_user();
+
+ if(! $uid)
+ return;
+
+ $channel = $a->get_channel();
+
+ $h = q("select * from hubloc where hubloc_hash = '%s'",
+ dbesc($channel['channel_hash'])
+ );
+
+ if(! $h)
+ return;
+
+ $synchubs = array();
+
+ foreach($h as $x) {
+ if($x['host'] == $a->get_hostname())
+ continue;
+ $synchubs[] = $x;
+ }
+
+ if(! $synchubs)
+ return;
+
+ $r = q("select xchan_guid, xchan_guid_sig from xchan where xchan_hash = '%s' limit 1",
+ dbesc($channel['channel_hash'])
+ );
+ if(! $r)
+ return;
+
+ $env_recips = array();
+ $env_recips[] = array('guid' => $r[0]['xchan_guid'],'guid_sig' => $r[0]['xchan_guid_sig']);
+
+ $info = (($packet) ? $packet : array());
+
+ if(array_key_exists($uid,$a->config) && array_key_exists('transient',$a->config[$uid])) {
+ $settings = $a->config[$uid]['transient'];
+ if($settings) {
+ $info['config'] = $settings;
+ }
+ }
+
+ if($channel) {
+ $info['channel'] = array();
+ foreach($channel as $k => $v) {
+ if(strpos('channel_',$k) !== 0)
+ continue;
+
+ // don't pass these elements, they should not be synchronised
+
+ $disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey');
+
+ if(in_array($k,$disallowed))
+ continue;
+
+ $info['channel'][$k] = $v;
+ }
+ }
+
+ $interval = ((get_config('system','delivery_interval') !== false)
+ ? intval(get_config('system','delivery_interval')) : 2 );
+
+
+ foreach($synchubs as $hub) {
+ $hash = random_string();
+ $n = zot_build_packet($channel,'channel_sync',$env_recips,$hub['hubloc_sitekey'],null,$hash);
+ q("insert into outq ( outq_hash, outq_account, outq_channel, outq_posturl, outq_async, outq_created, outq_updated, outq_notify, outq_msg ) values ( '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s' )",
+ dbesc($hash),
+ intval($channel['channel_account']),
+ intval($channel['channel_id']),
+ dbesc($hub['hubloc_callback']),
+ intval(1),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ dbesc($n),
+ dbesc(json_encode($info))
+ );
+
+ proc_run('php','include/deliver.php',$hash);
+ if($interval)
+ @time_sleep_until(microtime(true) + (float) $interval);
+ }
+
+
+}
diff --git a/include/taxonomy.php b/include/taxonomy.php
new file mode 100644
index 000000000..7e9a4c856
--- /dev/null
+++ b/include/taxonomy.php
@@ -0,0 +1,159 @@
+<?php /** @file */
+
+// post categories and "save to file" use the same item.file table for storage.
+// We will differentiate the different uses by wrapping categories in angle brackets
+// and save to file categories in square brackets.
+// To do this we need to escape these characters if they appear in our tag.
+
+function file_tag_encode($s) {
+ return str_replace(array('<','>','[',']'),array('%3c','%3e','%5b','%5d'),$s);
+}
+
+function file_tag_decode($s) {
+ return str_replace(array('%3c','%3e','%5b','%5d'),array('<','>','[',']'),$s);
+}
+
+function file_tag_file_query($table,$s,$type = 'file') {
+
+ if($type == 'file')
+ $termtype = TERM_FILE;
+ else
+ $termtype = TERM_CATEGORY;
+
+ return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ",
+ intval($termtype),
+ protect_sprintf(dbesc($s))
+ );
+}
+
+function term_query($table,$s,$type = TERM_UNKNOWN) {
+
+ return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ",
+ intval($type),
+ protect_sprintf(dbesc($s))
+ );
+}
+
+
+function store_item_tag($uid,$iid,$otype,$type,$term,$url = '') {
+ if(! $term)
+ return false;
+ $r = q("select * from term
+ where uid = %d and oid = %d and otype = %d and type = %d
+ and term = '%s' and url = '%s' ",
+ intval($uid),
+ intval($iid),
+ intval($otype),
+ intval($type),
+ dbesc($term),
+ dbesc($url)
+ );
+ if($r)
+ return false;
+ $r = q("insert into term (uid, oid, otype, type, term, url)
+ values( %d, %d, %d, %d, '%s', '%s') ",
+ intval($uid),
+ intval($iid),
+ intval($otype),
+ intval($type),
+ dbesc($term),
+ dbesc($url)
+ );
+ return $r;
+}
+
+function get_terms_oftype($arr,$type) {
+ $ret = array();
+ if(! (is_array($arr) && count($arr)))
+ return $ret;
+
+ if(! is_array($type))
+ $type = array($type);
+
+ foreach($type as $t)
+ foreach($arr as $x)
+ if($x['type'] == $t)
+ $ret[] = $x;
+ return $ret;
+}
+
+function format_term_for_display($term) {
+ $s = '';
+ if($term['type'] == TERM_HASHTAG)
+ $s .= '#';
+ elseif($term['type'] == TERM_MENTION)
+ $s .= '@';
+ else
+ return $s;
+
+ if($term['url'])
+ $s .= '<a href="' . $term['url'] . '">' . htmlspecialchars($term['term']) . '</a>';
+ else
+ $s .= htmlspecialchars($term['term']);
+ return $s;
+}
+
+// Tag cloud functions - need to be adpated to this database format
+
+
+function tagadelic($uid, $count = 0, $type = TERM_HASHTAG) {
+
+ // Fetch tags
+ $r = q("select term, count(term) as total from term
+ where uid = %d and type = %d
+ and otype = %d
+ group by term order by total desc %s",
+ intval($uid),
+ intval($type),
+ intval(TERM_OBJ_POST),
+ ((intval($count)) ? "limit $count" : '')
+ );
+
+ if(! $r)
+ return array();
+
+ // Find minimum and maximum log-count.
+ $tags = array();
+ $min = 1e9;
+ $max = -1e9;
+
+ $x = 0;
+ foreach($r as $rr) {
+ $tags[$x][0] = $rr['term'];
+ $tags[$x][1] = log($rr['total']);
+ $tags[$x][2] = 0;
+ $min = min($min,$tags[$x][1]);
+ $max = max($max,$tags[$x][1]);
+ $x ++;
+ }
+
+ usort($tags,'tags_sort');
+
+ $range = max(.01, $max - $min) * 1.0001;
+
+ for($x = 0; $x < count($tags); $x ++) {
+ $tags[$x][2] = 1 + floor(5 * ($tags[$x][1] - $min) / $range);
+ }
+
+ return $tags;
+}
+
+function tags_sort($a,$b) {
+ if($a[0] == $b[0])
+ return 0;
+ return((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
+}
+
+
+function tagblock($link,$uid,$count = 0,$type = TERM_HASHTAG) {
+ $tab = 0;
+ $r = tagadelic($uid,$count,$type);
+
+ if($r) {
+ echo '<div class="tags" align="center">';
+ foreach($r as $rr) {
+ echo '<a href="'.$link .'/' . '?f=&tag=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ';
+ }
+ echo '</div>';
+ }
+}
diff --git a/include/text.php b/include/text.php
index 71f2257ac..db29697f9 100755
--- a/include/text.php
+++ b/include/text.php
@@ -850,7 +850,6 @@ function smilies($s, $sample = false) {
':like',
':dislike',
'red#',
- '~friendika',
'~friendica'
);
@@ -889,7 +888,6 @@ function smilies($s, $sample = false) {
'<img class="smiley" src="' . $a->get_baseurl() . '/images/like.gif" alt=":like" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/dislike.gif" alt=":dislike" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/rhash-16.png" alt="red#" /></a>',
- '<a href="http://project.friendika.com">~friendika <img class="smiley" src="' . $a->get_baseurl() . '/images/friendika-16.png" alt="~friendika" /></a>',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . $a->get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>'
);
@@ -1025,6 +1023,20 @@ function prepare_body($item,$attach = false) {
$s .= '<div class="clear"></div></div>';
}
+ if(is_array($item['term']) && count($item['term'])) {
+ $tstr = '';
+ foreach($item['term'] as $t) {
+ $t1 = format_term_for_display($t);
+ if($t1) {
+ if($tstr)
+ $tstr .= ' ';
+ $tstr .= $t1;
+ }
+ }
+ if($tstr)
+ $s .= '<br /><div class="posttags">' . $tstr . '</div>';
+ }
+
$writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false);
$x = '';
@@ -1424,278 +1436,28 @@ function reltoabs($text, $base)
}
function item_post_type($item) {
- if(intval($item['event-id']))
- return t('event');
- if(strlen($item['resource_id']))
- return t('photo');
- if(strlen($item['verb']) && $item['verb'] !== ACTIVITY_POST)
- return t('activity');
- if($item['id'] != $item['parent'])
- return t('comment');
- return t('post');
-}
-
-// post categories and "save to file" use the same item.file table for storage.
-// We will differentiate the different uses by wrapping categories in angle brackets
-// and save to file categories in square brackets.
-// To do this we need to escape these characters if they appear in our tag.
-
-function file_tag_encode($s) {
- return str_replace(array('<','>','[',']'),array('%3c','%3e','%5b','%5d'),$s);
-}
-
-function file_tag_decode($s) {
- return str_replace(array('%3c','%3e','%5b','%5d'),array('<','>','[',']'),$s);
-}
-
-function file_tag_file_query($table,$s,$type = 'file') {
-
- if($type == 'file')
- $termtype = TERM_FILE;
- else
- $termtype = TERM_CATEGORY;
-
- return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ",
- intval($termtype),
- protect_sprintf(dbesc($s))
- );
-}
-
-function term_query($table,$s,$type = TERM_UNKNOWN) {
-
- return sprintf(" AND " . (($table) ? dbesc($table) . '.' : '') . "id in (select term.oid from term where term.type = %d and term.term = '%s' and term.uid = " . (($table) ? dbesc($table) . '.' : '') . "uid ) ",
- intval($type),
- protect_sprintf(dbesc($s))
- );
-}
-
-// ex. given music,video return <music><video> or [music][video]
-function file_tag_list_to_file($list,$type = 'file') {
- $tag_list = '';
- if(strlen($list)) {
- $list_array = explode(",",$list);
- if($type == 'file') {
- $lbracket = '[';
- $rbracket = ']';
- }
- else {
- $lbracket = '<';
- $rbracket = '>';
- }
-
- foreach($list_array as $item) {
- if(strlen($item)) {
- $tag_list .= $lbracket . file_tag_encode(trim($item)) . $rbracket;
- }
- }
- }
- return $tag_list;
-}
-
-// ex. given <music><video>[friends], return music,video or friends
-function file_tag_file_to_list($file,$type = 'file') {
- $matches = false;
- $list = '';
- if($type == 'file') {
- $cnt = preg_match_all('/\[(.*?)\]/',$file,$matches,PREG_SET_ORDER);
- }
- else {
- $cnt = preg_match_all('/<(.*?)>/',$file,$matches,PREG_SET_ORDER);
- }
- if($cnt) {
- foreach($matches as $mtch) {
- if(strlen($list))
- $list .= ',';
- $list .= file_tag_decode($mtch[1]);
- }
- }
-
- return $list;
-}
-
-function file_tag_update_pconfig($uid,$file_old,$file_new,$type = 'file') {
- // $file_old - categories previously associated with an item
- // $file_new - new list of categories for an item
-
- if(! intval($uid))
- return false;
-
- if($file_old == $file_new)
- return true;
-
- $saved = get_pconfig($uid,'system','filetags');
- if(strlen($saved)) {
- if($type == 'file') {
- $lbracket = '[';
- $rbracket = ']';
- }
- else {
- $lbracket = '<';
- $rbracket = '>';
- }
-
- $filetags_updated = $saved;
-
- // check for new tags to be added as filetags in pconfig
- $new_tags = array();
- $check_new_tags = explode(",",file_tag_file_to_list($file_new,$type));
-
- foreach($check_new_tags as $tag) {
- if(! stristr($saved,$lbracket . file_tag_encode($tag) . $rbracket))
- $new_tags[] = $tag;
- }
-
- $filetags_updated .= file_tag_list_to_file(implode(",",$new_tags),$type);
-
- // check for deleted tags to be removed from filetags in pconfig
- $deleted_tags = array();
- $check_deleted_tags = explode(",",file_tag_file_to_list($file_old,$type));
-
- foreach($check_deleted_tags as $tag) {
- if(! stristr($file_new,$lbracket . file_tag_encode($tag) . $rbracket))
- $deleted_tags[] = $tag;
- }
-
- foreach($deleted_tags as $key => $tag) {
- $r = q("select file from item where uid = %d " . file_tag_file_query('item',$tag,$type),
- intval($uid)
- );
-
- if(count($r)) {
- unset($deleted_tags[$key]);
- }
- else {
- $filetags_updated = str_replace($lbracket . file_tag_encode($tag) . $rbracket,'',$filetags_updated);
- }
- }
-
- if($saved != $filetags_updated) {
- set_pconfig($uid,'system','filetags', $filetags_updated);
- }
- return true;
- }
- else
- if(strlen($file_new)) {
- set_pconfig($uid,'system','filetags', $file_new);
- }
- return true;
-}
-
-function store_item_tag($uid,$iid,$otype,$type,$term,$url = '') {
- if(! $term)
- return false;
- $r = q("select * from term
- where uid = %d and oid = %d and otype = %d and type = %d
- and term = '%s' and url = '%s' ",
- intval($uid),
- intval($iid),
- intval($otype),
- intval($type),
- dbesc($term),
- dbesc($url)
- );
- if($r)
- return false;
- $r = q("insert into term (uid, oid, otype, type, term, url)
- values( %d, %d, %d, %d, '%s', '%s') ",
- intval($uid),
- intval($iid),
- intval($otype),
- intval($type),
- dbesc($term),
- dbesc($url)
- );
- return $r;
-}
-
-function get_terms_oftype($arr,$type) {
- $ret = array();
- if(! (is_array($arr) && count($arr)))
- return $ret;
-
- if(! is_array($type))
- $type = array($type);
-
- foreach($type as $t)
- foreach($arr as $x)
- if($x['type'] == $t)
- $ret[] = $x;
- return $ret;
-}
-
-function format_term_for_display($term) {
- $s = '';
- if($term['type'] == TERM_HASHTAG)
- $s .= '#';
- elseif($term['type'] == TERM_MENTION)
- $s .= '@';
-
- if($term['url']) $s .= '<a target="extlink" href="' . $term['url'] . '">' . htmlspecialchars($term['term']) . '</a>';
- else $s .= htmlspecialchars($term['term']);
- return $s;
-}
+ switch($item['resource_type']) {
+ case 'photo':
+ $post_type = t('photo');
+ break;
+ case 'event':
+ $post_type = t('event');
+ break;
+ default:
+ $post_type = t('status');
+ if($item['mid'] != $item['parent_mid'])
+ $post_type = t('comment');
+ break;
+ }
-function file_tag_save_file($uid,$item,$file) {
- $result = false;
- if(! intval($uid))
- return false;
+ if(strlen($item['verb']) && (! activity_match($item['verb'],ACTIVITY_POST)))
+ $post_type = t('activity');
- $r = q("select file from item where id = %d and uid = %d limit 1",
- intval($item),
- intval($uid)
- );
- if($r) {
- if(! stristr($r[0]['file'],'[' . file_tag_encode($file) . ']'))
- q("update item set file = '%s' where id = %d and uid = %d limit 1",
- dbesc($r[0]['file'] . '[' . file_tag_encode($file) . ']'),
- intval($item),
- intval($uid)
- );
- $saved = get_pconfig($uid,'system','filetags');
- if((! strlen($saved)) || (! stristr($saved,'[' . file_tag_encode($file) . ']')))
- set_pconfig($uid,'system','filetags',$saved . '[' . file_tag_encode($file) . ']');
- info( t('Item filed') );
- }
- return true;
+ return $post_type;
}
-function file_tag_unsave_file($uid,$item,$file,$cat = false) {
- $result = false;
- if(! intval($uid))
- return false;
-
- if($cat == true)
- $pattern = '<' . file_tag_encode($file) . '>' ;
- else
- $pattern = '[' . file_tag_encode($file) . ']' ;
-
-
- $r = q("select file from item where id = %d and uid = %d limit 1",
- intval($item),
- intval($uid)
- );
- if(! $r)
- return false;
-
- q("update item set file = '%s' where id = %d and uid = %d limit 1",
- dbesc(str_replace($pattern,'',$r[0]['file'])),
- intval($item),
- intval($uid)
- );
-
- $r = q("select file from item where uid = %d and deleted = 0 " . file_tag_file_query('item',$file,(($cat) ? 'category' : 'file')),
- intval($uid)
- );
-
- if(! $r) {
- $saved = get_pconfig($uid,'system','filetags');
- set_pconfig($uid,'system','filetags',str_replace($pattern,'',$saved));
-
- }
- return true;
-}
function normalise_openid($s) {
return trim(str_replace(array('http://','https://'),array('',''),$s),'/');
@@ -1794,7 +1556,7 @@ function ids_to_querystr($arr,$idx = 'id') {
// author_xchan and owner_xchan. If $abook is true also include the abook info.
// This is needed in the API to save extra per item lookups there.
-function xchan_query(&$items,$abook = false) {
+function xchan_query(&$items,$abook = true) {
$arr = array();
if($items && count($items)) {
foreach($items as $item) {
@@ -1806,8 +1568,10 @@ function xchan_query(&$items,$abook = false) {
}
if(count($arr)) {
if($abook) {
- $chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash
- where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )");
+ $chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d
+ where xchan_hash in (" . implode(',', $arr) . ") and ( hubloc_flags & " . intval(HUBLOC_FLAGS_PRIMARY) . " )",
+ intval($item['uid'])
+ );
}
else {
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
@@ -1936,67 +1700,3 @@ function jindent($json) {
}
-// Tag cloud functions - need to be adpated to this database format
-
-
-function tagadelic($uid, $count = 0, $type = TERM_HASHTAG) {
-
- // Fetch tags
- $r = q("select term, count(term) as total from term
- where uid = %d and type = %d
- and otype = %d
- group by term order by total desc %s",
- intval($uid),
- intval($type),
- intval(TERM_OBJ_POST),
- ((intval($count)) ? "limit $count" : '')
- );
-
- if(! $r)
- return array();
-
- // Find minimum and maximum log-count.
- $tags = array();
- $min = 1e9;
- $max = -1e9;
-
- $x = 0;
- foreach($r as $rr) {
- $tags[$x][0] = $rr['term'];
- $tags[$x][1] = log($rr['total']);
- $tags[$x][2] = 0;
- $min = min($min,$tags[$x][1]);
- $max = max($max,$tags[$x][1]);
- $x ++;
- }
-
- usort($tags,'tags_sort');
-
- $range = max(.01, $max - $min) * 1.0001;
-
- for($x = 0; $x < count($tags); $x ++) {
- $tags[$x][2] = 1 + floor(5 * ($tags[$x][1] - $min) / $range);
- }
-
- return $tags;
-}
-
-function tags_sort($a,$b) {
- if($a[0] == $b[0])
- return 0;
- return((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
-}
-
-
-function tagblock($link,$uid,$count = 0,$type = TERM_HASHTAG) {
- $tab = 0;
- $r = tagadelic($uid,$count,$type);
-
- if($r) {
- echo '<div class="tags" align="center">';
- foreach($r as $rr) {
- echo '<a href="'.$link .'/' . '?f=&tag=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ';
- }
- echo '</div>';
- }
-}
diff --git a/include/zot.php b/include/zot.php
index 79031ab26..f10a02d47 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -874,8 +874,16 @@ function zot_import($arr) {
$result = process_profile_delivery($i['notify']['sender'],$arr,$deliveries);
}
+ elseif($i['message']['type'] === 'channel_sync') {
+// $arr = get_channelsync_elements($i['message']);
+ $arr = $i['message'];
+ logger('Channel sync received: ' . print_r($arr,true), LOGGER_DATA);
+ logger('Channel sync recipients: ' . print_r($deliveries,true), LOGGER_DATA);
+
+// $result = process_channelsync_delivery($i['notify']['sender'],$arr,$deliveries);
+ }
}
if($result)
$return = array_merge($return,$result);
@@ -1028,6 +1036,10 @@ function process_delivery($sender,$arr,$deliveries,$relay) {
}
if($arr['item_restrict'] & ITEM_DELETED) {
+
+ // remove_community_tag is a no-op if this isn't a community tag activity
+ remove_community_tag($sender,$arr,$channel['channel_id']);
+
$item_id = delete_imported_item($sender,$arr,$channel['channel_id']);
$result[] = array($d['hash'],'deleted');
@@ -1040,7 +1052,7 @@ function process_delivery($sender,$arr,$deliveries,$relay) {
continue;
}
- // for events, extract the event info and create and event linked to an item
+ // for events, extract the event info and create an event linked to an item
if((x($arr,'obj_type')) && (activity_match($arr['obj_type'],ACTIVITY_OBJ_EVENT))) {
require_once('include/event.php');
@@ -1108,6 +1120,68 @@ function process_delivery($sender,$arr,$deliveries,$relay) {
}
+function remove_community_tag($sender,$arr,$uid) {
+
+ if(! (activity_match($arr['verb'],ACTIVITY_TAG) && ($arr['obj_type'] == ACTIVITY_OBJ_TAGTERM)))
+ return;
+
+ logger('remove_community_tag: invoked');
+
+
+ if(! get_pconfig($uid,'system','blocktags')) {
+ logger('remove_community tag: permission denied.');
+ return;
+ }
+
+ $r = q("select * from item where mid = '%s' and uid = %d limit 1",
+ dbesc($arr['mid']),
+ intval($uid)
+ );
+ if(! $r) {
+ logger('remove_community_tag: no item');
+ return;
+ }
+
+ if(($sender['hash'] != $r[0]['owner_xchan']) && ($sender['hash'] != $r[0]['author_xchan'])) {
+ logger('remove_community_tag: sender not authorised.');
+ return;
+ }
+
+ $i = $r[0];
+
+ if($i['target'])
+ $i['target'] = json_decode($i['target'],true);
+ if($i['object'])
+ $i['object'] = json_decode($i['object'],true);
+
+ if(! ($i['target'] && $i['object'])) {
+ logger('remove_community_tag: no target/object');
+ return;
+ }
+
+ $message_id = $i['target']['id'];
+
+ $r = q("select id from item where mid = '%s' and uid = %d limit 1",
+ dbesc($message_id),
+ intval($uid)
+ );
+ if(! $r) {
+ logger('remove_community_tag: no parent message');
+ return;
+ }
+
+ $x = q("delete from term where uid = %d and oid = %d and otype = %d and type = %d and term = '%s' and url = '%s' limit 1",
+ intval($uid),
+ intval($r[0]['id']),
+ intval(TERM_OBJ_POST),
+ intval(TERM_HASHTAG),
+ dbesc($i['object']['title']),
+ dbesc(get_rel_link($i['object']['link'],'alternate'))
+ );
+
+ return;
+}
+
function update_imported_item($sender,$item,$uid) {
item_store_update($item);
@@ -1217,6 +1291,7 @@ function import_directory_profile($hash,$profile) {
$arr['xprof_hash'] = $hash;
$arr['xprof_desc'] = (($profile['description']) ? htmlentities($profile['description'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_dob'] = datetime_convert('','',$profile['birthday'],'Y-m-d'); // !!!! check this for 0000 year
+ $arr['xprof_age'] = (($profile['age']) ? intval($profile['age']) : 0);
$arr['xprof_gender'] = (($profile['gender']) ? htmlentities($profile['gender'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_marital'] = (($profile['marital']) ? htmlentities($profile['marital'], ENT_COMPAT,'UTF-8',false) : '');
$arr['xprof_sexual'] = (($profile['sexual']) ? htmlentities($profile['sexual'], ENT_COMPAT,'UTF-8',false) : '');