diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 3 | ||||
-rw-r--r-- | include/ItemObject.php | 20 | ||||
-rw-r--r-- | include/bbcode.php | 9 | ||||
-rw-r--r-- | include/cli_startup.php | 1 | ||||
-rw-r--r-- | include/config.php | 290 | ||||
-rw-r--r-- | include/conversation.php | 82 | ||||
-rw-r--r-- | include/directory.php | 16 | ||||
-rw-r--r-- | include/enotify.php | 21 | ||||
-rwxr-xr-x | include/items.php | 116 | ||||
-rw-r--r-- | include/network.php | 20 | ||||
-rw-r--r-- | include/notifier.php | 6 | ||||
-rw-r--r-- | include/poller.php | 3 | ||||
-rw-r--r-- | include/settings.php | 99 | ||||
-rw-r--r-- | include/taxonomy.php | 159 | ||||
-rwxr-xr-x | include/text.php | 370 | ||||
-rw-r--r-- | include/zot.php | 77 |
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) : ''); |