define('FRIENDICA_CODENAME', 'Asparagus');
define('FRIENDICA_VERSION', '3.6-dev');
define('DFRN_PROTOCOL_VERSION', '2.23');
-define('DB_UPDATE_VERSION', 1248);
+define('DB_UPDATE_VERSION', 1249);
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
/**
--
CREATE TABLE IF NOT EXISTS `workerqueue` (
`id` int NOT NULL auto_increment COMMENT 'Auto incremented worker task id',
- `parameter` text COMMENT 'Task command',
+ `parameter` mediumtext COMMENT 'Task command',
`priority` tinyint NOT NULL DEFAULT 0 COMMENT 'Task priority',
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date',
`pid` int NOT NULL DEFAULT 0 COMMENT 'Process id of the worker',
$ret = api_statuses_show($type);
- Item::delete($id);
+ Item::deleteById($id);
return $ret;
}
throw new BadRequestException("Invalid action ".$action);
}
- $r = q("UPDATE item SET starred=%d WHERE id=%d AND uid=%d", $item[0]['starred'], $itemid, api_user());
-
- q("UPDATE thread SET starred=%d WHERE iid=%d AND uid=%d", $item[0]['starred'], $itemid, api_user());
+ Item::update(['starred' => $item[0]['starred']], ['id' => $itemid]);
if ($r === false) {
throw new InternalServerErrorException("DB error");
if (!DBM::is_result($photo_item)) {
throw new InternalServerErrorException("problem with deleting items occured");
}
- Item::delete($photo_item[0]['id']);
+ Item::deleteById($photo_item[0]['id']);
}
// now let's delete all photos from the album
}
// function for setting the items to "deleted = 1" which ensures that comments, likes etc. are not shown anymore
// to the user and the contacts of the users (drop_items() do all the necessary magic to avoid orphans in database and federate deletion)
- Item::delete($photo_item[0]['id']);
+ Item::deleteById($photo_item[0]['id']);
$answer = ['result' => 'deleted', 'message' => 'photo with id `' . $photo_id . '` has been deleted from server.'];
return api_format_data("photo_delete", $type, ['$result' => $answer]);
$object .= '<content>' . xmlify(format_event_bbcode($arr)) . '</content>';
$object .= '</object>' . "\n";
- q("UPDATE `item` SET `body` = '%s', `object` = '%s', `edited` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc(format_event_bbcode($arr)),
- dbesc($object),
- dbesc($arr['edited']),
- intval($r[0]['id']),
- intval($arr['uid'])
- );
+ $fields = ['body' => format_event_bbcode($arr), 'object' => $object, 'edited' => $arr['edited']];
+ Item::update($fields, ['id' => $r[0]['id']]);
$item_id = $r[0]['id'];
} else {
$item_id = Item::insert($item_arr);
if ($item_id) {
- q("UPDATE `item` SET `event-id` = %d WHERE `uid` = %d AND `id` = %d",
- intval($event['id']),
- intval($arr['uid']),
- intval($item_id)
- );
+ Item::update(['event-id' => $event['id']], ['id' => $item_id]);
}
Addon::callHooks("event_created", $event['id']);
use Friendica\Util\Temporal;
require_once 'include/bbcode.php';
-require_once 'include/tags.php';
require_once 'include/text.php';
-require_once 'include/threads.php';
require_once 'mod/share.php';
require_once 'include/enotify.php';
if (count($items)) {
foreach ($items as $item) {
- $owner = Item::delete($item);
+ $owner = Item::deleteById($item);
if ($owner && !$uid)
$uid = $owner;
}
}
// delete the item
- Item::delete($item['id']);
+ Item::deleteById($item['id']);
goaway(System::baseUrl() . '/' . $_SESSION['return_url']);
//NOTREACHED
+++ /dev/null
-<?php
-/**
- * @file include/tags.php
- */
-use Friendica\App;
-use Friendica\Content\Feature;
-use Friendica\Core\L10n;
-use Friendica\Core\System;
-use Friendica\Database\DBM;
-use Friendica\Model\Contact;
-
-function create_tags_from_item($itemid)
-{
- $profile_base = System::baseUrl();
- $profile_data = parse_url($profile_base);
- $profile_path = defaults($profile_data, 'path', '');
- $profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/';
- $profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/';
-
- $messages = q("SELECT `guid`, `uid`, `id`, `edited`, `deleted`, `created`, `received`, `title`, `body`, `tag`, `parent` FROM `item` WHERE `id` = %d LIMIT 1", intval($itemid));
-
- if (!$messages)
- return;
-
- $message = $messages[0];
-
- // Clean up all tags
- q("DELETE FROM `term` WHERE `otype` = %d AND `oid` = %d AND `type` IN (%d, %d)",
- intval(TERM_OBJ_POST),
- intval($itemid),
- intval(TERM_HASHTAG),
- intval(TERM_MENTION));
-
- if ($message['deleted']) {
- return;
- }
-
- $taglist = explode(',', $message['tag']);
-
- $tags = '';
- foreach ($taglist as $tag) {
- if ((substr(trim($tag), 0, 1) == '#') || (substr(trim($tag), 0, 1) == '@')) {
- $tags .= ' ' . trim($tag);
- } else {
- $tags .= ' #' . trim($tag);
- }
- }
-
- $data = ' ' . $message['title'] . ' ' . $message['body'] . ' ' . $tags . ' ';
-
- // ignore anything in a code block
- $data = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $data);
-
- $tags = [];
-
- $pattern = '/\W\#([^\[].*?)[\s\'".,:;\?!\[\]\/]/ism';
- if (preg_match_all($pattern, $data, $matches)) {
- foreach ($matches[1] as $match) {
- $tags['#' . strtolower($match)] = '';
- }
- }
-
- $pattern = '/\W([\#@])\[url\=(.*?)\](.*?)\[\/url\]/ism';
- if (preg_match_all($pattern, $data, $matches, PREG_SET_ORDER)) {
- foreach ($matches as $match) {
- $tags[$match[1] . strtolower(trim($match[3], ',.:;[]/\"?!'))] = $match[2];
- }
- }
-
- foreach ($tags as $tag => $link) {
- if (substr(trim($tag), 0, 1) == '#') {
- // try to ignore #039 or #1 or anything like that
- if (ctype_digit(substr(trim($tag), 1)))
- continue;
- // try to ignore html hex escapes, e.g. #x2317
- if ((substr(trim($tag), 1, 1) == 'x' || substr(trim($tag), 1, 1) == 'X') && ctype_digit(substr(trim($tag), 2)))
- continue;
- $type = TERM_HASHTAG;
- $term = substr($tag, 1);
- } elseif (substr(trim($tag), 0, 1) == '@') {
- $type = TERM_MENTION;
- $term = substr($tag, 1);
- } else { // This shouldn't happen
- $type = TERM_HASHTAG;
- $term = $tag;
- }
-
- if ($message['uid'] == 0) {
- $global = true;
-
- q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
- intval(TERM_OBJ_POST), dbesc($message['guid']));
- } else {
- $isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
- intval(TERM_OBJ_POST), dbesc($message['guid']));
-
- $global = (count($isglobal) > 0);
- }
-
- q("INSERT INTO `term` (`uid`, `oid`, `otype`, `type`, `term`, `url`, `guid`, `created`, `received`, `global`)
- VALUES (%d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d)",
- intval($message['uid']), intval($itemid), intval(TERM_OBJ_POST), intval($type), dbesc($term),
- dbesc($link), dbesc($message['guid']), dbesc($message['created']), dbesc($message['received']), intval($global));
-
- // Search for mentions
- if ((substr($tag, 0, 1) == '@') && (strpos($link, $profile_base_friendica) || strpos($link, $profile_base_diaspora))) {
- $users = q("SELECT `uid` FROM `contact` WHERE self AND (`url` = '%s' OR `nurl` = '%s')", $link, $link);
- foreach ($users AS $user) {
- if ($user['uid'] == $message['uid']) {
- q("UPDATE `item` SET `mention` = 1 WHERE `id` = %d", intval($itemid));
-
- q("UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d", intval($message['parent']));
- }
- }
- }
- }
-}
-
-function create_tags_from_itemuri($itemuri, $uid)
-{
- $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
-
- if (count($messages)) {
- foreach ($messages as $message) {
- create_tags_from_item($message['id']);
- }
- }
-}
-
-function update_items()
-{
- $messages = dba::p("SELECT `oid`,`item`.`guid`, `item`.`created`, `item`.`received` FROM `term` INNER JOIN `item` ON `item`.`id`=`term`.`oid` WHERE `term`.`otype` = 1 AND `term`.`guid` = ''");
-
- logger('fetched messages: ' . dba::num_rows($messages));
- while ($message = dba::fetch($messages)) {
- if ($message['uid'] == 0) {
- $global = true;
-
- q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
- intval(TERM_OBJ_POST), dbesc($message['guid']));
- } else {
- $isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
- intval(TERM_OBJ_POST), dbesc($message['guid']));
-
- $global = (count($isglobal) > 0);
- }
-
- q("UPDATE `term` SET `guid` = '%s', `created` = '%s', `received` = '%s', `global` = %d WHERE `otype` = %d AND `oid` = %d",
- dbesc($message['guid']), dbesc($message['created']), dbesc($message['received']),
- intval($global), intval(TERM_OBJ_POST), intval($message['oid']));
- }
-
- dba::close($messages);
-
- $messages = dba::p("SELECT `guid` FROM `item` WHERE `uid` = 0");
-
- logger('fetched messages: ' . dba::num_rows($messages));
- while ($message = dba::fetch(messages)) {
- q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($message['guid']));
- }
-
- dba::close($messages);
-}
-
-/**
- * @brief Get alphabetical sorted array of used tags/terms of an user including
- * a weighting by frequency of use.
- *
- * @param int $uid The user ID.
- * @param int $count Max number of displayed tags/terms.
- * @param int $owner_id The contact id of the owner of the tagged items.
- * @param string $flags Special item flags.
- * @param int $type The tag/term type.
- *
- * @return arr Alphabetical sorted array of used tags of an user.
- */
-function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
-{
- require_once 'include/security.php';
-
- $item_condition = item_condition();
- $sql_options = item_permissions_sql($uid);
- $limit = $count ? sprintf('LIMIT %d', intval($count)) : '';
-
- if ($flags) {
- if ($flags === 'wall') {
- $sql_options .= ' AND `item`.`wall` ';
- }
- }
-
- if ($owner_id) {
- $sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' ';
- }
-
- // Fetch tags
- $r = dba::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term`
- LEFT JOIN `item` ON `term`.`oid` = `item`.`id`
- WHERE `term`.`uid` = ? AND `term`.`type` = ?
- AND `term`.`otype` = ?
- AND $item_condition $sql_options
- GROUP BY `term` ORDER BY `total` DESC $limit",
- $uid,
- $type,
- TERM_OBJ_POST
- );
- if (!DBM::is_result($r)) {
- return [];
- }
-
- return tag_calc($r);
-}
-
-/**
- * @brief Construct a tag/term cloud block for an user.
- *
- * @param int $uid The user ID.
- * @param int $count Max number of displayed tags/terms.
- * @param int $owner_id The contact ID of the owner of the tagged items.
- * @param string $flags Special item flags.
- * @param int $type The tag/term type.
- *
- * @return string HTML formatted output.
- */
-function wtagblock($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)
-{
- $o = '';
- $r = tagadelic($uid, $count, $owner_id, $flags, $type);
- if (count($r)) {
- $contact = dba::selectFirst('contact', ['url'], ['id' => $uid]);
- $url = System::removedBaseUrl($contact['url']);
-
- foreach ($r as $rr) {
- $tag['level'] = $rr[2];
- $tag['url'] = $url . '?tag=' . urlencode($rr[0]);
- $tag['name'] = $rr[0];
-
- $tags[] = $tag;
- }
-
- $tpl = get_markup_template('tagblock_widget.tpl');
- $o = replace_macros($tpl, [
- '$title' => L10n::t('Tags'),
- '$tags' => $tags
- ]);
- }
- return $o;
-}
-
-/**
- * @brief Calculate weighting of tags according to the frequency of use.
- *
- * @param array $arr Array of tags/terms with tag/term name and total count of use.
- * @return array Alphabetical sorted array of used tags/terms of an user.
- */
-function tag_calc($arr)
-{
- $tags = [];
- $min = 1e9;
- $max = -1e9;
- $x = 0;
-
- if (!$arr) {
- return [];
- }
-
- foreach ($arr 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(9 * ($tags[$x][1] - $min) / $range);
- }
-
- return $tags;
-}
-
-/**
- * @brief Compare function to sort tags/terms alphabetically.
- *
- * @param type $a
- * @param type $b
- *
- * @return int
- */
-function tags_sort($a, $b)
-{
- if (strtolower($a[0]) == strtolower($b[0])) {
- return 0;
- }
- return ((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
-}
-
-/**
- * @brief Insert a tag cloud widget for the present profile.
- *
- * @param int $limit Max number of displayed tags.
- * @return string HTML formattat output.
- */
-function tagcloud_wall_widget($limit = 50)
-{
- $a = get_app();
-
- if (!$a->profile['profile_uid'] || !$a->profile['url']) {
- return '';
- }
-
- if (Feature::isEnabled($a->profile['profile_uid'], 'tagadelic')) {
- $owner_id = Contact::getIdForURL($a->profile['url']);
-
- if (!$owner_id) {
- return '';
- }
- return wtagblock($a->profile['profile_uid'], $limit, $owner_id, 'wall');
- }
-
- return '';
-}
intval($uid)
);
if (DBM::is_result($r)) {
- if (! stristr($r[0]['file'],'[' . file_tag_encode($file) . ']')) {
- q("UPDATE `item` SET `file` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc($r[0]['file'] . '[' . file_tag_encode($file) . ']'),
- intval($item),
- intval($uid)
- );
+ if (!stristr($r[0]['file'],'[' . file_tag_encode($file) . ']')) {
+ $fields = ['file' => $r[0]['file'] . '[' . file_tag_encode($file) . ']'];
+ Item::update($fields, ['id' => $item]);
}
-
- Term::createFromItem($item);
-
$saved = PConfig::get($uid, 'system', 'filetags');
if (!strlen($saved) || !stristr($saved, '[' . file_tag_encode($file) . ']')) {
PConfig::set($uid, 'system', 'filetags', $saved . '[' . file_tag_encode($file) . ']');
return false;
}
- q("UPDATE `item` SET `file` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc(str_replace($pattern,'',$r[0]['file'])),
- intval($item),
- intval($uid)
- );
-
- Term::createFromItem($item);
+ $fields = ['file' => str_replace($pattern,'',$r[0]['file'])];
+ Item::update($fields, ['id' => $item]);
$r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
dbesc($file),
+++ /dev/null
-<?php
-
-use Friendica\Database\DBM;
-
-function add_thread($itemid, $onlyshadow = false) {
- $items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
- `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
- `deleted`, `origin`, `forum_mode`, `mention`, `network`, `author-id`, `owner-id`
- FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
-
- if (!$items)
- return;
-
- $item = $items[0];
- $item['iid'] = $itemid;
-
- if (!$onlyshadow) {
- $result = dba::insert('thread', $item);
-
- logger("Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
- }
-}
-
-function update_thread_uri($itemuri, $uid) {
- $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
-
- if (DBM::is_result($messages)) {
- foreach ($messages as $message) {
- update_thread($message["id"]);
- }
- }
-}
-
-function update_thread($itemid, $setmention = false) {
- $items = q("SELECT `uid`, `guid`, `title`, `body`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
- `deleted`, `origin`, `forum_mode`, `network`, `rendered-html`, `rendered-hash` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
-
- if (!DBM::is_result($items)) {
- return;
- }
-
- $item = $items[0];
-
- if ($setmention) {
- $item["mention"] = 1;
- }
-
- $sql = "";
-
- foreach ($item AS $field => $data)
- if (!in_array($field, ["guid", "title", "body", "rendered-html", "rendered-hash"])) {
- if ($sql != "") {
- $sql .= ", ";
- }
-
- $sql .= "`".$field."` = '".dbesc($data)."'";
- }
-
- $result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
-
- logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
-
- // Updating a shadow item entry
- $items = q("SELECT `id` FROM `item` WHERE `guid` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item["guid"]));
-
- if (!DBM::is_result($items)) {
- return;
- }
-
- $result = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s' WHERE `id` = %d",
- dbesc($item["title"]),
- dbesc($item["body"]),
- dbesc($item["rendered-html"]),
- dbesc($item["rendered-hash"]),
- intval($items[0]["id"])
- );
- logger("Updating public shadow for post ".$items[0]["id"]." - guid ".$item["guid"]." Result: ".print_r($result, true), LOGGER_DEBUG);
-}
-
-function delete_thread_uri($itemuri, $uid) {
- $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
-
- if (DBM::is_result($messages)) {
- foreach ($messages as $message) {
- delete_thread($message["id"], $itemuri);
- }
- }
-}
-
-function delete_thread($itemid, $itemuri = "") {
- $item = q("SELECT `uid` FROM `thread` WHERE `iid` = %d", intval($itemid));
-
- if (!DBM::is_result($item)) {
- logger('No thread found for id '.$itemid, LOGGER_DEBUG);
- return;
- }
-
- // Using dba::delete at this time could delete the associated item entries
- $result = dba::e("DELETE FROM `thread` WHERE `iid` = ?", $itemid);
-
- logger("delete_thread: Deleted thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
-
- if ($itemuri != "") {
- $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND NOT `deleted` AND NOT (`uid` IN (%d, 0))",
- dbesc($itemuri),
- intval($item["uid"])
- );
- if (!DBM::is_result($r)) {
- dba::delete('item', ['uri' => $itemuri, 'uid' => 0]);
- logger("delete_thread: Deleted shadow for item ".$itemuri, LOGGER_DEBUG);
- }
- }
-}
// associated threads.
$r = dba::select('item', ['id'], ['guid' => $guid]);
while ($row = dba::fetch($r)) {
- Item::delete($row['id']);
+ Item::deleteById($row['id']);
}
dba::close($r);
}
intval($contact_id),
intval(local_user())
);
- if ($archived) {
- q("UPDATE `item` SET `private` = 2 WHERE `contact-id` = %d AND `uid` = %d", intval($contact_id), intval(local_user()));
- }
return DBM::is_result($r);
}
// Delete only real events (no birthdays)
if (DBM::is_result($ev) && $ev[0]['type'] == 'event') {
- $del = Item::delete($ev[0]['itemid']);
+ $del = Item::deleteById($ev[0]['itemid']);
}
if ($del == 0) {
use Friendica\Util\Emailer;
require_once 'include/enotify.php';
-require_once 'include/tags.php';
-require_once 'include/threads.php';
require_once 'include/text.php';
require_once 'include/items.php';
$o = '';
if (($a->argc == 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) {
if (is_ajax()) {
- $o = Item::delete($a->argv[2]);
+ $o = Item::deleteById($a->argv[2]);
} else {
$o = drop_item($a->argv[2]);
}
use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\Group;
+use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Module\Login;
use Friendica\Util\DateTimeFormat;
$unseen = dba::exists('item', $condition);
if ($unseen) {
- $r = dba::update('item', ['unseen' => false], $condition);
+ $r = Item::update(['unseen' => false], $condition);
}
}
use Friendica\Model\Item;
use Friendica\Model\Photo;
use Friendica\Model\Profile;
+use Friendica\Model\Term;
use Friendica\Network\Probe;
use Friendica\Object\Image;
use Friendica\Protocol\DFRN;
require_once 'include/acl_selectors.php';
require_once 'include/bbcode.php';
require_once 'include/security.php';
-require_once 'include/tags.php';
-require_once 'include/threads.php';
function photos_init(App $a) {
);
// find and delete the corresponding item with all the comments and likes/dislikes
- $r = q("SELECT `id`, `parent-uri`, `visible` FROM `item` WHERE `resource-id` IN ( $str_res ) AND `uid` = %d",
+ $r = q("SELECT `id` FROM `item` WHERE `resource-id` IN ( $str_res ) AND `uid` = %d",
intval($page_owner_uid)
);
if (DBM::is_result($r)) {
foreach ($r as $rr) {
- q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(DateTimeFormat::utcNow()),
- dbesc($rr['parent-uri']),
- intval($page_owner_uid)
- );
- create_tags_from_itemuri($rr['parent-uri'], $page_owner_uid);
- delete_thread_uri($rr['parent-uri'], $page_owner_uid);
-
- $drop_id = intval($rr['id']);
-
- // send the notification upstream/downstream as the case may be
- if ($rr['visible']) {
- Worker::add(PRIORITY_HIGH, "Notifier", "drop", $drop_id);
- }
+ Item::deleteById($rr['id']);
}
}
intval($page_owner_uid),
dbesc($r[0]['resource-id'])
);
- $i = q("SELECT `id`, `uri`, `visible` FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1",
+ $i = q("SELECT `id` FROM `item` WHERE `resource-id` = '%s' AND `uid` = %d LIMIT 1",
dbesc($r[0]['resource-id']),
intval($page_owner_uid)
);
if (DBM::is_result($i)) {
- q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(DateTimeFormat::utcNow()),
- dbesc(DateTimeFormat::utcNow()),
- dbesc($i[0]['uri']),
- intval($page_owner_uid)
- );
- create_tags_from_itemuri($i[0]['uri'], $page_owner_uid);
- delete_thread_uri($i[0]['uri'], $page_owner_uid);
-
- $url = System::baseUrl();
- $drop_id = intval($i[0]['id']);
+ Item::deleteById($i[0]['id']);
// Update the photo albums cache
Photo::clearAlbumCache($page_owner_uid);
-
- if ($i[0]['visible']) {
- Worker::add(PRIORITY_HIGH, "Notifier", "drop", $drop_id);
- }
}
}
}
$newinform .= $inform;
- $r = q("UPDATE `item` SET `tag` = '%s', `inform` = '%s', `edited` = '%s', `changed` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc($newtag),
- dbesc($newinform),
- dbesc(DateTimeFormat::utcNow()),
- dbesc(DateTimeFormat::utcNow()),
- intval($item_id),
- intval($page_owner_uid)
- );
- create_tags_from_item($item_id);
- update_thread($item_id);
+ $fields = ['tag' => $newtag, 'inform' => $newinform, 'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()];
+ $condition = ['id' => $item_id];
+ Item::update($fields, $condition);
$best = 0;
foreach ($p as $scales) {
);
if (local_user() && (local_user() == $link_item['uid'])) {
- q("UPDATE `item` SET `unseen` = 0 WHERE `parent` = %d and `uid` = %d",
- intval($link_item['parent']),
- intval(local_user())
- );
- update_thread($link_item['parent']);
+ Item::update(['unseen' => false], ['parent' => $link_item['parent']]);
}
if ($link_item['coord']) {
$item_id = Item::insert($arr);
if($item_id) {
- //q("UPDATE `item` SET `plink` = '%s' WHERE `uid` = %d AND `id` = %d",
- // dbesc(System::baseUrl() . '/display/' . $poster['nickname'] . '/' . $item_id),
- // intval($uid),
- // intval($item_id)
- //);
Worker::add(PRIORITY_HIGH, "Notifier", "tag", $item_id);
}
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Model\Group;
+use Friendica\Model\Item;
use Friendica\Model\Profile;
use Friendica\Module\Login;
use Friendica\Protocol\DFRN;
$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (x($category) ? xmlify($category) : ''));
- $a->page['aside'] .= tagcloud_wall_widget();
+ $a->page['aside'] .= Widget::tagCloud();
if (can_write_wall($a->profile['profile_uid'])) {
$x = [
if ($is_owner) {
$unseen = dba::exists('item', ['wall' => true, 'unseen' => true, 'uid' => local_user()]);
if ($unseen) {
- $r = dba::update('item', ['unseen' => false],
+ $r = Item::update(['unseen' => false],
['wall' => true, 'unseen' => true, 'uid' => local_user()]);
}
}
$r = q("SELECT %s
FROM `term`
STRAIGHT_JOIN `item` ON `item`.`id`=`term`.`oid` %s
- WHERE %s AND (`term`.`uid` = 0 OR (`term`.`uid` = %d AND NOT `term`.`global`)) AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`term` = '%s'
+ WHERE %s AND (`term`.`uid` = 0 OR (`term`.`uid` = %d AND NOT `term`.`global`))
+ AND `term`.`otype` = %d AND `term`.`type` = %d AND `term`.`term` = '%s' AND `item`.`verb` = '%s'
ORDER BY term.created DESC LIMIT %d , %d ",
item_fieldlists(), item_joins(), item_condition(),
intval(local_user()),
- intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search)),
+ intval(TERM_OBJ_POST), intval(TERM_HASHTAG), dbesc(protect_sprintf($search)), dbesc(ACTIVITY_POST),
intval($a->pager['start']), intval($a->pager['itemspage']));
} else {
logger("Start fulltext search for '".$search."'", LOGGER_DEBUG);
<?php
-
+/**
+ * @file mod/starred.php
+ */
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBM;
+use Friendica\Model\Item;
function starred_init(App $a) {
-
- require_once("include/threads.php");
-
$starred = 0;
if (! local_user()) {
$starred = 1;
}
- $r = q("UPDATE `item` SET `starred` = %d WHERE `uid` = %d AND `id` = %d",
- intval($starred),
- intval(local_user()),
- intval($message_id)
- );
-
- update_thread($message_id);
+ Item::update(['starred' => $starred], ['id' => $message_id]);
// See if we've been passed a return path to redirect to
$return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : '');
$post_id = Item::insert($arr);
- if (! $item['visible']) {
- $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d",
- intval($item['id']),
- intval($owner_uid)
- );
+ if (!$item['visible']) {
+ Item::update(['visible' => true], ['id' => $item['id']]);
}
$arr['id'] = $post_id;
$post_id = Item::insert($arr);
- if(! $item['visible']) {
- $r = q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d AND `uid` = %d",
- intval($item['id']),
- intval($owner_uid)
- );
+ if (!$item['visible']) {
+ Item::update(['visible' => true], ['id' => $item['id']]);
}
- $term_objtype = (($item['resource-id']) ? TERM_OBJ_PHOTO : TERM_OBJ_POST );
+ $term_objtype = ($item['resource-id'] ? TERM_OBJ_PHOTO : TERM_OBJ_POST);
$t = q("SELECT count(tid) as tcount FROM term WHERE oid=%d AND term='%s'",
intval($item['id']),
dbesc($term)
);
if((! $blocktags) && $t[0]['tcount']==0 ) {
- /*q("update item set tag = '%s' where id = %d",
- dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . System::baseUrl() . '/search?tag=' . $term . ']'. $term . '[/url]'),
- intval($item['id'])
- );*/
-
q("INSERT INTO term (oid, otype, type, term, url, uid) VALUE (%d, %d, %d, '%s', '%s', %d)",
intval($item['id']),
$term_objtype,
intval($owner_uid)
);
}
-
- /*if(count($x) && !$x[0]['blocktags'] && (! stristr($r[0]['tag'], ']' . $term . '['))) {
- q("update item set tag = '%s' where id = %d",
- dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . System::baseUrl() . '/search?tag=' . $term . ']'. $term . '[/url]'),
- intval($r[0]['id'])
- );
- }*/
-
}
killme();
return; // NOTREACHED
-
-
}
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBM;
+use Friendica\Model\Item;
require_once 'include/bbcode.php';
function tagrm_post(App $a) {
- if (! local_user()) {
+ if (!local_user()) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
}
intval(local_user())
);
- if (! DBM::is_result($r)) {
+ if (!DBM::is_result($r)) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
}
$tag_str = implode(',',$arr);
- q("UPDATE `item` SET `tag` = '%s' WHERE `id` = %d AND `uid` = %d",
- dbesc($tag_str),
- intval($item),
- intval(local_user())
- );
+ Item::update(['tag' => $tag_str], ['id' => $item]);
info(L10n::t('Tag removed') . EOL );
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
// NOTREACHED
-
}
$o = '';
- if (! local_user()) {
+ if (!local_user()) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
// NOTREACHED
}
$item = (($a->argc > 1) ? intval($a->argv[1]) : 0);
- if (! $item) {
+ if (!$item) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
// NOTREACHED
}
intval(local_user())
);
- if (! DBM::is_result($r)) {
+ if (!DBM::is_result($r)) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
}
$arr = explode(',', $r[0]['tag']);
- if (! count($arr)) {
+ if (!count($arr)) {
goaway(System::baseUrl() . '/' . $_SESSION['photo_return']);
}
use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\Group;
+use Friendica\Model\Item;
use Friendica\Model\Profile;
+use Friendica\Model\Term;
use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat;
intval(local_user()),
dbesc($video_id)
);
- $i = q("SELECT * FROM `item` WHERE `attach` like '%%attach/%s%%' AND `uid` = %d LIMIT 1",
+ $i = q("SELECT `id` FROM `item` WHERE `attach` like '%%attach/%s%%' AND `uid` = %d LIMIT 1",
dbesc($video_id),
intval(local_user())
);
- //echo "<pre>"; var_dump($i); killme();
- if (DBM::is_result($i)) {
- q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(DateTimeFormat::utcNow()),
- dbesc(DateTimeFormat::utcNow()),
- dbesc($i[0]['uri']),
- intval(local_user())
- );
- create_tags_from_itemuri($i[0]['uri'], local_user());
- delete_thread_uri($i[0]['uri'], local_user());
-
- $url = System::baseUrl();
- $drop_id = intval($i[0]['id']);
- if ($i[0]['visible']) {
- Worker::add(PRIORITY_HIGH, "Notifier", "drop", $drop_id);
- }
+ if (DBM::is_result($i)) {
+ Item::deleteById($i[0]['id']);
}
}
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Database\DBM;
+use Friendica\Model\Contact;
use Friendica\Model\GContact;
use Friendica\Model\Profile;
-
use dba;
require_once 'boot.php';
+require_once 'include/dba.php';
class Widget
{
'$items' => $r)
);
}
+
+ /**
+ * Insert a tag cloud widget for the present profile.
+ *
+ * @brief Insert a tag cloud widget for the present profile.
+ * @param int $limit Max number of displayed tags.
+ * @return string HTML formatted output.
+ */
+ public static function tagCloud($limit = 50)
+ {
+ $a = get_app();
+
+ if (!$a->profile['profile_uid'] || !$a->profile['url']) {
+ return '';
+ }
+
+ if (Feature::isEnabled($a->profile['profile_uid'], 'tagadelic')) {
+ $owner_id = Contact::getIdForURL($a->profile['url']);
+
+ if (!$owner_id) {
+ return '';
+ }
+ return Widget\TagCloud::getHTML($a->profile['profile_uid'], $limit, $owner_id, 'wall');
+ }
+
+ return '';
+ }
}
--- /dev/null
+<?php\r
+\r
+/*\r
+ * @file src/Content/Widget/TagCloud.php\r
+ */\r
+\r
+namespace Friendica\Content\Widget;\r
+\r
+use dba;\r
+use Friendica\Core\L10n;\r
+use Friendica\Core\System;\r
+use Friendica\Database\DBM;\r
+\r
+require_once 'include/dba.php';\r
+require_once 'include/security.php';\r
+\r
+/**\r
+ * TagCloud widget\r
+ *\r
+ * @author Rabuzarus\r
+ */\r
+class TagCloud\r
+{\r
+ /**\r
+ * Construct a tag/term cloud block for an user.\r
+ *\r
+ * @brief Construct a tag/term cloud block for an user.\r
+ * @param int $uid The user ID.\r
+ * @param int $count Max number of displayed tags/terms.\r
+ * @param int $owner_id The contact ID of the owner of the tagged items.\r
+ * @param string $flags Special item flags.\r
+ * @param int $type The tag/term type.\r
+ *\r
+ * @return string HTML formatted output.\r
+ */\r
+ public static function getHTML($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)\r
+ {\r
+ $o = '';\r
+ $r = self::tagadelic($uid, $count, $owner_id, $flags, $type);\r
+ if (count($r)) {\r
+ $contact = dba::selectFirst('contact', ['url'], ['uid' => $uid, 'self' => true]);\r
+ $url = System::removedBaseUrl($contact['url']);\r
+\r
+ foreach ($r as $rr) {\r
+ $tag['level'] = $rr[2];\r
+ $tag['url'] = $url . '?tag=' . urlencode($rr[0]);\r
+ $tag['name'] = $rr[0];\r
+\r
+ $tags[] = $tag;\r
+ }\r
+\r
+ $tpl = get_markup_template('tagblock_widget.tpl');\r
+ $o = replace_macros($tpl, [\r
+ '$title' => L10n::t('Tags'),\r
+ '$tags' => $tags\r
+ ]);\r
+ }\r
+ return $o;\r
+ }\r
+\r
+ /**\r
+ * Get alphabetical sorted array of used tags/terms of an user including\r
+ * a weighting by frequency of use.\r
+ *\r
+ * @brief Get alphabetical sorted array of used tags/terms of an user including\r
+ * a weighting by frequency of use.\r
+ * @param int $uid The user ID.\r
+ * @param int $count Max number of displayed tags/terms.\r
+ * @param int $owner_id The contact id of the owner of the tagged items.\r
+ * @param string $flags Special item flags.\r
+ * @param int $type The tag/term type.\r
+ *\r
+ * @return arr Alphabetical sorted array of used tags of an user.\r
+ */\r
+ private static function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG)\r
+ {\r
+ $item_condition = item_condition();\r
+ $sql_options = item_permissions_sql($uid);\r
+ $limit = $count ? sprintf('LIMIT %d', intval($count)) : '';\r
+\r
+ if ($flags) {\r
+ if ($flags === 'wall') {\r
+ $sql_options .= ' AND `item`.`wall` ';\r
+ }\r
+ }\r
+\r
+ if ($owner_id) {\r
+ $sql_options .= ' AND `item`.`owner-id` = ' . intval($owner_id) . ' ';\r
+ }\r
+\r
+ // Fetch tags\r
+ $r = dba::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term`\r
+ LEFT JOIN `item` ON `term`.`oid` = `item`.`id`\r
+ WHERE `term`.`uid` = ? AND `term`.`type` = ?\r
+ AND `term`.`otype` = ?\r
+ AND $item_condition $sql_options\r
+ GROUP BY `term` ORDER BY `total` DESC $limit",\r
+ $uid,\r
+ $type,\r
+ TERM_OBJ_POST\r
+ );\r
+ if (!DBM::is_result($r)) {\r
+ return [];\r
+ }\r
+\r
+ return self::tagCalc($r);\r
+ }\r
+\r
+ /**\r
+ * Calculate weighting of tags according to the frequency of use.\r
+ *\r
+ * @brief Calculate weighting of tags according to the frequency of use.\r
+ * @param array $arr Array of tags/terms with tag/term name and total count of use.\r
+ * @return array Alphabetical sorted array of used tags/terms of an user.\r
+ */\r
+ private static function tagCalc($arr)\r
+ {\r
+ $tags = [];\r
+ $min = 1e9;\r
+ $max = -1e9;\r
+ $x = 0;\r
+\r
+ if (!$arr) {\r
+ return [];\r
+ }\r
+\r
+ foreach ($arr as $rr) {\r
+ $tags[$x][0] = $rr['term'];\r
+ $tags[$x][1] = log($rr['total']);\r
+ $tags[$x][2] = 0;\r
+ $min = min($min, $tags[$x][1]);\r
+ $max = max($max, $tags[$x][1]);\r
+ $x ++;\r
+ }\r
+\r
+ usort($tags, 'self::tagsSort');\r
+ $range = max(.01, $max - $min) * 1.0001;\r
+\r
+ for ($x = 0; $x < count($tags); $x ++) {\r
+ $tags[$x][2] = 1 + floor(9 * ($tags[$x][1] - $min) / $range);\r
+ }\r
+\r
+ return $tags;\r
+ }\r
+\r
+ /**\r
+ * Compare function to sort tags/terms alphabetically.\r
+ *\r
+ * @brief Compare function to sort tags/terms alphabetically.\r
+ * @param type $a\r
+ * @param type $b\r
+ *\r
+ * @return int\r
+ */\r
+ private static function tagsSort($a, $b)\r
+ {\r
+ if (strtolower($a[0]) == strtolower($b[0])) {\r
+ return 0;\r
+ }\r
+ return ((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);\r
+ }\r
+}\r
-<?php\r
-/**\r
- * @file src/Core/Addon.php\r
- */\r
-namespace Friendica\Core;\r
-\r
-use Friendica\Core\Config;\r
-use Friendica\Database\DBM;\r
-\r
-use dba;\r
-\r
-require_once 'include/dba.php';\r
-\r
-/**\r
- * Some functions to handle addons\r
- */\r
-class Addon\r
-{\r
- /**\r
- * @brief uninstalls an addon.\r
- *\r
- * @param string $addon name of the addon\r
- * @return boolean\r
- */\r
- public static function uninstall($addon)\r
- {\r
- logger("Addons: uninstalling " . $addon);\r
- dba::delete('addon', ['name' => $addon]);\r
-\r
- @include_once('addon/' . $addon . '/' . $addon . '.php');\r
- if (function_exists($addon . '_uninstall')) {\r
- $func = $addon . '_uninstall';\r
- $func();\r
- }\r
- }\r
-\r
- /**\r
- * @brief installs an addon.\r
- *\r
- * @param string $addon name of the addon\r
- * @return bool\r
- */\r
- public static function install($addon)\r
- {\r
- // silently fail if addon was removed\r
-\r
- if (!file_exists('addon/' . $addon . '/' . $addon . '.php')) {\r
- return false;\r
- }\r
- logger("Addons: installing " . $addon);\r
- $t = @filemtime('addon/' . $addon . '/' . $addon . '.php');\r
- @include_once('addon/' . $addon . '/' . $addon . '.php');\r
- if (function_exists($addon . '_install')) {\r
- $func = $addon . '_install';\r
- $func();\r
-\r
- $addon_admin = (function_exists($addon."_addon_admin") ? 1 : 0);\r
-\r
- dba::insert('addon', ['name' => $addon, 'installed' => true,\r
- 'timestamp' => $t, 'plugin_admin' => $addon_admin]);\r
-\r
- // we can add the following with the previous SQL\r
- // once most site tables have been updated.\r
- // This way the system won't fall over dead during the update.\r
-\r
- if (file_exists('addon/' . $addon . '/.hidden')) {\r
- dba::update('addon', ['hidden' => true], ['name' => $addon]);\r
- }\r
- return true;\r
- } else {\r
- logger("Addons: FAILED installing " . $addon);\r
- return false;\r
- }\r
- }\r
-\r
- /**\r
- * reload all updated addons\r
- */\r
- public static function reload()\r
- {\r
- $addons = Config::get('system', 'addon');\r
- if (strlen($addons)) {\r
- $r = dba::select('addon', [], ['installed' => 1]);\r
- if (DBM::is_result($r)) {\r
- $installed = dba::inArray($r);\r
- } else {\r
- $installed = [];\r
- }\r
-\r
- $addon_list = explode(',', $addons);\r
-\r
- if (count($addon_list)) {\r
- foreach ($addon_list as $addon) {\r
- $addon = trim($addon);\r
- $fname = 'addon/' . $addon . '/' . $addon . '.php';\r
-\r
- if (file_exists($fname)) {\r
- $t = @filemtime($fname);\r
- foreach ($installed as $i) {\r
- if (($i['name'] == $addon) && ($i['timestamp'] != $t)) {\r
- logger('Reloading addon: ' . $i['name']);\r
- @include_once($fname);\r
-\r
- if (function_exists($addon . '_uninstall')) {\r
- $func = $addon . '_uninstall';\r
- $func();\r
- }\r
- if (function_exists($addon . '_install')) {\r
- $func = $addon . '_install';\r
- $func();\r
- }\r
- dba::update('addon', ['timestamp' => $t], ['id' => $i['id']]);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * @brief check if addon is enabled\r
- *\r
- * @param string $addon\r
- * @return boolean\r
- */\r
- public static function isEnabled($addon)\r
- {\r
- return dba::exists('addon', ['installed' => true, 'name' => $addon]);\r
- }\r
-\r
-\r
- /**\r
- * @brief registers a hook.\r
- *\r
- * @param string $hook the name of the hook\r
- * @param string $file the name of the file that hooks into\r
- * @param string $function the name of the function that the hook will call\r
- * @param int $priority A priority (defaults to 0)\r
- * @return mixed|bool\r
- */\r
- public static function registerHook($hook, $file, $function, $priority = 0)\r
- {\r
- $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];\r
- $exists = dba::exists('hook', $condition);\r
- if ($exists) {\r
- return true;\r
- }\r
-\r
- $r = dba::insert('hook', ['hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority]);\r
-\r
- return $r;\r
- }\r
-\r
- /**\r
- * @brief unregisters a hook.\r
- *\r
- * @param string $hook the name of the hook\r
- * @param string $file the name of the file that hooks into\r
- * @param string $function the name of the function that the hook called\r
- * @return array\r
- */\r
- public static function unregisterHook($hook, $file, $function)\r
- {\r
- $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];\r
- $r = dba::delete('hook', $condition);\r
- return $r;\r
- }\r
-\r
- /**\r
- * Load hooks\r
- */\r
- public static function loadHooks()\r
- {\r
- $a = get_app();\r
- $a->hooks = [];\r
- $r = dba::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]);\r
-\r
- while ($rr = dba::fetch($r)) {\r
- if (! array_key_exists($rr['hook'], $a->hooks)) {\r
- $a->hooks[$rr['hook']] = [];\r
- }\r
- $a->hooks[$rr['hook']][] = [$rr['file'],$rr['function']];\r
- }\r
- dba::close($r);\r
- }\r
-\r
- /**\r
- * @brief Calls a hook.\r
- *\r
- * Use this function when you want to be able to allow a hook to manipulate\r
- * the provided data.\r
- *\r
- * @param string $name of the hook to call\r
- * @param string|array &$data to transmit to the callback handler\r
- */\r
- public static function callHooks($name, &$data = null)\r
- {\r
- $a = get_app();\r
-\r
- if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {\r
- foreach ($a->hooks[$name] as $hook) {\r
- self::callSingleHook($a, $name, $hook, $data);\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * @brief Calls a single hook.\r
- *\r
- * @param string $name of the hook to call\r
- * @param array $hook Hook data\r
- * @param string|array &$data to transmit to the callback handler\r
- */\r
- public static function callSingleHook($a, $name, $hook, &$data = null)\r
- {\r
- // Don't run a theme's hook if the user isn't using the theme\r
- if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false) {\r
- return;\r
- }\r
-\r
- @include_once($hook[0]);\r
- if (function_exists($hook[1])) {\r
- $func = $hook[1];\r
- $func($a, $data);\r
- } else {\r
- // remove orphan hooks\r
- $condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];\r
- dba::delete('hook', $condition);\r
- }\r
- }\r
-\r
- /**\r
- * check if an app_menu hook exist for addon $name.\r
- * Return true if the addon is an app\r
- */\r
- public static function isApp($name)\r
- {\r
- $a = get_app();\r
-\r
- if (is_array($a->hooks) && (array_key_exists('app_menu', $a->hooks))) {\r
- foreach ($a->hooks['app_menu'] as $hook) {\r
- if ($hook[0] == 'addon/'.$name.'/'.$name.'.php') {\r
- return true;\r
- }\r
- }\r
- }\r
-\r
- return false;\r
- }\r
-\r
- /**\r
- * @brief Parse addon comment in search of addon infos.\r
- *\r
- * like\r
- * \code\r
- * * Name: addon\r
- * * Description: An addon which plugs in\r
- * . * Version: 1.2.3\r
- * * Author: John <profile url>\r
- * * Author: Jane <email>\r
- * * Maintainer: Jess <email>\r
- * *\r
- * *\endcode\r
- * @param string $addon the name of the addon\r
- * @return array with the addon information\r
- */\r
- public static function getInfo($addon)\r
- {\r
- $a = get_app();\r
-\r
- $info = [\r
- 'name' => $addon,\r
- 'description' => "",\r
- 'author' => [],\r
- 'maintainer' => [],\r
- 'version' => "",\r
- 'status' => ""\r
- ];\r
-\r
- if (!is_file("addon/$addon/$addon.php")) {\r
- return $info;\r
- }\r
-\r
- $stamp1 = microtime(true);\r
- $f = file_get_contents("addon/$addon/$addon.php");\r
- $a->save_timestamp($stamp1, "file");\r
-\r
- $r = preg_match("|/\*.*\*/|msU", $f, $m);\r
-\r
- if ($r) {\r
- $ll = explode("\n", $m[0]);\r
- foreach ($ll as $l) {\r
- $l = trim($l, "\t\n\r */");\r
- if ($l != "") {\r
- list($type, $v) = array_map("trim", explode(":", $l, 2));\r
- $type = strtolower($type);\r
- if ($type == "author" || $type == "maintainer") {\r
- $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);\r
- if ($r) {\r
- $info[$type][] = ['name' => $m[1], 'link' => $m[2]];\r
- } else {\r
- $info[$type][] = ['name' => $v];\r
- }\r
- } else {\r
- if (array_key_exists($type, $info)) {\r
- $info[$type] = $v;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- return $info;\r
- }\r
-}\r
+<?php
+/**
+ * @file src/Core/Addon.php
+ */
+namespace Friendica\Core;
+
+use Friendica\Core\Config;
+use Friendica\Database\DBM;
+use Friendica\Core\Worker;
+
+use dba;
+
+require_once 'include/dba.php';
+
+/**
+ * Some functions to handle addons
+ */
+class Addon
+{
+ /**
+ * @brief uninstalls an addon.
+ *
+ * @param string $addon name of the addon
+ * @return boolean
+ */
+ public static function uninstall($addon)
+ {
+ logger("Addons: uninstalling " . $addon);
+ dba::delete('addon', ['name' => $addon]);
+
+ @include_once('addon/' . $addon . '/' . $addon . '.php');
+ if (function_exists($addon . '_uninstall')) {
+ $func = $addon . '_uninstall';
+ $func();
+ }
+ }
+
+ /**
+ * @brief installs an addon.
+ *
+ * @param string $addon name of the addon
+ * @return bool
+ */
+ public static function install($addon)
+ {
+ // silently fail if addon was removed
+
+ if (!file_exists('addon/' . $addon . '/' . $addon . '.php')) {
+ return false;
+ }
+ logger("Addons: installing " . $addon);
+ $t = @filemtime('addon/' . $addon . '/' . $addon . '.php');
+ @include_once('addon/' . $addon . '/' . $addon . '.php');
+ if (function_exists($addon . '_install')) {
+ $func = $addon . '_install';
+ $func();
+
+ $addon_admin = (function_exists($addon."_addon_admin") ? 1 : 0);
+
+ dba::insert('addon', ['name' => $addon, 'installed' => true,
+ 'timestamp' => $t, 'plugin_admin' => $addon_admin]);
+
+ // we can add the following with the previous SQL
+ // once most site tables have been updated.
+ // This way the system won't fall over dead during the update.
+
+ if (file_exists('addon/' . $addon . '/.hidden')) {
+ dba::update('addon', ['hidden' => true], ['name' => $addon]);
+ }
+ return true;
+ } else {
+ logger("Addons: FAILED installing " . $addon);
+ return false;
+ }
+ }
+
+ /**
+ * reload all updated addons
+ */
+ public static function reload()
+ {
+ $addons = Config::get('system', 'addon');
+ if (strlen($addons)) {
+ $r = dba::select('addon', [], ['installed' => 1]);
+ if (DBM::is_result($r)) {
+ $installed = dba::inArray($r);
+ } else {
+ $installed = [];
+ }
+
+ $addon_list = explode(',', $addons);
+
+ if (count($addon_list)) {
+ foreach ($addon_list as $addon) {
+ $addon = trim($addon);
+ $fname = 'addon/' . $addon . '/' . $addon . '.php';
+
+ if (file_exists($fname)) {
+ $t = @filemtime($fname);
+ foreach ($installed as $i) {
+ if (($i['name'] == $addon) && ($i['timestamp'] != $t)) {
+ logger('Reloading addon: ' . $i['name']);
+ @include_once($fname);
+
+ if (function_exists($addon . '_uninstall')) {
+ $func = $addon . '_uninstall';
+ $func();
+ }
+ if (function_exists($addon . '_install')) {
+ $func = $addon . '_install';
+ $func();
+ }
+ dba::update('addon', ['timestamp' => $t], ['id' => $i['id']]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @brief check if addon is enabled
+ *
+ * @param string $addon
+ * @return boolean
+ */
+ public static function isEnabled($addon)
+ {
+ return dba::exists('addon', ['installed' => true, 'name' => $addon]);
+ }
+
+
+ /**
+ * @brief registers a hook.
+ *
+ * @param string $hook the name of the hook
+ * @param string $file the name of the file that hooks into
+ * @param string $function the name of the function that the hook will call
+ * @param int $priority A priority (defaults to 0)
+ * @return mixed|bool
+ */
+ public static function registerHook($hook, $file, $function, $priority = 0)
+ {
+ $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
+ $exists = dba::exists('hook', $condition);
+ if ($exists) {
+ return true;
+ }
+
+ $r = dba::insert('hook', ['hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority]);
+
+ return $r;
+ }
+
+ /**
+ * @brief unregisters a hook.
+ *
+ * @param string $hook the name of the hook
+ * @param string $file the name of the file that hooks into
+ * @param string $function the name of the function that the hook called
+ * @return array
+ */
+ public static function unregisterHook($hook, $file, $function)
+ {
+ $condition = ['hook' => $hook, 'file' => $file, 'function' => $function];
+ $r = dba::delete('hook', $condition);
+ return $r;
+ }
+
+ /**
+ * Load hooks
+ */
+ public static function loadHooks()
+ {
+ $a = get_app();
+ $a->hooks = [];
+ $r = dba::select('hook', ['hook', 'file', 'function'], [], ['order' => ['priority' => 'desc', 'file']]);
+
+ while ($rr = dba::fetch($r)) {
+ if (! array_key_exists($rr['hook'], $a->hooks)) {
+ $a->hooks[$rr['hook']] = [];
+ }
+ $a->hooks[$rr['hook']][] = [$rr['file'],$rr['function']];
+ }
+ dba::close($r);
+ }
+
+ /**
+ * @brief Forks a hook.
+ *
+ * Use this function when you want to fork a hook via the worker.
+ *
+ * @param string $name of the hook to call
+ * @param string|array $data to transmit to the callback handler
+ */
+ public static function forkHooks($priority, $name, $data = null)
+ {
+ $a = get_app();
+
+ if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {
+ foreach ($a->hooks[$name] as $hook) {
+ Worker::add($priority, 'ForkHook', $name, json_encode($hook), json_encode($data));
+ }
+ }
+ }
+
+ /**
+ * @brief Calls a hook.
+ *
+ * Use this function when you want to be able to allow a hook to manipulate
+ * the provided data.
+ *
+ * @param string $name of the hook to call
+ * @param string|array &$data to transmit to the callback handler
+ */
+ public static function callHooks($name, &$data = null)
+ {
+ $a = get_app();
+
+ if (is_array($a->hooks) && array_key_exists($name, $a->hooks)) {
+ foreach ($a->hooks[$name] as $hook) {
+ self::callSingleHook($a, $name, $hook, $data);
+ }
+ }
+ }
+
+ /**
+ * @brief Calls a single hook.
+ *
+ * @param string $name of the hook to call
+ * @param array $hook Hook data
+ * @param string|array &$data to transmit to the callback handler
+ */
+ public static function callSingleHook($a, $name, $hook, &$data = null)
+ {
+ // Don't run a theme's hook if the user isn't using the theme
+ if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false) {
+ return;
+ }
+
+ @include_once($hook[0]);
+ if (function_exists($hook[1])) {
+ $func = $hook[1];
+ $func($a, $data);
+ } else {
+ // remove orphan hooks
+ $condition = ['hook' => $name, 'file' => $hook[0], 'function' => $hook[1]];
+ dba::delete('hook', $condition);
+ }
+ }
+
+ /**
+ * check if an app_menu hook exist for addon $name.
+ * Return true if the addon is an app
+ */
+ public static function isApp($name)
+ {
+ $a = get_app();
+
+ if (is_array($a->hooks) && (array_key_exists('app_menu', $a->hooks))) {
+ foreach ($a->hooks['app_menu'] as $hook) {
+ if ($hook[0] == 'addon/'.$name.'/'.$name.'.php') {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief Parse addon comment in search of addon infos.
+ *
+ * like
+ * \code
+ * * Name: addon
+ * * Description: An addon which plugs in
+ * . * Version: 1.2.3
+ * * Author: John <profile url>
+ * * Author: Jane <email>
+ * * Maintainer: Jess <email>
+ * *
+ * *\endcode
+ * @param string $addon the name of the addon
+ * @return array with the addon information
+ */
+ public static function getInfo($addon)
+ {
+ $a = get_app();
+
+ $info = [
+ 'name' => $addon,
+ 'description' => "",
+ 'author' => [],
+ 'maintainer' => [],
+ 'version' => "",
+ 'status' => ""
+ ];
+
+ if (!is_file("addon/$addon/$addon.php")) {
+ return $info;
+ }
+
+ $stamp1 = microtime(true);
+ $f = file_get_contents("addon/$addon/$addon.php");
+ $a->save_timestamp($stamp1, "file");
+
+ $r = preg_match("|/\*.*\*/|msU", $f, $m);
+
+ if ($r) {
+ $ll = explode("\n", $m[0]);
+ foreach ($ll as $l) {
+ $l = trim($l, "\t\n\r */");
+ if ($l != "") {
+ list($type, $v) = array_map("trim", explode(":", $l, 2));
+ $type = strtolower($type);
+ if ($type == "author" || $type == "maintainer") {
+ $r = preg_match("|([^<]+)<([^>]+)>|", $v, $m);
+ if ($r) {
+ $info[$type][] = ['name' => $m[1], 'link' => $m[2]];
+ } else {
+ $info[$type][] = ['name' => $v];
+ }
+ } else {
+ if (array_key_exists($type, $info)) {
+ $info[$type] = $v;
+ }
+ }
+ }
+ }
+ }
+ return $info;
+ }
+}
// Run the cron job that calls all other jobs
self::add(PRIORITY_MEDIUM, "Cron");
- // Run the cronhooks job separately from cron for being able to use a different timing
- self::add(PRIORITY_MEDIUM, "CronHooks");
-
// Cleaning dead processes
self::killStaleWorkers();
}
"comment" => "Background tasks queue entries",
"fields" => [
"id" => ["type" => "int", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "Auto incremented worker task id"],
- "parameter" => ["type" => "text", "comment" => "Task command"],
+ "parameter" => ["type" => "mediumtext", "comment" => "Task command"],
"priority" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Task priority"],
"created" => ["type" => "datetime", "not null" => "1", "default" => NULL_DATE, "comment" => "Creation date"],
"pid" => ["type" => "int", "not null" => "1", "default" => "0", "comment" => "Process id of the worker"],
use Text_LanguageDetect;
require_once 'boot.php';
-require_once 'include/tags.php';
-require_once 'include/threads.php';
require_once 'include/items.php';
require_once 'include/text.php';
+require_once 'include/event.php';
class Item extends BaseObject
{
continue;
}
- create_tags_from_item($item['id']);
- Term::createFromItem($item['id']);
- update_thread($item['id']);
+ Term::insertFromTagFieldByItemId($item['id']);
+ Term::insertFromFileFieldByItemId($item['id']);
+ self::updateThread($item['id']);
Worker::add(PRIORITY_HIGH, "Notifier", 'edit_post', $item['id']);
}
return $rows;
}
+ /**
+ * @brief Delete an item and notify others about it - if it was ours
+ *
+ * @param array $condition The condition for finding the item entries
+ * @param integer $priority Priority for the notification
+ */
+ public static function delete($condition, $priority = PRIORITY_HIGH)
+ {
+ $items = dba::select('item', ['id'], $condition);
+ while ($item = dba::fetch($items)) {
+ self::deleteById($item['id'], $priority);
+ }
+ dba::close($items);
+ }
+
/**
* @brief Delete an item and notify others about it - if it was ours
*
* @param integer $item_id Item ID that should be delete
+ * @param integer $priority Priority for the notification
*
* @return $boolean success
*/
- public static function delete($item_id, $priority = PRIORITY_HIGH)
+ public static function deleteById($item_id, $priority = PRIORITY_HIGH)
{
// locate item to be deleted
- $fields = ['id', 'uid', 'parent', 'parent-uri', 'origin', 'deleted', 'file', 'resource-id', 'event-id', 'attach'];
+ $fields = ['id', 'uid', 'parent', 'parent-uri', 'origin', 'deleted',
+ 'file', 'resource-id', 'event-id', 'attach',
+ 'verb', 'object-type', 'object', 'target', 'contact-id'];
$item = dba::selectFirst('item', $fields, ['id' => $item_id]);
if (!DBM::is_result($item)) {
return false;
dba::delete('photo', ['resource-id' => $item['resource-id'], 'uid' => $item['uid']]);
}
- // If item is a link to an event, nuke the event record.
+ // If item is a link to an event, delete the event.
if (intval($item['event-id'])) {
- dba::delete('event', ['id' => $item['event-id'], 'uid' => $item['uid']]);
+ event_delete($item['event-id']);
}
// If item has attachments, drop them
dba::delete('attach', ['id' => $matches[1], 'uid' => $item['uid']]);
}
+ // Delete tags that had been attached to other items
+ self::deleteTagsFromItem($item);
+
// Set the item to "deleted"
dba::update('item', ['deleted' => true, 'title' => '', 'body' => '',
'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()],
['id' => $item['id']]);
- create_tags_from_item($item['id']);
- Term::createFromItem($item['id']);
- delete_thread($item['id'], $item['parent-uri']);
+ Term::insertFromTagFieldByItemId($item['id']);
+ Term::insertFromFileFieldByItemId($item['id']);
+ self::deleteThread($item['id'], $item['parent-uri']);
// If it's the parent of a comment thread, kill all the kids
if ($item['id'] == $item['parent']) {
- $items = dba::select('item', ['id'], ['parent' => $item['parent']]);
- while ($row = dba::fetch($items)) {
- self::delete($row['id'], $priority);
- }
+ self::delete(['parent' => $item['parent']], $priority);
}
// send the notification upstream/downstream
return true;
}
+ private static function deleteTagsFromItem($item)
+ {
+ if (($item["verb"] != ACTIVITY_TAG) || ($item["object-type"] != ACTIVITY_OBJ_TAGTERM)) {
+ return;
+ }
+
+ $xo = XML::parseString($item["object"], false);
+ $xt = XML::parseString($item["target"], false);
+
+ if ($xt->type != ACTIVITY_OBJ_NOTE) {
+ return;
+ }
+
+ $i = dba::selectFirst('item', ['id', 'contact-id', 'tag'], ['uri' => $xt->id, 'uid' => $item['uid']]);
+ if (!DBM::is_result($i)) {
+ return;
+ }
+
+ // For tags, the owner cannot remove the tag on the author's copy of the post.
+ $owner_remove = ($item["contact-id"] == $i["contact-id"]);
+ $author_copy = $item["origin"];
+
+ if (($owner_remove && $author_copy) || !$owner_remove) {
+ return;
+ }
+
+ $tags = explode(',', $i["tag"]);
+ $newtags = [];
+ if (count($tags)) {
+ foreach ($tags as $tag) {
+ if (trim($tag) !== trim($xo->body)) {
+ $newtags[] = trim($tag);
+ }
+ }
+ }
+ self::update(['tag' => implode(',', $newtags)], ['id' => $i["id"]]);
+ }
+
public static function insert($arr, $force_parent = false, $notify = false, $dontcache = false)
{
$a = get_app();
}
if ($arr['parent-uri'] === $arr['uri']) {
- add_thread($current_post);
+ self::addThread($current_post);
} else {
- update_thread($parent_id);
+ self::updateThread($parent_id);
}
dba::commit();
* Due to deadlock issues with the "term" table we are doing these steps after the commit.
* This is not perfect - but a workable solution until we found the reason for the problem.
*/
- create_tags_from_item($current_post);
- Term::createFromItem($current_post);
+ Term::insertFromTagFieldByItemId($current_post);
+ Term::insertFromFileFieldByItemId($current_post);
if ($arr['parent-uri'] === $arr['uri']) {
self::addShadow($current_post);
dbesc($u[0]['deny_gid']),
intval($item_id)
);
- update_thread($item_id);
+ self::updateThread($item_id);
Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], 'Notifier', 'tgroup', $item_id);
continue;
}
- self::delete($item['id'], PRIORITY_LOW);
+ self::deleteById($item['id'], PRIORITY_LOW);
}
}
'unseen' => 1,
];
- $new_item_id = Item::insert($new_item);
+ $new_item_id = self::insert($new_item);
- // @todo: Explain this block
- if (! $item['visible']) {
- q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
- intval($item['id'])
- );
+ // If the parent item isn't visible then set it to visible
+ if (!$item['visible']) {
+ self::update(['visible' => true], ['id' => $item['id']]);
}
// Save the author information for the like in case we need to relay to Diaspora
return true;
}
+
+ private static function addThread($itemid, $onlyshadow = false)
+ {
+ $items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
+ `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
+ `deleted`, `origin`, `forum_mode`, `mention`, `network`, `author-id`, `owner-id`
+ FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
+
+ if (!$items) {
+ return;
+ }
+
+ $item = $items[0];
+ $item['iid'] = $itemid;
+
+ if (!$onlyshadow) {
+ $result = dba::insert('thread', $item);
+
+ logger("Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
+ }
+ }
+
+ private static function updateThread($itemid, $setmention = false)
+ {
+ $items = q("SELECT `uid`, `guid`, `title`, `body`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
+ `deleted`, `origin`, `forum_mode`, `network`, `rendered-html`, `rendered-hash` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
+
+ if (!DBM::is_result($items)) {
+ return;
+ }
+
+ $item = $items[0];
+
+ if ($setmention) {
+ $item["mention"] = 1;
+ }
+
+ $sql = "";
+
+ foreach ($item as $field => $data)
+ if (!in_array($field, ["guid", "title", "body", "rendered-html", "rendered-hash"])) {
+ if ($sql != "") {
+ $sql .= ", ";
+ }
+
+ $sql .= "`".$field."` = '".dbesc($data)."'";
+ }
+
+ $result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
+
+ logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
+
+ // Updating a shadow item entry
+ $items = dba::selectFirst('item', ['id'], ['guid' => $item['guid'], 'uid' => 0]);
+
+ if (!DBM::is_result($items)) {
+ return;
+ }
+
+ $result = dba::update(
+ 'item',
+ ['title' => $item['title'], 'body' => $item['body'], 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']],
+ ['id' => $items['id']]
+ );
+
+ logger("Updating public shadow for post ".$items["id"]." - guid ".$item["guid"]." Result: ".print_r($result, true), LOGGER_DEBUG);
+ }
+
+ private static function deleteThread($itemid, $itemuri = "")
+ {
+ $item = dba::selectFirst('thread', ['uid'], ['iid' => $itemid]);
+ if (!DBM::is_result($item)) {
+ logger('No thread found for id '.$itemid, LOGGER_DEBUG);
+ return;
+ }
+
+ // Using dba::delete at this time could delete the associated item entries
+ $result = dba::e("DELETE FROM `thread` WHERE `iid` = ?", $itemid);
+
+ logger("deleteThread: Deleted thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
+
+ if ($itemuri != "") {
+ $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND NOT `deleted` AND NOT (`uid` IN (%d, 0))",
+ dbesc($itemuri),
+ intval($item["uid"])
+ );
+ if (!DBM::is_result($r)) {
+ dba::delete('item', ['uri' => $itemuri, 'uid' => 0]);
+ logger("deleteThread: Deleted shadow for item ".$itemuri, LOGGER_DEBUG);
+ }
+ }
+ }
}
*/
namespace Friendica\Model;
+use Friendica\Core\System;
+use Friendica\Database\DBM;
use dba;
-require_once "include/dba.php";
+require_once 'boot.php';
+require_once 'include/dba.php';
class Term
{
+ public static function insertFromTagFieldByItemId($itemid)
+ {
+ $profile_base = System::baseUrl();
+ $profile_data = parse_url($profile_base);
+ $profile_path = defaults($profile_data, 'path', '');
+ $profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/';
+ $profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/';
+
+ $fields = ['guid', 'uid', 'id', 'edited', 'deleted', 'created', 'received', 'title', 'body', 'tag', 'parent'];
+ $message = dba::selectFirst('item', $fields, ['id' => $itemid]);
+ if (!DBM::is_result($message)) {
+ return;
+ }
+
+ // Clean up all tags
+ dba::e("DELETE FROM `term` WHERE `otype` = ? AND `oid` = ? AND `type` IN (?, ?)",
+ TERM_OBJ_POST, $itemid, TERM_HASHTAG, TERM_MENTION);
+
+ if ($message['deleted']) {
+ return;
+ }
+
+ $taglist = explode(',', $message['tag']);
+
+ $tags_string = '';
+ foreach ($taglist as $tag) {
+ if ((substr(trim($tag), 0, 1) == '#') || (substr(trim($tag), 0, 1) == '@')) {
+ $tags_string .= ' ' . trim($tag);
+ } else {
+ $tags_string .= ' #' . trim($tag);
+ }
+ }
+
+ $data = ' ' . $message['title'] . ' ' . $message['body'] . ' ' . $tags_string . ' ';
+
+ // ignore anything in a code block
+ $data = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $data);
+
+ $tags = [];
+
+ $pattern = '/\W\#([^\[].*?)[\s\'".,:;\?!\[\]\/]/ism';
+ if (preg_match_all($pattern, $data, $matches)) {
+ foreach ($matches[1] as $match) {
+ $tags['#' . strtolower($match)] = '';
+ }
+ }
+
+ $pattern = '/\W([\#@])\[url\=(.*?)\](.*?)\[\/url\]/ism';
+ if (preg_match_all($pattern, $data, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $tags[$match[1] . strtolower(trim($match[3], ',.:;[]/\"?!'))] = $match[2];
+ }
+ }
+
+ foreach ($tags as $tag => $link) {
+ if (substr(trim($tag), 0, 1) == '#') {
+ // try to ignore #039 or #1 or anything like that
+ if (ctype_digit(substr(trim($tag), 1))) {
+ continue;
+ }
+
+ // try to ignore html hex escapes, e.g. #x2317
+ if ((substr(trim($tag), 1, 1) == 'x' || substr(trim($tag), 1, 1) == 'X') && ctype_digit(substr(trim($tag), 2))) {
+ continue;
+ }
+
+ $type = TERM_HASHTAG;
+ $term = substr($tag, 1);
+ } elseif (substr(trim($tag), 0, 1) == '@') {
+ $type = TERM_MENTION;
+ $term = substr($tag, 1);
+ } else { // This shouldn't happen
+ $type = TERM_HASHTAG;
+ $term = $tag;
+ }
+
+ if ($message['uid'] == 0) {
+ $global = true;
+ dba::update('term', ['global' => true], ['otype' => TERM_OBJ_POST, 'guid' => $message['guid']]);
+ } else {
+ $global = dba::exists('term', ['uid' => 0, 'otype' => TERM_OBJ_POST, 'guid' => $message['guid']]);
+ }
+
+ dba::insert('term', [
+ 'uid' => $message['uid'],
+ 'oid' => $itemid,
+ 'otype' => TERM_OBJ_POST,
+ 'type' => $type,
+ 'term' => $term,
+ 'url' => $link,
+ 'guid' => $message['guid'],
+ 'created' => $message['created'],
+ 'received' => $message['received'],
+ 'global' => $global
+ ]);
+
+ // Search for mentions
+ if ((substr($tag, 0, 1) == '@') && (strpos($link, $profile_base_friendica) || strpos($link, $profile_base_diaspora))) {
+ $users = q("SELECT `uid` FROM `contact` WHERE self AND (`url` = '%s' OR `nurl` = '%s')", $link, $link);
+ foreach ($users AS $user) {
+ if ($user['uid'] == $message['uid']) {
+ dba::update('item', ['mention' => true], ['id' => $itemid]);
+ dba::update('thread', ['mention' => true], ['iid' => $message['parent']]);
+ }
+ }
+ }
+ }
+ }
+
/**
* @param integer $itemid item id
* @return void
*/
- public static function createFromItem($itemid)
+ public static function insertFromFileFieldByItemId($itemid)
{
$message = dba::selectFirst('item', ['uid', 'deleted', 'file'], ['id' => $itemid]);
- if (!\Friendica\Database\DBM::is_result($message)) {
+ if (!DBM::is_result($message)) {
return;
}
}
}
}
-
- /**
- * @param string $itemuri item uri
- * @param integer $uid uid
- * @return void
- */
- public static function createFromItemURI($itemuri, $uid)
- {
- $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
-
- if (count($messages)) {
- foreach ($messages as $message) {
- self::createFromItem($message["id"]);
- }
- }
- }
}
}
}
+ if (substr($webfinger["subject"], 0, 5) == "acct:") {
+ $data["addr"] = substr($webfinger["subject"], 5);
+ }
+
if (!isset($data["network"]) || ($hcard_url == "")) {
return false;
}
require_once 'boot.php';
require_once 'include/dba.php';
require_once "include/enotify.php";
-require_once "include/threads.php";
require_once "include/items.php";
-require_once "include/tags.php";
require_once "include/event.php";
require_once "include/text.php";
require_once "include/html2bbcode.php";
'edited' => DateTimeFormat::utc($item["edited"])];
$condition = ["`uri` = ? AND `uid` IN (0, ?)", $item["uri"], $importer["importer_uid"]];
- dba::update('item', $fields, $condition);
-
- create_tags_from_itemuri($item["uri"], $importer["importer_uid"]);
- update_thread_uri($item["uri"], $importer["importer_uid"]);
+ Item::update($fields, $condition);
$changed = true;
// extract tag, if not duplicate, add to parent item
if ($xo->content) {
- if (!(stristr($r[0]["tag"], trim($xo->content)))) {
- q(
- "UPDATE `item` SET `tag` = '%s' WHERE `id` = %d",
- dbesc($r[0]["tag"] . (strlen($r[0]["tag"]) ? ',' : '') . '#[url=' . $xo->id . ']'. $xo->content . '[/url]'),
- intval($r[0]["id"])
- );
- create_tags_from_item($r[0]["id"]);
+ if (!stristr($r[0]["tag"], trim($xo->content))) {
+ $tag = $r[0]["tag"] . (strlen($r[0]["tag"]) ? ',' : '') . '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
+ Item::update(['tag' => $tag], ['id' => $r[0]["id"]]);
}
}
}
if ($attributes->name == "ref") {
$uri = $attributes->textContent;
}
- if ($attributes->name == "when") {
- $when = $attributes->textContent;
- }
- }
- if ($when) {
- $when = DateTimeFormat::utc($when);
- } else {
- $when = DateTimeFormat::utcNow();
}
if (!$uri || !$importer["id"]) {
return false;
}
- /// @todo Only select the used fields
- $r = q(
- "SELECT `item`.*, `contact`.`self` FROM `item` INNER JOIN `contact` on `item`.`contact-id` = `contact`.`id`
- WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
- dbesc($uri),
- intval($importer["uid"]),
- intval($importer["id"])
- );
- if (!DBM::is_result($r)) {
+ $condition = ["`uri` = ? AND `uid` = ? AND `contact-id` = ? AND NOT `file` LIKE '%[%'",
+ $uri, $importer["uid"], $importer["id"]];
+ $item = dba::selectFirst('item', ['id'], $condition);
+ if (!DBM::is_result($item)) {
logger("Item with uri " . $uri . " from contact " . $importer["id"] . " for user " . $importer["uid"] . " wasn't found.", LOGGER_DEBUG);
return;
- } else {
- $item = $r[0];
-
- $entrytype = self::getEntryType($importer, $item);
-
- if (!$item["deleted"]) {
- logger('deleting item '.$item["id"].' uri='.$uri, LOGGER_DEBUG);
- } else {
- return;
- }
-
- if ($item["object-type"] == ACTIVITY_OBJ_EVENT) {
- logger("Deleting event ".$item["event-id"], LOGGER_DEBUG);
- event_delete($item["event-id"]);
- }
-
- if (($item["verb"] == ACTIVITY_TAG) && ($item["object-type"] == ACTIVITY_OBJ_TAGTERM)) {
- $xo = XML::parseString($item["object"], false);
- $xt = XML::parseString($item["target"], false);
-
- if ($xt->type == ACTIVITY_OBJ_NOTE) {
- $i = q(
- "SELECT `id`, `contact-id`, `tag` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($xt->id),
- intval($importer["importer_uid"])
- );
- if (DBM::is_result($i)) {
- // For tags, the owner cannot remove the tag on the author's copy of the post.
-
- $owner_remove = (($item["contact-id"] == $i[0]["contact-id"]) ? true: false);
- $author_remove = (($item["origin"] && $item["self"]) ? true : false);
- $author_copy = (($item["origin"]) ? true : false);
+ }
- if ($owner_remove && $author_copy) {
- return;
- }
- if ($author_remove || $owner_remove) {
- $tags = explode(',', $i[0]["tag"]);
- $newtags = [];
- if (count($tags)) {
- foreach ($tags as $tag) {
- if (trim($tag) !== trim($xo->body)) {
- $newtags[] = trim($tag);
- }
- }
- }
- q(
- "UPDATE `item` SET `tag` = '%s' WHERE `id` = %d",
- dbesc(implode(',', $newtags)),
- intval($i[0]["id"])
- );
- create_tags_from_item($i[0]["id"]);
- }
- }
- }
- }
+ $entrytype = self::getEntryType($importer, $item);
- if ($entrytype == DFRN_TOP_LEVEL) {
- $r = q(
- "UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `parent-uri` = '%s' AND `uid` IN (0, %d)",
- dbesc($when),
- dbesc(DateTimeFormat::utcNow()),
- dbesc($uri),
- intval($importer["uid"])
- );
- create_tags_from_itemuri($uri, $importer["uid"]);
- Term::createFromItemURI($uri, $importer["uid"]);
- update_thread_uri($uri, $importer["uid"]);
- } else {
- $r = q(
- "UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `uri` = '%s' AND `uid` IN (0, %d)",
- dbesc($when),
- dbesc(DateTimeFormat::utcNow()),
- dbesc($uri),
- intval($importer["uid"])
- );
- create_tags_from_itemuri($uri, $importer["uid"]);
- Term::createFromItemURI($uri, $importer["uid"]);
- update_thread_uri($uri, $importer["importer_uid"]);
+ if (!$item["deleted"]) {
+ logger('deleting item '.$item["id"].' uri='.$uri, LOGGER_DEBUG);
+ } else {
+ return;
+ }
- // if this is a relayed delete, propagate it to other recipients
+ Item::deleteById($item["id"]);
- if ($entrytype == DFRN_REPLY_RC) {
- logger("Notifying followers about deletion of post " . $item["id"], LOGGER_DEBUG);
- Worker::add(PRIORITY_HIGH, "Notifier", "drop", $item["id"]);
- }
+ if ($entrytype != DFRN_TOP_LEVEL) {
+ // if this is a relayed delete, propagate it to other recipients
+ if ($entrytype == DFRN_REPLY_RC) {
+ logger("Notifying followers about deletion of post " . $item["id"], LOGGER_DEBUG);
+ Worker::add(PRIORITY_HIGH, "Notifier", "drop", $item["id"]);
}
}
}
continue;
}
- // Currently we don't have a central deletion function that we could use in this case.
- // The function "item_drop" doesn't work for that case
- dba::update(
- 'item',
- [
- 'deleted' => true,
- 'title' => '',
- 'body' => '',
- 'edited' => DateTimeFormat::utcNow(),
- 'changed' => DateTimeFormat::utcNow()],
- ['id' => $item["id"]]
- );
-
- // Delete the thread - if it is a starting post and not a comment
- if ($target_type != 'Comment') {
- delete_thread($item["id"], $item["parent-uri"]);
- }
+ Item::deleteById($item["id"]);
logger("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item["parent"], LOGGER_DEBUG);
use DOMXPath;
require_once 'include/dba.php';
-require_once 'include/threads.php';
require_once 'include/html2bbcode.php';
require_once 'include/bbcode.php';
require_once 'include/items.php';
return;
}
- // Currently we don't have a central deletion function that we could use in this case
- // The function "item_drop" doesn't work for that case
- dba::update(
- 'item',
- ['deleted' => true, 'title' => '', 'body' => '',
- 'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()],
- ['id' => $deleted["id"]]
- );
-
- delete_thread($deleted["id"], $deleted["parent-uri"]);
+ Item::deleteById($deleted["id"]);
logger('Deleted item with uri '.$item['uri'].' for user '.$item['uid']);
}
logger('cron: start');
+ // Fork the cron jobs in separate parts to avoid problems when one of them is crashing
+ Addon::forkHooks($a->queue['priority'], "cron");
+
// run queue delivery process in the background
Worker::add(PRIORITY_NEGLIGIBLE, "Queue");
+++ /dev/null
-<?php
-/**
- * @file src/Worker/CronHooks.php
- */
-
-namespace Friendica\Worker;
-
-use Friendica\Core\Addon;
-use Friendica\Core\Config;
-use Friendica\Core\Worker;
-use Friendica\Util\DateTimeFormat;
-
-Class CronHooks {
- public static function execute($hook = '') {
- global $a;
-
- if (($hook != '') && is_array($a->hooks) && array_key_exists("cron", $a->hooks)) {
- foreach ($a->hooks["cron"] as $single_hook) {
- if ($single_hook[1] == $hook) {
- logger("Calling cron hook '" . $hook . "'", LOGGER_DEBUG);
- Addon::callSingleHook($a, $hook, $single_hook);
- }
- }
- return;
- }
-
- $last = Config::get('system', 'last_cronhook');
-
- $poll_interval = intval(Config::get('system', 'cronhook_interval'));
- if (!$poll_interval) {
- $poll_interval = 9;
- }
-
- if ($last) {
- $next = $last + ($poll_interval * 60);
- if ($next > time()) {
- logger('cronhook intervall not reached');
- return;
- }
- }
-
- $a->set_baseurl(Config::get('system', 'url'));
-
- logger('cronhooks: start');
-
- $d = DateTimeFormat::utcNow();
-
- if (is_array($a->hooks) && array_key_exists("cron", $a->hooks)) {
- foreach ($a->hooks["cron"] as $hook) {
- logger("Calling cronhooks for '" . $hook[1] . "'", LOGGER_DEBUG);
- Worker::add(PRIORITY_MEDIUM, "CronHooks", $hook[1]);
- }
- }
-
- logger('cronhooks: end');
-
- Config::set('system', 'last_cronhook', time());
-
- return;
- }
-}
--- /dev/null
+<?php
+/**
+ * @file src/Worker/ForkHook.php
+ */
+
+namespace Friendica\Worker;
+
+use Friendica\Core\Addon;
+
+Class ForkHook {
+ public static function execute($name, $hook_json, $data_json) {
+ global $a;
+
+ $hook = json_decode($hook_json, true);
+ $data = json_decode($data_json, true);
+
+ Addon::callSingleHook($a, $name, $hook, $data);
+ }
+}
logger('notifier: calling hooks', LOGGER_DEBUG);
if ($normal_mode) {
- Addon::callHooks('notifier_normal',$target_item);
+ Addon::forkHooks($a->queue['priority'], 'notifier_normal', $target_item);
}
Addon::callHooks('notifier_end',$target_item);
if (($mailconf['action'] != 1) && ($mailconf['action'] != 3))
if ($meta->deleted && ! $item['deleted']) {
$fields = ['deleted' => true, 'changed' => DateTimeFormat::utcNow()];
- dba::update('item', $fields, ['id' => $item['id']]);
+ Item::update($fields, ['id' => $item['id']]);
}
switch ($mailconf['action']) {
<?php
+
namespace Friendica\Worker;
-require_once("include/tags.php");
+class TagUpdate
+{
+ public static function execute()
+ {
+ $messages = dba::p("SELECT `oid`,`item`.`guid`, `item`.`created`, `item`.`received` FROM `term` INNER JOIN `item` ON `item`.`id`=`term`.`oid` WHERE `term`.`otype` = 1 AND `term`.`guid` = ''");
+
+ logger('fetched messages: ' . dba::num_rows($messages));
+ while ($message = dba::fetch($messages)) {
+ if ($message['uid'] == 0) {
+ $global = true;
+
+ q("UPDATE `term` SET `global` = 1 WHERE `otype` = %d AND `guid` = '%s'",
+ intval(TERM_OBJ_POST), dbesc($message['guid']));
+ } else {
+ $isglobal = q("SELECT `global` FROM `term` WHERE `uid` = 0 AND `otype` = %d AND `guid` = '%s'",
+ intval(TERM_OBJ_POST), dbesc($message['guid']));
+
+ $global = (count($isglobal) > 0);
+ }
+
+ q("UPDATE `term` SET `guid` = '%s', `created` = '%s', `received` = '%s', `global` = %d WHERE `otype` = %d AND `oid` = %d",
+ dbesc($message['guid']), dbesc($message['created']), dbesc($message['received']),
+ intval($global), intval(TERM_OBJ_POST), intval($message['oid']));
+ }
+
+ dba::close($messages);
+
+ $messages = dba::p("SELECT `guid` FROM `item` WHERE `uid` = 0");
+
+ logger('fetched messages: ' . dba::num_rows($messages));
+ while ($message = dba::fetch(messages)) {
+ q("UPDATE `item` SET `global` = 1 WHERE `guid` = '%s'", dbesc($message['guid']));
+ }
-class TagUpdate {
- public static function execute() {
- update_items();
+ dba::close($messages);
}
}
#adminpage #frio_background_image.input-group {
display: block;
}
+#adminpage ul#pluginslist, li.plugin {
+ padding-top: 10px;
+}
+#adminpage li .icon {
+ display: inline-block;
+ vertical-align: text-top;
+ position: relative;
+ padding-left: 5px;
+}
+#adminpage li .icon:before {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ width: 17px;
+ height: 17px;
+ left: 0;
+ margin-left: -20px;
+ margin-top: 2px;
+ border: 1px solid #cccccc;
+ border-radius: 3px;
+ background-color: #fff;
+ -webkit-transition: border 0.15s ease-in-out, color 0.15s ease-in-out;
+ -o-transition: border 0.15s ease-in-out, color 0.15s ease-in-out;
+ transition: border 0.15s ease-in-out, color 0.15s ease-in-out;
+}
+#adminpage li .icon.on:after {
+ font-family: "FontAwesome";
+ content: "\f00c";
+ display: inline-block;
+ position: absolute;
+ width: 16px;
+ height: 16px;
+ left: 0;
+ top: 0;
+ margin-left: -20px;
+ margin-top: 2px;
+ padding-left: 3px;
+ padding-top: 1px;
+ font-size: 11px;
+ color: #555555;
+}
+#adminpage .plugin .desc {
+ padding-left: 10px;
+}
/* Register Page*/
#register-openid-wrapper, #register-name-wrapper, #register-invite-wrapper, #profile-publish-wrapper {