pluginspath . 'thewire/actions'; register_action("thewire/add", false, "$action_base/add.php"); register_action("thewire/delete", false, "$action_base/delete.php"); register_plugin_hook('unit_test', 'system', 'thewire_test'); } /** * The wire page handler * * Supports: * thewire/all View site wire posts * thewire/owner/ View this user's wire posts * thewire/following/ View the posts of those this user follows * thewire/reply/ Reply to a post * thewire/view/ View a conversation thread * thewire/tag/ View wire posts tagged with * * @param array $page From the page_handler function * @return true|false Depending on success */ function thewire_page_handler($page) { // if just /thewire go to global view in the else statement if (isset($page[0]) && $page[0]) { switch ($page[0]) { case "all": include dirname(__FILE__) . "/pages/everyone.php"; break; case "friends": include dirname(__FILE__) . "/pages/friends.php"; break; case "owner": include dirname(__FILE__) . "/pages/user.php"; break; case "thread": if (isset($page[1])) { set_input('thread_id', $page[1]); } include dirname(__FILE__) . "/pages/thread.php"; break; case "reply": if (isset($page[1])) { set_input('guid', $page[1]); } include dirname(__FILE__) . "/pages/reply.php"; break; case "tag": if (isset($page[1])) { set_input('tag', $page[1]); } include dirname(__FILE__) . "/pages/tag.php"; break; case "previous": if (isset($page[1])) { set_input('guid', $page[1]); } include dirname(__FILE__) . "/pages/previous.php"; break; } } else { include dirname(__FILE__) . "/pages/everyone.php"; } return true; } /** * Override the url for a wire post to return the thread * * @param $thewirepost - wire post object */ function thewire_url($thewirepost) { global $CONFIG; return $CONFIG->url . "thewire/view/" . $thewirepost->guid; } /** * Returns the notification body * * @param string $hook * @param string $entity_type * @param string $returnvalue * @param array $params * @return $string */ function thewire_notify_message($hook, $entity_type, $returnvalue, $params) { global $CONFIG; $entity = $params['entity']; if (($entity instanceof ElggEntity) && ($entity->getSubtype() == 'thewire')) { $descr = $entity->description; $owner = $entity->getOwnerEntity(); if ($entity->reply) { // have to do this because of poor design of Elgg notification system $parent_post = get_entity(get_input('parent_guid')); if ($parent_post) { $parent_owner = $parent_post->getOwnerEntity(); } $body = sprintf(elgg_echo('thewire:notify:reply'), $owner->name, $parent_owner->name); } else { $body = sprintf(elgg_echo('thewire:notify:post'), $owner->name); } $body .= "\n\n" . $descr . "\n\n"; $body .= elgg_echo('thewire') . ": {$CONFIG->url}thewire"; return $body; } return $returnvalue; } /** * Get an array of hashtags from a text string * * @param string $text * @return array */ function thewire_get_hashtags($text) { // beginning of text or white space followed by hashtag // hashtag must begin with # and contain at least one character not digit, space, or punctuation $matches = array(); preg_match_all('/(^|[^\w])#(\w*[^\s\d!-\/:-@]+\w*)/', $text, $matches); return $matches[2]; } /** * Replace urls, hash tags, and @'s by links * * @param $text * @return string */ function thewire_filter($text) { global $CONFIG; $text = ' ' . $text; // email addresses $text = preg_replace( '/(^|[^\w])([\w\-\.]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})/i', '$1$2@$3', $text); // links $text = parse_urls($text); // usernames $text = preg_replace( '/(^|[^\w])@([\w]+)/', '$1@$2', $text); // hashtags $text = preg_replace( '/(^|[^\w])#(\w*[^\s\d!-\/:-@]+\w*)/', '$1#$2', $text); $text = trim($text); return $text; } /** * Create a new wire post. * * @param string $text The post text * @param int $userid The user's guid * @param int $access_id Public/private etc * @param int $parent_guid Parent post guid (if any) * @param string $method The method (default: 'site') * @return guid or false if failure */ function thewire_save_post($text, $userid, $access_id, $parent_guid = 0, $method = "site") { $post = new ElggObject(); $post->subtype = "thewire"; $post->owner_guid = $userid; $post->access_id = $access_id; // only 200 characters allowed $text = elgg_substr($text, 0, 200); // no html tags allowed so we escape $post->description = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); $post->method = $method; //method: site, email, api, ... $tags = thewire_get_hashtags($text); if ($tags) { $post->tags = $tags; } // must do this before saving so notifications pick up that this is a reply if ($parent_guid) { $post->reply = true; } $guid = $post->save(); // set thread guid if ($parent_guid) { $post->addRelationship($parent_guid, 'parent'); // name conversation threads by guid of first post (works even if first post deleted) $parent_post = get_entity($parent_guid); $post->wire_thread = $parent_post->wire_thread; } else { // first post in this thread $post->wire_thread = $guid; } if ($guid) { add_to_river('river/object/thewire/create', 'create', $post->owner_guid, $post->guid); } return $guid; } /** * Send notification to poster of parent post if not notified already * * @param int $guid * @param int $parent_guid * @param ElggUser $user */ function thewire_send_response_notification($guid, $parent_guid, $user) { $parent_owner = get_entity($parent_guid)->getOwnerEntity(); $user = get_loggedin_user(); // check to make sure user is not responding to self if ($parent_owner->guid != $user->guid) { // check if parent owner has notification for this user $send_response = true; global $NOTIFICATION_HANDLERS; foreach ($NOTIFICATION_HANDLERS as $method => $foo) { if (check_entity_relationship($parent_owner->guid, 'notify' . $method, $user->guid)) { $send_response = false; } } // create the notification message if ($send_response) { // grab same notification message that goes to everyone else $params = array( 'entity' => get_entity($guid), 'method' => "email", ); $msg = thewire_notify_message("", "", "", $params); notify_user( $parent_owner->guid, $user->guid, elgg_echo('thewire:notify:subject'), $msg); } } } /** * Get the latest wire guid - used for ajax update * @return guid */ function thewire_latest_guid() { $post = elgg_get_entities(array( 'type' => 'object', 'subtype' => 'thewire', 'limit' => 1, )); if ($post) { return $post[0]->guid; } else { return 0; } } /** * Get the parent of a wire post * * @param ElggObject $post * @return ElggObject or null */ function thewire_get_parent($post_guid) { $parents = elgg_get_entities_from_relationship(array( 'relationship' => 'parent', 'relationship_guid' => $post_guid, )); if ($parents) { return $parents[0]; } return null; } /** * Runs unit tests for the wire */ function thewire_test($hook, $type, $value, $params) { global $CONFIG; $value[] = $CONFIG->pluginspath . 'thewire/tests/regex.php'; return $value; } /** * Removes the access and edit items from the entity menu * * @param type $hook * @param type $type * @param type $value * @param type $params * @return array */ function thewire_remove_entity_menu_items($hook, $type, $value, $params) { if (elgg_in_context('thewire')) { $menu = elgg_extract('default', $value, array()); foreach ($menu as $i => $entry) { $name = $entry->getName(); if ($name == 'access' || $name == 'edit') { unset($value['default'][$i]); } } return $value; } }