aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php3
-rw-r--r--include/ConversationObject.php33
-rw-r--r--include/ItemObject.php139
-rw-r--r--include/bbcode.php9
-rw-r--r--include/cli_startup.php1
-rw-r--r--include/config.php314
-rw-r--r--include/contact_selectors.php16
-rw-r--r--include/conversation.php101
-rw-r--r--include/deliver.php13
-rw-r--r--include/dir_fns.php5
-rw-r--r--include/directory.php21
-rw-r--r--include/enotify.php21
-rw-r--r--include/features.php1
-rwxr-xr-xinclude/items.php172
-rw-r--r--include/network.php20
-rw-r--r--include/notifier.php69
-rw-r--r--include/permissions.php16
-rw-r--r--include/poller.php3
-rw-r--r--include/profile_advanced.php35
-rw-r--r--include/settings.php99
-rw-r--r--include/taxonomy.php208
-rwxr-xr-xinclude/text.php375
-rw-r--r--include/zot.php87
23 files changed, 1061 insertions, 700 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/ConversationObject.php b/include/ConversationObject.php
index 7cf39f757..3f5e901d3 100644
--- a/include/ConversationObject.php
+++ b/include/ConversationObject.php
@@ -11,12 +11,14 @@ require_once('include/text.php');
/**
* A list of threads
*
- * We should think about making this a SPL Iterator
*/
+
class Conversation extends BaseObject {
private $threads = array();
private $mode = null;
+ private $observer = null;
private $writable = false;
+ private $commentable = false;
private $profile_owner = 0;
private $preview = false;
@@ -34,8 +36,8 @@ class Conversation extends BaseObject {
$a = $this->get_app();
- $observer = $a->get_observer();
- $ob_hash = (($observer) ? $observer['xchan_hash'] : '');
+ $this->observer = $a->get_observer();
+ $ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
switch($mode) {
case 'network':
@@ -63,7 +65,6 @@ class Conversation extends BaseObject {
break;
}
$this->mode = $mode;
-
}
/**
@@ -80,6 +81,10 @@ class Conversation extends BaseObject {
return $this->writable;
}
+ public function is_commentable() {
+ return $this->commentable;
+ }
+
/**
* Check if page is a preview
*/
@@ -101,6 +106,10 @@ class Conversation extends BaseObject {
$this->set_mode($mode);
}
+ public function get_observer() {
+ return $this->observer;
+ }
+
/**
* Add a thread to the conversation
@@ -121,12 +130,24 @@ class Conversation extends BaseObject {
}
/*
- * Only add will be displayed
+ * Only add things that will be displayed
*/
- if(activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE)) {
+
+ if(($item->get_data_value('id') != $item->get_data_value('parent')) && (activity_match($item->get_data_value('verb'),ACTIVITY_LIKE) || activity_match($item->get_data_value('verb'),ACTIVITY_DISLIKE))) {
return false;
}
+
+ if(local_user() && $item->get_data_value('uid') == local_user())
+ $this->commentable = true;
+
+ if($this->writable)
+ $this->commentable = true;
+
+ if(($this->observer) && (! $this->writable)) {
+ $this->commentable = can_comment_on_post($this->observer['xchan_hash'],$item->data);
+ }
+
$item->set_conversation($this);
$this->threads[] = $item;
return end($this->threads);
diff --git a/include/ItemObject.php b/include/ItemObject.php
index ccd192ff5..7a9e43819 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -11,12 +11,10 @@ require_once('boot.php');
* An item
*/
class Item extends BaseObject {
- private $data = array();
+ public $data = array();
private $template = 'conv_item.tpl';
private $comment_box_template = 'comment_item.tpl';
private $toplevel = false;
- private $writable = false;
- private $commentable = false;
private $children = array();
private $parent = null;
private $conversation = null;
@@ -27,31 +25,15 @@ class Item extends BaseObject {
private $wall_to_wall = false;
private $threaded = false;
private $visiting = false;
- private $observer = null;
private $channel = null;
public function __construct($data) {
$a = $this->get_app();
$this->data = $data;
- $this->channel = $a->get_channel();
- $this->observer = $a->get_observer();
-
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
- $this->writable = (((local_user()) && ($this->channel['channel_hash'] === $this->data['owner_xchan'])) ? true : false);
- $this->commentable = $this->writable;
-
- if(($this->observer) && (! $this->writable)) {
- $this->commentable = perm_is_allowed($this->data['uid'],$this->observer['xchan_hash'],'post_comments');
- }
-
-// 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) {
@@ -85,7 +67,6 @@ class Item extends BaseObject {
$result = array();
$a = $this->get_app();
- $observer = $this->observer;
$item = $this->get_data();
$commentww = '';
@@ -99,6 +80,7 @@ class Item extends BaseObject {
$total_children = $this->count_descendants();
$conv = $this->get_conversation();
+ $observer = $conv->get_observer();
$lock = ((($item['item_private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
@@ -111,10 +93,9 @@ class Item extends BaseObject {
else
$edpost = false;
-// FIXME - this is wrong.
-// if(($this->get_data_value('uid') == local_user()) || $this->is_visiting())
-
- if($this->get_data_value('uid') == local_user())
+ if($observer['xchan_hash'] == $this->get_data_value('author_xchan')
+ || $observer['xchan_hash'] == $this->get_data_value('owner_xchan')
+ || $this->get_data_value('uid') == local_user())
$dropping = true;
if($dropping) {
@@ -123,7 +104,7 @@ class Item extends BaseObject {
'delete' => t('Delete'),
);
}
-
+// FIXME
if($observer_is_pageowner) {
$multidrop = array(
'select' => t('Select'),
@@ -152,6 +133,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,16 +148,20 @@ class Item extends BaseObject {
'starred' => t('starred'),
);
- $tagger = array(
- 'tagit' => t("add tag"),
- 'classtagger' => "",
- );
}
} else {
$indent = 'comment';
}
- if($this->is_commentable()) {
+ // FIXME - check this permission
+ if($conv->get_profile_owner() == local_user()) {
+ $tagger = array(
+ 'tagit' => t("add tag"),
+ 'classtagger' => "",
+ );
+ }
+
+ if($conv->is_commentable()) {
$like = array( t("I like this \x28toggle\x29"), t("like"));
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
if ($shareable)
@@ -456,28 +442,6 @@ class Item extends BaseObject {
}
/**
- * Check if this is writable
- */
- private function is_writable() {
-
- return $this->writable;
-
-// $conv = $this->get_conversation();
-
-// return true;
-
-// if($conv) {
- // This will allow us to comment on wall-to-wall items owned by our friends
- // and community forums even if somebody else wrote the post.
-// return ($this->writable || ($this->is_visiting() && $conv->get_mode() == 'channel'));
-// }
- }
-
- private function is_commentable() {
- return $this->commentable;
- }
-
- /**
* Count the total of our descendants
*/
private function count_descendants() {
@@ -514,44 +478,43 @@ class Item extends BaseObject {
$comment_box = '';
$conv = $this->get_conversation();
- if(! $this->is_commentable())
+ if(! $conv->is_commentable())
return;
- if($conv->is_writable() || $this->is_writable()) {
- $template = get_markup_template($this->get_comment_box_template());
-
- $a = $this->get_app();
-
- $qc = ((local_user()) ? get_pconfig(local_user(),'system','qcomment') : null);
- $qcomment = (($qc) ? explode("\n",$qc) : null);
-
- $comment_box = replace_macros($template,array(
- '$return_path' => '',
- '$threaded' => $this->is_threaded(),
- '$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
- '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
- '$id' => $this->get_id(),
- '$parent' => $this->get_id(),
- '$qcomment' => $qcomment,
- '$profile_uid' => $conv->get_profile_owner(),
- '$mylink' => $this->observer['xchan_url'],
- '$mytitle' => t('This is you'),
- '$myphoto' => $this->observer['xchan_photo_s'],
- '$comment' => t('Comment'),
- '$submit' => t('Submit'),
- '$edbold' => t('Bold'),
- '$editalic' => t('Italic'),
- '$eduline' => t('Underline'),
- '$edquote' => t('Quote'),
- '$edcode' => t('Code'),
- '$edimg' => t('Image'),
- '$edurl' => t('Link'),
- '$edvideo' => t('Video'),
- '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
- '$indent' => $indent,
- '$sourceapp' => get_app()->sourcename
- ));
- }
+ $template = get_markup_template($this->get_comment_box_template());
+
+ $a = $this->get_app();
+ $observer = $conv->get_observer();
+
+ $qc = ((local_user()) ? get_pconfig(local_user(),'system','qcomment') : null);
+ $qcomment = (($qc) ? explode("\n",$qc) : null);
+
+ $comment_box = replace_macros($template,array(
+ '$return_path' => '',
+ '$threaded' => $this->is_threaded(),
+ '$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
+ '$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
+ '$id' => $this->get_id(),
+ '$parent' => $this->get_id(),
+ '$qcomment' => $qcomment,
+ '$profile_uid' => $conv->get_profile_owner(),
+ '$mylink' => $observer['xchan_url'],
+ '$mytitle' => t('This is you'),
+ '$myphoto' => $observer['xchan_photo_s'],
+ '$comment' => t('Comment'),
+ '$submit' => t('Submit'),
+ '$edbold' => t('Bold'),
+ '$editalic' => t('Italic'),
+ '$eduline' => t('Underline'),
+ '$edquote' => t('Quote'),
+ '$edcode' => t('Code'),
+ '$edimg' => t('Image'),
+ '$edurl' => t('Link'),
+ '$edvideo' => t('Video'),
+ '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''),
+ '$indent' => $indent,
+ '$sourceapp' => get_app()->sourcename
+ ));
return $comment_box;
}
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 5db0a3d05..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,21 +122,40 @@ function del_config($family,$key) {
}
-function load_pconfig($uid,$family) {
+function load_pconfig($uid,$family = '') {
global $a;
- $r = q("SELECT * FROM `pconfig` WHERE `cat` = '%s' AND `uid` = %d",
- dbesc($family),
- intval($uid)
- );
- if(count($r)) {
+
+ 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",
+ dbesc($family),
+ intval($uid)
+ );
+ }
+ else {
+ $r = q("SELECT * FROM `pconfig` WHERE `uid` = %d",
+ intval($uid)
+ );
+ }
+
+ if($r) {
foreach($r as $rr) {
$k = $rr['k'];
- $a->config[$uid][$family][$k] = $rr['v'];
+ $c = $rr['cat'];
+ 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>!";
- }
+ }
}
@@ -151,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;
@@ -231,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)
@@ -241,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;
}
@@ -304,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),
@@ -330,6 +357,7 @@ function set_xconfig($xchan,$family,$key,$value) {
if($ret)
return $value;
return $ret;
+
}
diff --git a/include/contact_selectors.php b/include/contact_selectors.php
index adcca2c52..b56a77937 100644
--- a/include/contact_selectors.php
+++ b/include/contact_selectors.php
@@ -1,21 +1,19 @@
<?php /** @file */
-function contact_profile_assign($current,$foreign_net) {
+function contact_profile_assign($current) {
$o = '';
- $disabled = (($foreign_net) ? ' disabled="true" ' : '');
+ $o .= "<select id=\"contact-profile-selector\" name=\"profile-assign\" />\r\n";
- $o .= "<select id=\"contact-profile-selector\" $disabled name=\"profile-assign\" />\r\n";
+ $r = q("SELECT profile_guid, profile_name FROM `profile` WHERE `uid` = %d",
+ intval($_SESSION['uid']));
- $r = q("SELECT `id`, `profile_name` FROM `profile` WHERE `uid` = %d",
- intval($_SESSION['uid']));
-
- if(count($r)) {
+ if($r) {
foreach($r as $rr) {
- $selected = (($rr['id'] == $current) ? " selected=\"selected\" " : "");
- $o .= "<option value=\"{$rr['id']}\" $selected >{$rr['profile_name']}</option>\r\n";
+ $selected = (($rr['profile_guid'] == $current) ? " selected=\"selected\" " : "");
+ $o .= "<option value=\"{$rr['profile_guid']}\" $selected >{$rr['profile_name']}</option>\r\n";
}
}
$o .= "</select>\r\n";
diff --git a/include/conversation.php b/include/conversation.php
index 13f67c4dd..1023c068d 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;
}
@@ -365,7 +393,7 @@ function visible_activity($item) {
*
*/
-if(!function_exists('conversation')) {
+
function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
$tstart = dba_timer();
@@ -374,6 +402,8 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
$ssl_state = ((local_user()) ? true : false);
+ if(local_user())
+ load_pconfig(local_user(),'');
$arr_blocked = null;
@@ -554,17 +584,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
$tags=array();
$hashtags = array();
$mentions = array();
- foreach(explode(',',$item['tag']) as $tag){
- $tag = trim($tag);
- if ($tag!="") {
- $t = bbcode($tag);
- $tags[] = $t;
- if($t[0] == '#')
- $hashtags[] = $t;
- elseif($t[0] == '@')
- $mentions[] = $t;
- }
- }
$sp = false;
$profile_link = best_link_url($item,$sp);
@@ -620,7 +639,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
$tmp_item = array(
'template' => $tpl,
'toplevel' => 'toplevel_item',
- 'tags' => $tags,
'id' => (($preview) ? 'P0' : $item['item_id']),
'linktitle' => sprintf( t('View %s\'s profile @ %s'), $profile_name, $profile_url),
'profile_url' => $profile_link,
@@ -678,6 +696,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
}
else
{
+
// Normal View
// logger('conv: items: ' . print_r($items,true));
@@ -790,7 +809,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional') {
return $o;
-}}
+}
function best_link_url($item) {
@@ -823,7 +842,7 @@ function best_link_url($item) {
}
-if(! function_exists('item_photo_menu')){
+
function item_photo_menu($item){
$a = get_app();
$contact = null;
@@ -890,9 +909,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 = '';
@@ -920,7 +939,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
@@ -929,7 +948,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)
@@ -953,7 +972,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/deliver.php b/include/deliver.php
index c5ed35c87..547d009cc 100644
--- a/include/deliver.php
+++ b/include/deliver.php
@@ -23,11 +23,14 @@ function deliver_run($argv, $argc) {
if($r[0]['outq_posturl'] === z_root() . '/post') {
// local delivery
// we should probably batch these and save a few delivery processes
- $msg = array('body' => json_encode(array('pickup' => array(array('notify' => json_decode($r[0]['outq_notify'],true),'message' => json_decode($r[0]['outq_msg'],true))))));
- zot_import($msg);
- $r = q("delete from outq where outq_hash = '%s' limit 1",
- dbesc($argv[$x])
- );
+ // If there is no outq_msg, this is a refresh_all message which does not require local handling
+ if($r[0]['outq_msg']) {
+ $msg = array('body' => json_encode(array('pickup' => array(array('notify' => json_decode($r[0]['outq_notify'],true),'message' => json_decode($r[0]['outq_msg'],true))))));
+ zot_import($msg);
+ $r = q("delete from outq where outq_hash = '%s' limit 1",
+ dbesc($argv[$x])
+ );
+ }
}
else {
$result = zot_zot($r[0]['outq_posturl'],$r[0]['outq_notify']);
diff --git a/include/dir_fns.php b/include/dir_fns.php
index 5a1d671cb..0b678fd91 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -53,7 +53,7 @@ function syncdirs($uid) {
logger('syncdirs', LOGGER_DEBUG);
- $p = q("select channel.channel_hash, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
+ $p = q("select channel.channel_hash, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1",
intval($uid)
);
@@ -64,6 +64,9 @@ function syncdirs($uid) {
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
+ if($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
+ $profile['age'] = $age;
+
$profile['gender'] = $p[0]['gender'];
$profile['marital'] = $p[0]['marital'];
$profile['sexual'] = $p[0]['sexual'];
diff --git a/include/directory.php b/include/directory.php
index 5f24b4af8..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) {
@@ -41,11 +45,16 @@ function directory_run($argv, $argc){
$url = DIRECTORY_FALLBACK_MASTER . '/post';
}
+ // ensure the upstream directory is updated
+
$packet = zot_build_packet($channel,'refresh');
$z = zot_zot($url,$packet);
-
// re-queue if unsuccessful
+ // Now update all the connections
+
+ proc_run('php','include/notifier.php','refresh_all',$channel['channel_id']);
+
}
if (array_search(__file__,get_included_files())===0){
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/features.php b/include/features.php
index c2aabbc42..da1322a14 100644
--- a/include/features.php
+++ b/include/features.php
@@ -58,6 +58,7 @@ function get_features() {
array('filing', t('Saved Folders'), t('Ability to file posts under folders')),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments')),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator')),
+ array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your channel page')),
),
);
diff --git a/include/items.php b/include/items.php
index 5489fa9e8..898fc9ff8 100755
--- a/include/items.php
+++ b/include/items.php
@@ -49,10 +49,46 @@ function collect_recipients($item,&$private) {
$recipients = check_list_permissions($item['uid'],$recipients,'view_stream');
+ // add ourself just in case we have nomadic clones that need to get a copy.
+
+ $recipients[] = $item['author_xchan'];
+ if($item['owner_xchan'] != $item['author_xchan'])
+ $recipients[] = $item['owner_xchan'];
return $recipients;
}
+
+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 +178,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 +518,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 +583,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 +639,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 +865,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 +1371,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
@@ -1808,30 +1863,73 @@ function tag_deliver($uid,$item_id) {
// See if we are the owner of the parent item and have given permission to tag our posts.
// If so tag the parent post.
- // 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']);
@@ -1931,45 +2029,51 @@ function tgroup_check($uid,$item) {
// check that the message originated elsewhere and is a top-level post
- if(($item['wall']) || ($item['origin']) || ($item['mid'] != $item['parent-mid']))
+ if($arr['mid'] != $arr['parent_mid'])
return false;
+ if(! perm_is_allowed($uid,$item['author_xchan'],'tag_deliver'))
+ return false;
- $u = q("select * from user where uid = %d limit 1",
+ $u = q("select * from channel where channel_id = %d limit 1",
intval($uid)
);
- if(! count($u))
- return false;
-
- $community_page = (($u[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
- $prvgroup = (($u[0]['page-flags'] == PAGE_PRVGROUP) ? true : false);
+ if(! $u)
+ return false;
- $link = normalise_link($a->get_baseurl() . '/channel/' . $u[0]['nickname']);
+ $terms = get_terms_oftype($item['term'],TERM_MENTION);
- // Diaspora uses their own hardwired link URL in @-tags
- // instead of the one we supply with webfinger
+ logger('tgroup_check: post mentions: ' . print_r($terms,true), LOGGER_DATA);
- $dlink = normalise_link($a->get_baseurl() . '/u/' . $u[0]['nickname']);
+ $link = normalise_link($a->get_baseurl() . '/channel/' . $u[0]['channel_address']);
- $body = preg_replace("/\[share\](.*?)\[\/share\]/ism", '', $item['body']);
-
- $cnt = preg_match_all('/[\@\!]\[zrl\=(.*?)\](.*?)\[\/zrl\]/ism',$body,$matches,PREG_SET_ORDER);
- if($cnt) {
- foreach($matches as $mtch) {
- if(link_compare($link,$mtch[1]) || link_compare($dlink,$mtch[1])) {
+ if($terms) {
+ foreach($terms as $term) {
+ if(($term['term'] == $u[0]['channel_name']) && link_compare($term['url'],$link)) {
$mention = true;
- logger('tgroup_check: mention found: ' . $mtch[2]);
+ break;
}
}
- }
+ }
- if(! $mention)
+ if($mention) {
+ logger('tgroup_check: mention found for ' . $u[0]['channel_name']);
+ }
+ else
return false;
- if((! $community_page) && (! $prvgroup))
- return false;
+ // At this point we've determined that the person receiving this post was mentioned in it.
+ // Now let's check if this mention was inside a reshare so we don't spam a forum
+
+ $body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']);
+
+ $pattern = '/@\[zrl\=' . preg_quote($term['url'],'/') . '\]' . preg_quote($u[0]['channel_name'],'/') . '\[\/zrl\]/';
+ if(! preg_match($pattern,$body,$matches)) {
+ logger('tgroup_check: mention was in a reshare - ignoring');
+ return false;
+ }
return true;
@@ -4684,7 +4788,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 159931124..96c0bf31f 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -53,6 +53,7 @@ require_once('include/html2plain.php');
*
* ZOT
* permission_update abook_id
+ * refresh_all channel_id
* relay item_id (item was relayed to owner, we will deliver it as owner)
*
*/
@@ -136,6 +137,7 @@ function notifier_run($argv, $argc){
$recipients = array();
$url_recipients = array();
$normal_mode = true;
+ $packet_type = 'undefined';
if($cmd === 'mail') {
$normal_mode = false;
@@ -186,6 +188,27 @@ function notifier_run($argv, $argc){
$recipients[] = $suggest[0]['cid'];
$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)
+ );
+ if($s)
+ $channel = $s[0];
+ $uid = $item_id;
+ $recipients = array();
+ $r = q("select * from abook where abook_channel = %d and not (abook_flags & %d)",
+ intval($item_id),
+ intval(ABOOK_FLAG_SELF)
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $recipients[] = $rr['abook_xchan'];
+ }
+ }
+ $private = false;
+ $packet_type = 'refresh';
+ }
else {
// Normal items
@@ -213,6 +236,12 @@ function notifier_run($argv, $argc){
return;
}
+ if($target_item['item_restrict'] & ITEM_WEBPAGE) {
+ logger('notifier: target item ITEM_WEBPAGE', LOGGER_DEBUG);
+ return;
+ }
+
+
$s = q("select * from channel where channel_id = %d limit 1",
intval($target_item['uid'])
);
@@ -346,18 +375,34 @@ function notifier_run($argv, $argc){
foreach($hubs as $hub) {
$hash = random_string();
- $n = zot_build_packet($channel,'notify',$env_recips,(($private) ? $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($target_item['aid']),
- intval($target_item['uid']),
- dbesc($hub['hubloc_callback']),
- intval(1),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc($n),
- dbesc(json_encode($encoded_item))
- );
+ if($packet_type === 'refresh') {
+ $n = zot_build_packet($channel,'refresh');
+ 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('')
+ );
+ }
+ else {
+ $n = zot_build_packet($channel,'notify',$env_recips,(($private) ? $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($target_item['aid']),
+ intval($target_item['uid']),
+ dbesc($hub['hubloc_callback']),
+ intval(1),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ dbesc($n),
+ dbesc(json_encode($encoded_item))
+ );
+ }
$deliver[] = $hash;
if(count($deliver) >= $deliveries_per_process) {
diff --git a/include/permissions.php b/include/permissions.php
index 071a599f8..bf380cf95 100644
--- a/include/permissions.php
+++ b/include/permissions.php
@@ -98,7 +98,7 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) {
// If they're blocked - they can't read or write
- if(($x) && (($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED) || ($x[0]['abook_flags'] & ABOOK_FLAG_PENDING))) {
+ if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) {
$ret[$perm_name] = false;
continue;
}
@@ -164,13 +164,17 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) {
// If PERMS_CONTACTS or PERMS_SPECIFIC, they need to be in your address book
// $x is a valid address book entry
-
-
if(! $x) {
$ret[$perm_name] = false;
continue;
}
+ // They are in your address book, but haven't been approved
+
+ if($x[0]['abook_flags'] & ABOOK_FLAG_PENDING) {
+ $ret[$perm_name] = false;
+ continue;
+ }
if(($r) && ($r[0][$channel_perm] & PERMS_CONTACTS)) {
@@ -242,7 +246,7 @@ function perm_is_allowed($uid,$observer_xchan,$permission) {
// If they're blocked - they can't read or write
- if(($x) && (($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED) || ($x[0]['abook_flags'] & ABOOK_FLAG_PENDING)))
+ if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED))
return false;
if(($x) && (! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED))
@@ -287,6 +291,10 @@ function perm_is_allowed($uid,$observer_xchan,$permission) {
return false;
}
+ if($x[0]['abook_flags'] & ABOOK_FLAG_PENDING) {
+ return false;
+ }
+
if($r[0][$channel_perm] & PERMS_CONTACTS) {
return true;
}
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/profile_advanced.php b/include/profile_advanced.php
index f008d1c8f..21606185d 100644
--- a/include/profile_advanced.php
+++ b/include/profile_advanced.php
@@ -80,9 +80,44 @@ function advanced_profile(&$a) {
if($txt = prepare_text($a->profile['education'])) $profile['education'] = array( t('School/education:'), $txt );
+ $r = q("select * from obj left join term on obj_obj = term_hash where term_hash != '' and obj_page = '%s' and uid = %d and obj_type = %d
+ order by obj_verb, term",
+ dbesc($a->profile['profile_guid']),
+ intval($a->profile['profile_uid']),
+ intval(TERM_OBJ_THING)
+ );
+
+ $things = null;
+
+ if($r) {
+ $things = array();
+
+ // Use the system obj_verbs array as a sort key, since we don't really
+ // want an alphabetic sort. To change the order, use a plugin to
+ // alter the obj_verbs() array or alter it in code. Unknown verbs come
+ // after the known ones - in no particular order.
+
+ $v = obj_verbs();
+ foreach($v as $k => $foo)
+ $things[$k] = null;
+ foreach($r as $rr) {
+ if(! $things[$rr['obj_verb']])
+ $things[$rr['obj_verb']] = array();
+ $things[$rr['obj_verb']][] = array('term' => $rr['term'],'url' => $rr['url'],'img' => $rr['imgurl']);
+ }
+ $sorted_things = array();
+ if($things)
+ foreach($things as $k => $v)
+ if(is_array($things[$k]))
+ $sorted_things[$k] = $v;
+ }
+
+ logger('mod_profile: things: ' . print_r($sorted_things,true), LOGGER_DATA);
+
return replace_macros($tpl, array(
'$title' => t('Profile'),
'$profile' => $profile,
+ '$things' => $sorted_things
));
}
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..b6803743a
--- /dev/null
+++ b/include/taxonomy.php
@@ -0,0 +1,208 @@
+<?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, $authors = '', $flags = 0, $type = TERM_HASHTAG) {
+
+ $sql_options = '';
+
+ if($flags)
+ $sql_options .= " and ((item_flags & " . intval($flags) . ") = " . intval($flags) . ") ";
+ if($authors) {
+ if(! is_array($authors))
+ $authors = array($authors);
+ stringify_array_elms($authors,true);
+ $sql_options .= " and author_xchan in (" . implode(',',$authors) . ") ";
+ }
+
+ // Fetch tags
+ $r = q("select term, count(term) as total from term left join item on term.oid = item.id
+ where term.uid = %d and term.type = %d
+ and otype = %d and item_restrict = 0 and item_private = 0
+ $sql_options
+ 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,$authors = '',$flags = 0,$type = TERM_HASHTAG) {
+ $o = '';
+ $tab = 0;
+ $r = tagadelic($uid,$count,$authors,$flags,$type);
+
+ if($r) {
+ $o = '<div class="tagblock widget"><h3>' . t('Tags') . '</h3><div class="tags" align="center">';
+ foreach($r as $rr) {
+ $o .= '<a href="'.$link .'/' . '?f=&tag=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ' . "\r\n";
+ }
+ $o .= '</div></div>';
+ }
+ return $o;
+}
+
+
+ /**
+ * verbs: [0] = first person singular, e.g. "I want", [1] = 3rd person singular, e.g. "Bill wants"
+ * We use the first person form when creating an activity, but the third person for use in activities
+ * FIXME: There is no accounting for verb gender for languages where this is significant. We may eventually
+ * require obj_verbs() to provide full conjugations and specify which form to use in the $_REQUEST params to this module.
+ */
+
+
+
+function obj_verbs() {
+ $verbs = array(
+ 'has' => array( t('have'), t('has')),
+ 'wants' => array( t('want'), t('wants')),
+ 'likes' => array( t('like'), t('likes')),
+ 'dislikes' => array( t('dislike'), t('dislikes')),
+ );
+
+ $arr = array('verbs' => $verbs);
+ call_hooks('obj_verbs', $arr);
+ return $arr['verbs'];
+}
+
+
+function obj_verb_selector() {
+ $verbs = obj_verbs();
+ $o .= '<select class="obj-verb-selector" name="verb" >';
+ foreach($verbs as $k => $v) {
+ $o .= '<option value="' . urlencode($k) . '">' . $v[0] . '</option>';
+ }
+ $o .= '</select>';
+ return $o;
+
+} \ No newline at end of file
diff --git a/include/text.php b/include/text.php
index 71f2257ac..2d29dff31 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,25 @@ function prepare_body($item,$attach = false) {
$s .= '<div class="clear"></div></div>';
}
+// At some point in time, posttags were removed from the threaded conversation templates, but remained in the search_item template.
+// Code to put them back was added into include/conversation.php and/or include/ItemObject.php but under new class names
+// Then it was discovered that the following bits remained of the old code.
+// Commented out, but we may decide to use this instead of the other version and put all the tag rendering in one place. In the other
+// location it is more theme-able.
+// 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 +1441,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 +1561,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 +1573,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 +1705,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 2eb3b5eb0..6c8a21d1a 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);
@@ -1017,15 +1025,21 @@ function process_delivery($sender,$arr,$deliveries,$relay) {
$channel = $r[0];
+ $tag_delivery = tgroup_check($channel['channel_id'],$arr);
+
$perm = (($arr['mid'] == $arr['parent_mid']) ? 'send_stream' : 'post_comments');
- if(! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) {
+ if((! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) && (! $tag_delivery)) {
logger("permission denied for delivery {$channel['channel_id']}");
$result[] = array($d['hash'],'permission denied');
continue;
}
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');
@@ -1038,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');
@@ -1106,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);
@@ -1215,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) : '');
@@ -1235,7 +1312,6 @@ function import_directory_profile($hash,$profile) {
$arr['xprof_keywords'] = implode(' ',$clean);
-
$r = q("select * from xprof where xprof_hash = '%s' limit 1",
dbesc($hash)
);
@@ -1251,6 +1327,7 @@ function import_directory_profile($hash,$profile) {
$x = q("update xprof set
xprof_desc = '%s',
xprof_dob = '%s',
+ xprof_age = %d,
xprof_gender = '%s',
xprof_marital = '%s',
xprof_sexual = '%s',
@@ -1262,6 +1339,7 @@ function import_directory_profile($hash,$profile) {
where xprof_hash = '%s' limit 1",
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
+ intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),
@@ -1276,10 +1354,11 @@ function import_directory_profile($hash,$profile) {
}
else {
$update = true;
- $x = q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_keywords) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
+ $x = q("insert into xprof (xprof_hash, xprof_desc, xprof_dob, xprof_age, xprof_gender, xprof_marital, xprof_sexual, xprof_locale, xprof_region, xprof_postcode, xprof_country, xprof_keywords) values ('%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($arr['xprof_hash']),
dbesc($arr['xprof_desc']),
dbesc($arr['xprof_dob']),
+ intval($arr['xprof_age']),
dbesc($arr['xprof_gender']),
dbesc($arr['xprof_marital']),
dbesc($arr['xprof_sexual']),