X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fitems.php;h=31a709fcbf2318ac80f01ed5024efba4cdec858d;hb=0cd9db9cb7f4c96f597e37590a536eaae123238d;hp=3bf0a001c6a06d5a438df5de3e3f04a7b2a3ecb0;hpb=45d73b106bbebdea17c56c00235c0dcebc471536;p=friendica.git diff --git a/include/items.php b/include/items.php index 3bf0a001c6..31a709fcbf 100644 --- a/include/items.php +++ b/include/items.php @@ -4,7 +4,8 @@ * @file include/items.php */ -use \Friendica\ParseUrl; +use Friendica\App; +use Friendica\ParseUrl; require_once 'include/bbcode.php'; require_once 'include/oembed.php'; @@ -142,7 +143,7 @@ function title_is_body($title, $body) { $body = substr($body, 0, strlen($title)); } - if (($title != $body) and (substr($title, -3) == "...")) { + if (($title != $body) && (substr($title, -3) == "...")) { $pos = strrpos($title, "..."); if ($pos > 0) { $title = substr($title, 0, $pos); @@ -158,16 +159,16 @@ function add_page_info_data($data) { // It maybe is a rich content, but if it does have everything that a link has, // then treat it that way - if (($data["type"] == "rich") AND is_string($data["title"]) AND - is_string($data["text"]) AND (sizeof($data["images"]) > 0)) { + if (($data["type"] == "rich") && is_string($data["title"]) && + is_string($data["text"]) && (sizeof($data["images"]) > 0)) { $data["type"] = "link"; } - if ((($data["type"] != "link") AND ($data["type"] != "video") AND ($data["type"] != "photo")) OR ($data["title"] == $data["url"])) { + if ((($data["type"] != "link") && ($data["type"] != "video") && ($data["type"] != "photo")) || ($data["title"] == $data["url"])) { return ""; } - if ($no_photos AND ($data["type"] == "photo")) { + if ($no_photos && ($data["type"] == "photo")) { return ""; } @@ -203,7 +204,7 @@ function add_page_info_data($data) { $preview = str_replace(array("[", "]"), array("[", "]"), htmlentities($data["images"][0]["src"], ENT_QUOTES, 'UTF-8', false)); // if the preview picture is larger than 500 pixels then show it in a larger mode // But only, if the picture isn't higher than large (To prevent huge posts) - if (($data["images"][0]["width"] >= 500) AND ($data["images"][0]["width"] >= $data["images"][0]["height"])) { + if (($data["images"][0]["width"] >= 500) && ($data["images"][0]["width"] >= $data["images"][0]["height"])) { $text .= " image='".$preview."'"; } else { $text .= " preview='".$preview."'"; @@ -213,7 +214,7 @@ function add_page_info_data($data) { $text .= "]".$data["text"]."[/attachment]"; $hashtags = ""; - if (isset($data["keywords"]) AND count($data["keywords"])) { + if (isset($data["keywords"]) && count($data["keywords"])) { $hashtags = "\n"; foreach ($data["keywords"] AS $keyword) { /// @todo make a positive list of allowed characters @@ -236,11 +237,11 @@ function query_page_info($url, $no_photos = false, $photo = "", $keywords = fals logger('fetch page info for ' . $url . ' ' . print_r($data, true), LOGGER_DEBUG); - if (!$keywords AND isset($data["keywords"])) { + if (!$keywords && isset($data["keywords"])) { unset($data["keywords"]); } - if (($keyword_blacklist != "") AND isset($data["keywords"])) { + if (($keyword_blacklist != "") && isset($data["keywords"])) { $list = explode(", ", $keyword_blacklist); foreach ($list AS $keyword) { $keyword = trim($keyword); @@ -258,7 +259,7 @@ function add_page_keywords($url, $no_photos = false, $photo = "", $keywords = fa $data = query_page_info($url, $no_photos, $photo, $keywords, $keyword_blacklist); $tags = ""; - if (isset($data["keywords"]) AND count($data["keywords"])) { + if (isset($data["keywords"]) && count($data["keywords"])) { foreach ($data["keywords"] AS $keyword) { $hashtag = str_replace(array(" ", "+", "/", ".", "#", "'"), array("", "", "", "", "", ""), $keyword); @@ -300,7 +301,7 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false) { } // Convert urls without bbcode elements - if (!$matches AND $texturl) { + if (!$matches && $texturl) { preg_match("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", " ".$body, $matches); // Yeah, a hack. I really hate regular expressions :) @@ -314,21 +315,21 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false) { } // Remove the link from the body if the link is attached at the end of the post - if (isset($footer) AND (trim($footer) != "") AND (strpos($footer, $matches[1]))) { + if (isset($footer) && (trim($footer) != "") && (strpos($footer, $matches[1]))) { $removedlink = trim(str_replace($matches[1], "", $body)); - if (($removedlink == "") OR strstr($body, $removedlink)) { + if (($removedlink == "") || strstr($body, $removedlink)) { $body = $removedlink; } $url = str_replace(array('/', '.'), array('\/', '\.'), $matches[1]); $removedlink = preg_replace("/\[url\=" . $url . "\](.*?)\[\/url\]/ism", '', $body); - if (($removedlink == "") OR strstr($body, $removedlink)) { + if (($removedlink == "") || strstr($body, $removedlink)) { $body = $removedlink; } } // Add the page information to the bottom - if (isset($footer) AND (trim($footer) != "")) { + if (isset($footer) && (trim($footer) != "")) { $body .= $footer; } @@ -339,7 +340,7 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false) { * Adds a "lang" specification in a "postopts" element of given $arr, * if possible and not already present. * Expects "body" element to exist in $arr. - * + * * @todo Add a parameter to request forcing override */ function item_add_language_opt(&$arr) { @@ -410,7 +411,70 @@ function uri_to_guid($uri, $host = "") { return $guid_prefix.$host_hash; } -/// @TODO Maybe $arr must be called-by-reference? This function modifies it +/** + * @brief Store the conversation data + * + * @param array $arr Item array with conversation data + * @return array Item array with removed conversation data + */ +function store_conversation($arr) { + if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) { + $conversation = array('item-uri' => $arr['uri'], 'received' => dbm::date()); + + if (isset($arr['parent-uri']) && ($arr['parent-uri'] != $arr['uri'])) { + $conversation['reply-to-uri'] = $arr['parent-uri']; + } + if (isset($arr['thr-parent']) && ($arr['thr-parent'] != $arr['uri'])) { + $conversation['reply-to-uri'] = $arr['thr-parent']; + } + + if (isset($arr['conversation-uri'])) { + $conversation['conversation-uri'] = $arr['conversation-uri']; + } + + if (isset($arr['conversation-href'])) { + $conversation['conversation-href'] = $arr['conversation-href']; + } + + if (isset($arr['protocol'])) { + $conversation['protocol'] = $arr['protocol']; + } + + if (isset($arr['source'])) { + $conversation['source'] = $arr['source']; + } + + $old_conv = dba::fetch_first("SELECT `item-uri`, `reply-to-uri`, `conversation-uri`, `conversation-href`, `protocol`, `source` + FROM `conversation` WHERE `item-uri` = ?", $conversation['item-uri']); + if (dbm::is_result($old_conv)) { + // Don't update when only the source has changed. + // Only do this when there had been no source before. + if ($old_conv['source'] != '') { + unset($old_conv['source']); + } + // Update structure data all the time but the source only when its from a better protocol. + if (($old_conv['protocol'] < $conversation['protocol']) && ($old_conv['protocol'] != 0)) { + unset($conversation['protocol']); + unset($conversation['source']); + } + if (!dba::update('conversation', $conversation, array('item-uri' => $conversation['item-uri']), $old_conv)) { + logger('Conversation: update for '.$conversation['item-uri'].' from '.$conv['protocol'].' to '.$conversation['protocol'].' failed', LOGGER_DEBUG); + } + } else { + if (!dba::insert('conversation', $conversation)) { + logger('Conversation: insert for '.$conversation['item-uri'].' (protocol '.$conversation['protocol'].') failed', LOGGER_DEBUG); + } + } + } + + unset($arr['conversation-uri']); + unset($arr['conversation-href']); + unset($arr['protocol']); + unset($arr['source']); + + return $arr; +} + /// @TODO add type-hint array function item_store($arr, $force_parent = false, $notify = false, $dontcache = false) { @@ -423,6 +487,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f $arr['origin'] = 1; $arr['last-child'] = 1; $arr['network'] = NETWORK_DFRN; + $arr['protocol'] = PROTOCOL_DFRN; // We have to avoid duplicates. So we create the GUID in form of a hash of the plink or uri. // In difference to the call to "uri_to_guid" several lines below we add the hash of our own host. @@ -436,6 +501,23 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f } } + if ($notify) { + $guid_prefix = ""; + } elseif ((trim($arr['guid']) == "") && (trim($arr['plink']) != "")) { + $arr['guid'] = uri_to_guid($arr['plink']); + } elseif ((trim($arr['guid']) == "") && (trim($arr['uri']) != "")) { + $arr['guid'] = uri_to_guid($arr['uri']); + } else { + $parsed = parse_url($arr["author-link"]); + $guid_prefix = hash("crc32", $parsed["host"]); + } + + $arr['guid'] = ((x($arr, 'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $guid_prefix)); + $arr['uri'] = ((x($arr, 'uri')) ? notags(trim($arr['uri'])) : item_new_uri($a->get_hostname(), $uid, $arr['guid'])); + + // Store conversation data + $arr = store_conversation($arr); + /* * If a Diaspora signature structure was passed in, pull it out of the * item array and set it aside for later storage. @@ -517,20 +599,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f item_add_language_opt($arr); - if ($notify) { - $guid_prefix = ""; - } elseif ((trim($arr['guid']) == "") AND (trim($arr['plink']) != "")) { - $arr['guid'] = uri_to_guid($arr['plink']); - } elseif ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "")) { - $arr['guid'] = uri_to_guid($arr['uri']); - } else { - $parsed = parse_url($arr["author-link"]); - $guid_prefix = hash("crc32", $parsed["host"]); - } - $arr['wall'] = ((x($arr, 'wall')) ? intval($arr['wall']) : 0); - $arr['guid'] = ((x($arr, 'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $guid_prefix)); - $arr['uri'] = ((x($arr, 'uri')) ? notags(trim($arr['uri'])) : item_new_uri($a->get_hostname(), $uid, $arr['guid'])); $arr['extid'] = ((x($arr, 'extid')) ? notags(trim($arr['extid'])) : ''); $arr['author-name'] = ((x($arr, 'author-name')) ? trim($arr['author-name']) : ''); $arr['author-link'] = ((x($arr, 'author-link')) ? notags(trim($arr['author-link'])) : ''); @@ -584,7 +653,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f $arr['edited'] = datetime_convert(); } - if (($arr['author-link'] == "") AND ($arr['owner-link'] == "")) { + if (($arr['author-link'] == "") && ($arr['owner-link'] == "")) { logger("Both author-link and owner-link are empty. Called by: " . App::callstack(), LOGGER_DEBUG); } @@ -691,41 +760,6 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f $arr['thr-parent'] = $arr['parent-uri']; - if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) { - $conversation = array('item-uri' => $arr['uri'], 'received' => dbm::date()); - if (isset($arr['thr-parent'])) { - if ($arr['thr-parent'] != $arr['uri']) { - $conversation['reply-to-uri'] = $arr['thr-parent']; - } - } - if (isset($arr['conversation-uri'])) { - $conversation['conversation-uri'] = $arr['conversation-uri']; - unset($arr['conversation-uri']); - } - - if ($arr['network'] == NETWORK_DFRN) { - $conversation['protocol'] = PROTOCOL_DFRN; - } elseif ($arr['network'] == NETWORK_DIASPORA) { - $conversation['protocol'] = PROTOCOL_DIASPORA; - } - - if (isset($arr['protocol'])) { - $conversation['protocol'] = $arr['protocol']; - unset($arr['protocol']); - } - if (isset($arr['object'])) { - $conversation['source'] = $arr['object']; - if (in_array($arr['network'], array(NETWORK_DIASPORA, NETWORK_OSTATUS))) { - unset($arr['object']); - } - } - if (isset($arr['source'])) { - $conversation['source'] = $arr['source']; - unset($arr['source']); - } - dba::insert('conversation', $conversation); - } - if ($arr['parent-uri'] === $arr['uri']) { $parent_id = 0; $parent_deleted = 0; @@ -798,7 +832,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f $a = get_app(); $self = normalise_link(App::get_baseurl() . '/profile/' . $u[0]['nickname']); logger("item_store: 'myself' is ".$self." for parent ".$parent_id." checking against ".$arr['author-link']." and ".$arr['owner-link'], LOGGER_DEBUG); - if ((normalise_link($arr['author-link']) == $self) OR (normalise_link($arr['owner-link']) == $self)) { + if ((normalise_link($arr['author-link']) == $self) || (normalise_link($arr['owner-link']) == $self)) { q("UPDATE `thread` SET `mention` = 1 WHERE `iid` = %d", intval($parent_id)); logger("item_store: tagged thread ".$parent_id." as mention for user ".$self, LOGGER_DEBUG); } @@ -918,8 +952,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f logger('item_store: ' . print_r($arr,true), LOGGER_DATA); - q("COMMIT"); - q("START TRANSACTION;"); + dba::transaction(); $r = dbq("INSERT INTO `item` (`" . implode("`, `", array_keys($arr)) @@ -941,7 +974,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f } } else { // This can happen - for example - if there are locking timeouts. - q("ROLLBACK"); + dba::rollback(); // Store the data into a spool file so that we can try again later. @@ -966,7 +999,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f if ($current_post == 0) { // This is one of these error messages that never should occur. logger("couldn't find created item - we better quit now."); - q("ROLLBACK"); + dba::rollback(); return 0; } @@ -981,7 +1014,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f if (!dbm::is_result($r)) { // This shouldn't happen, since COUNT always works when the database connection is there. logger("We couldn't count the stored entries. Very strange ..."); - q("ROLLBACK"); + dba::rollback(); return 0; } @@ -990,13 +1023,13 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f logger('Duplicated post occurred. uri = ' . $arr['uri'] . ' uid = ' . $arr['uid']); // Yes, we could do a rollback here - but we are having many users with MyISAM. - q("DELETE FROM `item` WHERE `id` = %d", intval($current_post)); - q("COMMIT"); + dba::delete('item', array('id' => $current_post)); + dba::commit(); return 0; } elseif ($r[0]["entries"] == 0) { // This really should never happen since we quit earlier if there were problems. logger("Something is terribly wrong. We haven't found our created entry."); - q("ROLLBACK"); + dba::rollback(); return 0; } @@ -1018,7 +1051,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f // update the commented timestamp on the parent // Only update "commented" if it is really a comment - if (($arr['verb'] == ACTIVITY_POST) OR !get_config("system", "like_no_comment")) { + if (($arr['verb'] == ACTIVITY_POST) || !get_config("system", "like_no_comment")) { q("UPDATE `item` SET `commented` = '%s', `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), dbesc(datetime_convert()), @@ -1056,7 +1089,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f * current post can be deleted if is for a community page and no mention are * in it. */ - if (!$deleted AND !$dontcache) { + if (!$deleted && !$dontcache) { $r = q('SELECT * FROM `item` WHERE `id` = %d', intval($current_post)); if ((dbm::is_result($r)) && (count($r) == 1)) { @@ -1076,7 +1109,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f update_thread($parent_id); } - q("COMMIT"); + dba::commit(); /* * Due to deadlock issues with the "term" table we are doing these steps after the commit. @@ -1106,7 +1139,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f check_item_notification($current_post, $uid); if ($notify) { - proc_run(PRIORITY_HIGH, "include/notifier.php", $notify_type, $current_post); + proc_run(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), "include/notifier.php", $notify_type, $current_post); } return $current_post; @@ -1123,10 +1156,10 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f */ function item_set_last_item($arr) { - $update = (!$arr['private'] AND (($arr["author-link"] === $arr["owner-link"]) OR ($arr["parent-uri"] === $arr["uri"]))); + $update = (!$arr['private'] && (($arr["author-link"] === $arr["owner-link"]) || ($arr["parent-uri"] === $arr["uri"]))); // Is it a forum? Then we don't care about the rules from above - if (!$update AND ($arr["network"] == NETWORK_DFRN) AND ($arr["parent-uri"] === $arr["uri"])) { + if (!$update && ($arr["network"] == NETWORK_DFRN) && ($arr["parent-uri"] === $arr["uri"])) { $isforum = q("SELECT `forum` FROM `contact` WHERE `id` = %d AND `forum`", intval($arr['contact-id'])); if (dbm::is_result($isforum)) { @@ -1249,7 +1282,7 @@ function get_item_id($guid, $uid = 0) { // Does the given user have this item? if ($uid) { $r = q("SELECT `item`.`id`, `user`.`nickname` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid` - WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 + WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 AND `item`.`moderated` = 0 AND `item`.`guid` = '%s' AND `item`.`uid` = %d", dbesc($guid), intval($uid)); if (dbm::is_result($r)) { $id = $r[0]["id"]; @@ -1260,7 +1293,7 @@ function get_item_id($guid, $uid = 0) { // Or is it anywhere on the server? if ($nick == "") { $r = q("SELECT `item`.`id`, `user`.`nickname` FROM `item` INNER JOIN `user` ON `user`.`uid` = `item`.`uid` - WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0 + WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 AND `item`.`moderated` = 0 AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `item`.`wall` = 1 @@ -1345,10 +1378,7 @@ function tag_deliver($uid, $item_id) { // mmh.. no mention.. community page or private group... no wall.. no origin.. top-post (not a comment) // delete it! logger("tag_deliver: no-mention top-level post to communuty or private group. delete."); - q("DELETE FROM item WHERE id = %d and uid = %d", - intval($item_id), - intval($uid) - ); + dba::delete('item', array('id' => $item_id)); return true; } return; @@ -1400,7 +1430,7 @@ function tag_deliver($uid, $item_id) { ); update_thread($item_id); - proc_run(PRIORITY_HIGH,'include/notifier.php', 'tgroup', $item_id); + proc_run(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), 'include/notifier.php', 'tgroup', $item_id); } @@ -1570,7 +1600,7 @@ function item_is_remote_self($contact, &$datarray) { return false; } - if (($contact['network'] != NETWORK_FEED) AND $datarray['private']) { + if (($contact['network'] != NETWORK_FEED) && $datarray['private']) { return false; } @@ -1671,7 +1701,7 @@ function new_follower($importer, $contact, $datarray, $item, $sharing = false) { intval($importer['uid']) ); - if (dbm::is_result($r) AND !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) { + if (dbm::is_result($r) && !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) { // create notification $hash = random_string(); @@ -1711,7 +1741,7 @@ function new_follower($importer, $contact, $datarray, $item, $sharing = false) { )); } - } elseif (dbm::is_result($r) AND in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) { + } elseif (dbm::is_result($r) && in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) { $r = q("UPDATE `contact` SET `pending` = 0 WHERE `uid` = %d AND `url` = '%s' AND `pending` LIMIT 1", intval($importer['uid']), dbesc($url) @@ -1773,7 +1803,7 @@ function subscribe_to_hub($url, $importer, $contact, $hubmode = 'subscribe') { logger('subscribe_to_hub: ' . $hubmode . ' ' . $contact['name'] . ' to hub ' . $url . ' endpoint: ' . $push_url . ' with verifier ' . $verify_token); - if (!strlen($contact['hub-verify']) OR ($contact['hub-verify'] != $verify_token)) { + if (!strlen($contact['hub-verify']) || ($contact['hub-verify'] != $verify_token)) { $r = q("UPDATE `contact` SET `hub-verify` = '%s' WHERE `id` = %d", dbesc($verify_token), intval($contact['id']) @@ -2046,7 +2076,7 @@ function item_expire($uid, $days, $network = "", $force = false) { drop_item($item['id'], false); } - proc_run(PRIORITY_HIGH, "include/notifier.php", "expire", $uid); + proc_run(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "include/notifier.php", "expire", $uid); } @@ -2069,7 +2099,7 @@ function drop_items($items) { // multiple threads may have been deleted, send an expire notification if ($uid) { - proc_run(PRIORITY_HIGH, "include/notifier.php", "expire", $uid); + proc_run(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "include/notifier.php", "expire", $uid); } } @@ -2094,6 +2124,10 @@ function drop_item($id, $interactive = true) { $item = $r[0]; + if ($item['deleted']) { + return 0; + } + $owner = $item['uid']; $contact_id = 0; @@ -2204,23 +2238,6 @@ function drop_item($id, $interactive = true) { // ignore the result } - - // clean up item_id and sign meta-data tables - - /* - /// @TODO Old code - caused very long queries and warning entries in the mysql logfiles: - - $r = q("DELETE FROM item_id where iid in (select id from item where parent = %d and uid = %d)", - intval($item['id']), - intval($item['uid']) - ); - - $r = q("DELETE FROM sign where iid in (select id from item where parent = %d and uid = %d)", - intval($item['id']), - intval($item['uid']) - ); - */ - // The new code splits the queries since the mysql optimizer really has bad problems with subqueries // Creating list of parents @@ -2277,11 +2294,12 @@ function drop_item($id, $interactive = true) { } } + // send the notification upstream/downstream + // The priority depends on how the deletion is done. $drop_id = intval($item['id']); + $priority = ($interactive ? PRIORITY_HIGH : PRIORITY_LOW); - // send the notification upstream/downstream as the case may be - - proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id); + proc_run(array('priority' => $priority, 'dont_fork' => true), "include/notifier.php", "drop", $drop_id); if (! $interactive) { return $owner;