namespace Friendica\Model;
use Friendica\BaseObject;
+use Friendica\Content\Text;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\XML;
use dba;
use Text_LanguageDetect;
require_once 'boot.php';
require_once 'include/items.php';
require_once 'include/text.php';
-require_once 'include/event.php';
class Item extends BaseObject
{
* @param integer $item_id Item ID that should be delete
* @param integer $priority Priority for the notification
*
- * @return $boolean success
+ * @return boolean success
*/
public static function deleteById($item_id, $priority = PRIORITY_HIGH)
{
// If item is a link to an event, delete the event.
if (intval($item['event-id'])) {
- event_delete($item['event-id']);
+ Event::delete($item['event-id']);
}
// If item has attachments, drop them
}
}
+ if (!empty($item['thr-parent'])) {
+ $item['parent-uri'] = $item['thr-parent'];
+ }
+
if (x($item, 'gravity')) {
$item['gravity'] = intval($item['gravity']);
} elseif ($item['parent-uri'] === $item['uri']) {
// The contact-id should be set before "self::insert" was called - but there seems to be issues sometimes
$item["contact-id"] = self::contactId($item);
- $item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"], 0));
+ $item['author-id'] = defaults($item, 'author-id', Contact::getIdForURL($item["author-link"]));
if (Contact::isBlocked($item["author-id"])) {
logger('Contact '.$item["author-id"].' is blocked, item '.$item["uri"].' will not be stored');
return 0;
}
- $item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"], 0));
+ $item['owner-id'] = defaults($item, 'owner-id', Contact::getIdForURL($item["owner-link"]));
if (Contact::isBlocked($item["owner-id"])) {
logger('Contact '.$item["owner-id"].' is blocked, item '.$item["uri"].' will not be stored');
return $current_post;
}
+ /**
+ * @brief Distributes public items to the receivers
+ *
+ * @param integer $itemid Item ID that should be added
+ */
+ public static function distribute($itemid)
+ {
+ $condition = ["`id` IN (SELECT `parent` FROM `item` WHERE `id` = ?)", $itemid];
+ $parent = dba::selectFirst('item', ['owner-id'], $condition);
+ if (!DBM::is_result($parent)) {
+ return;
+ }
+
+ // Only distribute public items from native networks
+ $condition = ['id' => $itemid, 'uid' => 0,
+ 'network' => [NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""],
+ 'visible' => true, 'deleted' => false, 'moderated' => false, 'private' => false];
+ $item = dba::selectFirst('item', [], ['id' => $itemid]);
+ if (!DBM::is_result($item)) {
+ return;
+ }
+
+ unset($item['id']);
+ unset($item['parent']);
+ unset($item['mention']);
+ unset($item['wall']);
+ unset($item['origin']);
+ unset($item['global']);
+ unset($item['starred']);
+ unset($item['rendered-hash']);
+ unset($item['rendered-html']);
+
+ $users = [];
+
+ $condition = ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `id` = ?) AND `uid` != 0 AND NOT `blocked` AND NOT `readonly` AND `rel` IN (?, ?)",
+ $parent['owner-id'], CONTACT_IS_SHARING, CONTACT_IS_FRIEND];
+ $contacts = dba::select('contact', ['uid'], $condition);
+ while ($contact = dba::fetch($contacts)) {
+ $users[$contact['uid']] = $contact['uid'];
+ }
+
+ if ($item['uri'] != $item['parent-uri']) {
+ $parents = dba::select('item', ['uid'], ["`uri` = ? AND `uid` != 0", $item['parent-uri']]);
+ while ($parent = dba::fetch($parents)) {
+ $users[$parent['uid']] = $parent['uid'];
+ }
+ }
+
+ foreach ($users as $uid) {
+ self::storeForUser($itemid, $item, $uid);
+ }
+ }
+
+ /**
+ * @brief Store public items for the receivers
+ *
+ * @param integer $itemid Item ID that should be added
+ * @param array $item The item entry that will be stored
+ * @param integer $uid The user that will receive the item entry
+ */
+ private static function storeForUser($itemid, $item, $uid)
+ {
+ $item['uid'] = $uid;
+ $item['origin'] = 0;
+ $item['wall'] = 0;
+ if ($item['uri'] == $item['parent-uri']) {
+ $item['contact-id'] = Contact::getIdForURL($item['owner-link'], $uid);
+ } else {
+ $item['contact-id'] = Contact::getIdForURL($item['author-link'], $uid);
+ }
+
+ if (empty($item['contact-id'])) {
+ $self = dba::selectFirst('contact', ['id'], ['self' => true, 'uid' => $uid]);
+ if (!DBM::is_result($self)) {
+ return;
+ }
+ $item['contact-id'] = $self['id'];
+ }
+
+ if (in_array($item['type'], ["net-comment", "wall-comment"])) {
+ $item['type'] = 'remote-comment';
+ } elseif ($item['type'] == 'wall') {
+ $item['type'] = 'remote';
+ }
+
+ /// @todo Handling of "event-id"
+
+ $distributed = self::insert($item, false, false, true);
+
+ if (!$distributed) {
+ logger("Distributed public item " . $itemid . " for user " . $uid . " wasn't stored", LOGGER_DEBUG);
+ } else {
+ logger("Distributed public item " . $itemid . " for user " . $uid . " with id " . $distributed, LOGGER_DEBUG);
+ }
+ }
+
/**
* @brief Add a shadow entry for a given item id that is a thread starter
*
*/
public static function addShadow($itemid)
{
- $fields = ['uid', 'wall', 'private', 'moderated', 'visible', 'contact-id', 'deleted', 'network', 'author-id', 'owner-id'];
- $condition = ["`id` = ? AND (`parent` = ? OR `parent` = 0)", $itemid, $itemid];
+ $fields = ['uid', 'private', 'moderated', 'visible', 'deleted', 'network'];
+ $condition = ['id' => $itemid, 'parent' => [0, $itemid]];
$item = dba::selectFirst('item', $fields, $condition);
if (!DBM::is_result($item)) {
return;
}
- // Only do these checks if the post isn't a wall post
- if (!$item["wall"]) {
- // Check, if hide-friends is activated - then don't do a shadow entry
- if (dba::exists('profile', ['is-default' => true, 'uid' => $item['uid'], 'hide-friends' => true])) {
- return;
- }
-
- // Check if the contact is hidden or blocked
- if (!dba::exists('contact', ['hidden' => false, 'blocked' => false, 'id' => $item['contact-id']])) {
- return;
- }
- }
-
- // Only add a shadow, if the profile isn't hidden
- if (dba::exists('user', ['uid' => $item['uid'], 'hidewall' => true])) {
- return;
- }
-
$item = dba::selectFirst('item', [], ['id' => $itemid]);
- if (DBM::is_result($item) && ($item["allow_cid"] == '') && ($item["allow_gid"] == '') &&
+ if (DBM::is_result($item) && ($item["allow_cid"] == '') && ($item["allow_gid"] == '') &&
($item["deny_cid"] == '') && ($item["deny_gid"] == '')) {
if (!dba::exists('item', ['uri' => $item['uri'], 'uid' => 0])) {
$item['uid'] = 0;
$item['origin'] = 0;
$item['wall'] = 0;
- $item['contact-id'] = Contact::getIdForURL($item['author-link'], 0);
+ if ($item['uri'] == $item['parent-uri']) {
+ $item['contact-id'] = Contact::getIdForURL($item['owner-link']);
+ } else {
+ $item['contact-id'] = Contact::getIdForURL($item['author-link']);
+ }
if (in_array($item['type'], ["net-comment", "wall-comment"])) {
$item['type'] = 'remote-comment';
$item['uid'] = 0;
$item['origin'] = 0;
$item['wall'] = 0;
- $item['contact-id'] = Contact::getIdForURL($item['author-link'], 0);
+ $item['contact-id'] = Contact::getIdForURL($item['author-link']);
if (in_array($item['type'], ["net-comment", "wall-comment"])) {
$item['type'] = 'remote-comment';
* if possible and not already present.
* Expects "body" element to exist in $arr.
*/
- private static function addLanguageInPostopts(&$arr)
+ private static function addLanguageInPostopts(&$item)
{
- if (x($arr, 'postopts')) {
- if (strstr($arr['postopts'], 'lang=')) {
+ if (!empty($item['postopts'])) {
+ if (strstr($item['postopts'], 'lang=')) {
// do not override
return;
}
- $postopts = $arr['postopts'];
+ $postopts = $item['postopts'];
} else {
$postopts = "";
}
- $naked_body = preg_replace('/\[(.+?)\]/','', $arr['body']);
- $l = new Text_LanguageDetect();
- $lng = $l->detect($naked_body, 3);
+ $naked_body = Text\BBCode::toPlaintext($item['body'], false);
- if (sizeof($lng) > 0) {
- if ($postopts != "") {
+ $languages = (new Text_LanguageDetect())->detect($naked_body, 3);
+
+ if (sizeof($languages) > 0) {
+ if ($postopts != '') {
$postopts .= '&'; // arbitrary separator, to be reviewed
}
$postopts .= 'lang=';
$sep = "";
- foreach ($lng as $language => $score) {
+ foreach ($languages as $language => $score) {
$postopts .= $sep . $language . ";" . $score;
$sep = ':';
}
- $arr['postopts'] = $postopts;
+ $item['postopts'] = $postopts;
}
}
}
// now change this copy of the post to a forum head message and deliver to all the tgroup members
- $self = dba::selectFirst('contact', ['name', 'url', 'thumb'], ['uid' => $uid, 'self' => true]);
+ $self = dba::selectFirst('contact', ['id', 'name', 'url', 'thumb'], ['uid' => $uid, 'self' => true]);
if (!DBM::is_result($self)) {
return;
}
+ $owner_id = Contact::getIdForURL($self['url']);
+
// also reset all the privacy bits to the forum default permissions
$private = ($user['allow_cid'] || $user['allow_gid'] || $user['deny_cid'] || $user['deny_gid']) ? 1 : 0;
$forum_mode = ($prvgroup ? 2 : 1);
- $fields = ['wall' => true, 'origin' => true, 'forum_mode' => $forum_mode,
- 'owner-name' => $self['name'], 'owner-link' => $self['url'], 'owner-avatar' => $self['thumb'],
- 'private' => $private, 'allow_cid' => $user['allow_cid'], 'allow_gid' => $user['allow_gid'],
- 'deny_cid' => $user['deny_cid'], 'deny_gid' => $user['deny_gid']];
+ $fields = ['wall' => true, 'origin' => true, 'forum_mode' => $forum_mode, 'contact-id' => $self['id'],
+ 'owner-id' => $owner_id, 'owner-name' => $self['name'], 'owner-link' => $self['url'],
+ 'owner-avatar' => $self['thumb'], 'private' => $private, 'allow_cid' => $user['allow_cid'],
+ 'allow_gid' => $user['allow_gid'], 'deny_cid' => $user['deny_cid'], 'deny_gid' => $user['deny_gid']];
dba::update('item', $fields, ['id' => $item_id]);
self::updateThread($item_id);
$item_contact_id = $owner_self_contact['id'];
$item_contact = $owner_self_contact;
} else {
- $item_contact_id = Contact::getIdForURL($author_contact['url'], $uid);
+ $item_contact_id = Contact::getIdForURL($author_contact['url'], $uid, true);
$item_contact = dba::selectFirst('contact', [], ['id' => $item_contact_id]);
if (!DBM::is_result($item_contact)) {
logger('like: unknown item contact ' . $item_contact_id);