123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <?php
- /**
- * Provides links and notifications for using @username mentions
- *
- */
- elgg_register_event_handler('init', 'system', 'mentions_init');
- function mentions_init() {
- elgg_extend_view('css/elgg', 'css/mentions');
- elgg_require_js('mentions/autocomplete');
- elgg_extend_view('input/longtext', 'mentions/popup');
- elgg_extend_view('input/plaintext', 'mentions/popup');
- elgg_register_event_handler('pagesetup', 'system', 'mentions_get_views');
- // can't use notification hooks here because of many reasons
- elgg_register_event_handler('create', 'object', 'mentions_notification_handler');
- elgg_register_event_handler('create', 'annotation', 'mentions_notification_handler');
- // @todo This will result in multiple notifications for an edited entity so we don't do this
- //register_elgg_event_handler('update', 'all', 'mentions_notification_handler');
- // add option to the personal notifications form
- elgg_extend_view('notifications/subscriptions/personal', 'mentions/notification_settings');
- elgg_register_plugin_hook_handler('action', 'notificationsettings/save', 'mentions_save_settings');
- }
- function mentions_get_regex() {
- // @todo this won't work for usernames that must be html encoded.
- // get all chars with unicode 'letter' or 'mark' properties or a number _ or .,
- // preceeded by @, and possibly surrounded by word boundaries.
- return '/[\b]?@([\p{L}\p{M}_\.0-9]+)[\b]?/iu';
- }
- function mentions_get_views() {
- // allow plugins to add additional views to be processed for usernames
- $views = array('output/longtext');
- $views = elgg_trigger_plugin_hook('get_views', 'mentions', null, $views);
- foreach ($views as $view) {
- elgg_register_plugin_hook_handler('view', $view, 'mentions_rewrite');
- }
- }
- /**
- * Rewrites a view for @username mentions.
- *
- * @param string $hook The name of the hook
- * @param string $type The type of the hook
- * @param string $content The content of the page
- * @return string
- */
- function mentions_rewrite($hook, $entity_type, $returnvalue, $params) {
- $regexp = mentions_get_regex();
- $returnvalue = preg_replace_callback($regexp, 'mentions_preg_callback', $returnvalue);
- return $returnvalue;
- }
- /**
- * Used as a callback fro the preg_replace in mentions_rewrite()
- *
- * @param type $matches
- * @return type str
- */
- function mentions_preg_callback($matches) {
- $user = get_user_by_username($matches[1]);
- $period = '';
- $icon = '';
- // Catch the trailing period when used as punctuation and not a username.
- if (!$user && substr($matches[1], -1) == '.') {
- $user = get_user_by_username(rtrim($matches[1], '.'));
- $period = '.';
- }
- if ($user) {
- if (elgg_get_plugin_setting('fancy_links', 'mentions')) {
- $icon = elgg_view('output/img', array(
- 'src' => $user->getIconURL('topbar'),
- 'class' => 'pas mentions-user-icon'
- ));
- $replace = elgg_view('output/url', array(
- 'href' => $user->getURL(),
- 'text' => $icon . $user->name,
- 'class' => 'mentions-user-link'
- ));
- } else {
- $replace = elgg_view('output/url', array(
- 'href' => $user->getURL(),
- 'text' => $user->name,
- ));
- }
- return $replace .= $period;
- } else {
- return $matches[0];
- }
- }
- /**
- * Catch all create events and scan for @username tags to notify user.
- *
- * @param string $event The event name
- * @param string $event_type The event type
- * @param ElggData $object The object that was created
- * @return void
- */
- function mentions_notification_handler($event, $event_type, $object) {
- // excludes messages - otherwise an endless loop of notifications occur!
- if (elgg_instanceof($object, 'object', 'messages')) {
- return;
- }
- $type = $object->getType();
- $subtype = $object->getSubtype();
- $owner = $object->getOwnerEntity();
- $fields = array(
- 'title', 'description', 'value'
- );
- // store the guids of notified users so they only get one notification per creation event
- $notified_guids = array();
- foreach ($fields as $field) {
- $content = $object->$field;
- // it's ok in this case if 0 matches == FALSE
- if (preg_match_all(mentions_get_regex(), $content, $matches)) {
- // match against the 2nd index since the first is everything
- foreach ($matches[1] as $username) {
- $user = get_user_by_username($username);
- // check for trailing punctuation caught by the regex
- if (!$user && substr($username, -1) == '.') {
- $user = get_user_by_username(rtrim($username, '.'));
- }
- if (!$user) {
- continue;
- }
- // user must have access to view object/annotation
- if ($type == 'annotation') {
- $annotated_entity = $object->getEntity();
- if (!$annotated_entity || !has_access_to_entity($annotated_entity, $user)) {
- continue;
- }
- } else {
- if (!has_access_to_entity($object, $user)) {
- continue;
- }
- }
- if (!in_array($user->getGUID(), $notified_guids)) {
- $notified_guids[] = $user->getGUID();
- // if they haven't set the notification status default to sending.
- // Private settings are stored as strings so we check against "0"
- $notification_setting = elgg_get_plugin_user_setting('notify', $user->getGUID(), 'mentions');
- if ($notification_setting === "0") {
- continue;
- }
- $link = $object->getURL();
- $type_key = "mentions:notification_types:$type:$subtype";
- $type_str = elgg_echo($type_key);
- if ($type_str == $type_key) {
- // plugins can add to the list of mention objects by defining
- // the language string 'mentions:notification_types:<type>:<subtype>'
- continue;
- }
- $subject = elgg_echo('mentions:notification:subject', array($owner->name, $type_str));
- $body = elgg_echo('mentions:notification:body', array(
- $owner->name,
- $type_str,
- $link,
- ));
- $params = array(
- 'object' => $object,
- 'action' => 'mention',
- );
- notify_user($user->getGUID(), $owner->getGUID(), $subject, $body, $params);
- }
- }
- }
- }
- }
- /**
- * Save mentions-specific info from the notification form
- *
- * @param type $hook
- * @param type $type
- * @param type $value
- * @param type $params
- */
- function mentions_save_settings($hook, $type, $value, $params) {
- $notify = (bool) get_input('mentions_notify');
- $user = get_entity(get_input('guid'));
- if (!elgg_set_plugin_user_setting('notify', $notify, $user->getGUID(), 'mentions')) {
- register_error(elgg_echo('mentions:settings:failed'));
- }
- return;
- }
|