From d19d1751e8d59419657df8f6c40d8941e44f3cab Mon Sep 17 00:00:00 2001 From: Katherine Bailey Date: Sat, 9 Apr 2011 16:22:33 -0700 Subject: [PATCH] Issue #1037718: flag integration --- activity_contrib.info | 8 ++ activity_contrib.info.txt | 8 -- activity_contrib.module | 4 +- activity_contrib_action_handlers.inc | 204 ++++++++++++++++++++++++++++++++++ modules/flag.activity.inc | 59 ++++++++++ 5 files changed, 274 insertions(+), 9 deletions(-) create mode 100644 activity_contrib.info delete mode 100644 activity_contrib.info.txt create mode 100644 modules/flag.activity.inc diff --git activity_contrib.info activity_contrib.info new file mode 100644 index 0000000..df9fef3 --- /dev/null +++ activity_contrib.info @@ -0,0 +1,8 @@ +; Id: $ +name = Activity Contrib +description = "Activity integration for various contrib modules." +core = 7.x +dependencies[] = activity +package = Activity +files[] = activity_contrib_action_handlers.inc +; @TODO: add unit tests. \ No newline at end of file diff --git activity_contrib.info.txt activity_contrib.info.txt deleted file mode 100644 index df9fef3..0000000 --- activity_contrib.info.txt +++ /dev/null @@ -1,8 +0,0 @@ -; Id: $ -name = Activity Contrib -description = "Activity integration for various contrib modules." -core = 7.x -dependencies[] = activity -package = Activity -files[] = activity_contrib_action_handlers.inc -; @TODO: add unit tests. \ No newline at end of file diff --git activity_contrib.module activity_contrib.module index 1ea8401..0041433 100644 --- activity_contrib.module +++ activity_contrib.module @@ -11,9 +11,11 @@ function flag_activity_api() { // Figure out the activity access control realms. $flags = flag_get_flags(); + $realms = array(); foreach ($flags as $fid => $flag) { - $realms["flag_" . $flag->fid] = $flag->title; + $realms["flag_" . $flag->fid] = array('name' => $flag->title); } + return array( 'api' => '3.0-alpha1', 'realms' => $realms, diff --git activity_contrib_action_handlers.inc activity_contrib_action_handlers.inc index 80e31ea..979168f 100644 --- activity_contrib_action_handlers.inc +++ activity_contrib_action_handlers.inc @@ -5,6 +5,210 @@ * @{ */ class FlagActivityActionHandler extends ActivityActionHandler { + + /** + * Return the nid of this Activity. + * + * @param array $objects + * An array of objects used in tokenization. + * + * @return int / NULL + */ + public function determineNid($objects) { + $nid = NULL; + if (isset($objects['flag-action']) && $objects['flag-action']->content_type == 'node') { + $nid = $objects['flag-action']->content_id; + } + + // TODO: Should probably also store the nid if it's a comment being flagged, + // i.e. the nid of the comment. + return $nid; + } + + /** + * Return the eid field for this Activity. + * + * @param array $context + * The context argument passed into the action callback. + * + * @return int + */ + public function determineEid($context) { + $flag = $context['flag']; + $type = $flag->content_type; + // It's unfortunate to have to do a switch statement here, but at this point + // we don't have the fcid so we can't simply call flag_get_content_id(). + switch ($type) { + case 'node': + $content_id = $context['node']->nid; + break; + case 'user': + $content_id = $context['user']->uid; + break; + case 'comment': + $content_id = $context['comment']->cid; + break; + default: + return 0; + } + // TODO: need to actually get the sid :-/ + $record = $flag->get_flagging_record($content_id, $GLOBALS['user']->uid, 0); + return $record->fcid; + } + + /** + * Load objects for tokenization. + * + * @param int $eid + * The entity identifier for this Activity. + * + * @return array + */ + public function loadObjects($eid) { + // $eid is the fcid + $record = db_query("SELECT fid, content_type, content_id, uid, sid from {flag_content} where fcid = :fcid", array(':fcid' => $eid))->fetchAssoc(); + $content_type = $record['content_type']; + $content_id = $record['content_id']; + + // Unfortunately we have to deal in very specific ways with the object being + // flagged, so bail if it's not a user, node or comment. + if (!in_array($content_type, array('node', 'user', 'comment'))); + + $flag = flag_get_flag(NULL, $record['fid']); + $objects['flag'] = $flag; + + // Retrieve title and url for the content being flagged - sadly we have + // to do this differently depending on what type of entity has been flagged. + if ($content_type == 'comment') { + $comment = db_query("SELECT subject, nid FROM {comment} WHERE cid = :id", array(':id' => $content_id))->fetchAssoc(); + $content_url = url('node/'. $comment['nid'], array(), 'comment-'. $content_id, TRUE); + $content_title = $comment['subject']; + } + else { + if ($content_type == 'node') { + $sql = "SELECT title FROM {node} WHERE nid = :id"; + $content_url = url('node/'. $content_id); + } + else { + // It has to be a user. + $sql = "SELECT name FROM {users} WHERE uid = :id"; + $content_url = url('user/'. $content_id); + } + $content_title = db_query($sql, array(':id' => $content_id))->fetchField(); + } + + // Prepare the flagged item object for tokenization. + $fa = new stdClass(); + $fa->action = 'flag'; + $fa->content_type = $content_type; + $fa->content_id = $content_id; + $fa->content_title = $content_title; + $fa->content_url = $content_url; + $objects['flag-action'] = $fa; + + // Prepare the flagging user object for tokenization. + if (!$record['uid']) { + $user = new stdClass(); + $user->name = 'Someone'; + $user->uid = 0; + } + else { + $user = user_load($record['uid']); + } + $objects['user'] = $user; + return $objects; + } + + /** + * Return option defaults and structure. + * + * @return array. + */ + public function optionDefinition() { + $options = parent::optionDefinition(); + $options['flags'] = array( + '#default_value' => array(), + ); + $options['view_modes'] = array( + '#default_value' => array(), + ); + return $options; + } + + /** + * Display an FAPI form. + * + * @param &$form + * An FAPI form array. + * @param $form_state + * The form_state from FAPI. + */ + public function optionForm(&$form, $form_state) { + parent::optionForm($form, $form_state); + $flags = array(); + + foreach (flag_get_flags() as $fid => $flag) { + $flags[$fid] = check_plain($flag->name); + } + $form['flags'] = array( + '#type' => 'checkboxes', + '#title' => t('Allowed Flags'), + '#options' => $flags, + '#default_value' => $this->options['flags'], + ); + } + + /** + * Determine if the current Action is valid for this object. + * + * @param $eid + * The entity id for the activity. + * @param $actor + * The uid of the actor for this activity. + * @param $timestamp + * Unix timestamp when this activity occurred. + * @param array $objects + * The collection of objects for this action. + * @param mixed $argument1 + * The first argument passed to the action callback. + * @param mixed $argument2 + * The second argument passed to the action callback. + * + * @return boolean + */ + public function valid($eid, $actor, $timestamp, $objects, $argument1, $argument2) { + $flag_check = TRUE; + $allowed_flags = array_filter($this->options['flags']); + if (!empty($allowed_flags)) { + $flag_name = db_query("SELECT name from {flag_content} INNER JOIN {flags} USING(fid) where fcid = :fcid", array(':fcid' => $eid))->fetchField(); + $flag_check = in_array($flag_name, $allowed_flags); + } + return parent::valid($eid, $actor, $timestamp, $objects, $argument1, $argument2) && $flag_check; + } + + /** + * Return an array of message types. + */ + protected function messages() { + $messages = parent::messages(); + $messages['user'] = array( + 'title' => 'Flagger', + 'description' => 'The person who performed the flagging activity', + ); + return $messages; + } + + /** + * List all eids for this handler, used for batch regeneration and backfilling. + * + * @param int $offset + * The offset for the query. + * @param int $limit + * The limit for the query. + */ + public function listEids($offset, $limit) { + return array('total' => 0, 'arguments' => array()); + } } /** diff --git modules/flag.activity.inc modules/flag.activity.inc new file mode 100644 index 0000000..c3f6459 --- /dev/null +++ modules/flag.activity.inc @@ -0,0 +1,59 @@ + $flag) { + // This will also work for comments as those activity records have nids. + if ($activity->nid && $flag->content_type == 'node') { + $grants['flag_' . $flag->fid] = array($activity->nid); + } + elseif ($flag->content_type == 'user') { + $grants['flag_' . $flag->fid] = array($activity->uid); + } + } + return $grants; +} + +/** + * Implementation of hook_activity_access_grants(). + */ +function flag_activity_access_grants($account) { + // Get all the user and node flags. + $user_flags = flag_get_user_flags('user', NULL, $account->uid); + $node_flags = flag_get_user_flags('node', NULL, $account->uid); + + $flag_grants = array(); + if (!empty($node_flags)) { + foreach ($node_flags as $flagged_objects) { + foreach ($flagged_objects as $nid => $flagged) { + // Tell activity to grant user $account access to those flagged with + // $fid that are $nid. + $flag_grants['flag_' . $flagged->fid][] = $nid; + } + } + } + + if (!empty($user_flags)) { + foreach ($user_flags as $flagged_objects) { + foreach ($flagged_objects as $uid => $flagged) { + // Tell Activity to grant user $account access to those flagged with + // $fid that are $uid. + $flag_grants['flag_' . $flagged->fid][] = $uid; + } + } + } + + return $flag_grants; +} + + -- 1.7.4.1