/** * Create a new activity entry in the database. If the specified activity type has an email projection * handler, this method will also send an email notification where appropriate. * * @todo Add an unsubscribe link to notification email footers. * * @param string $type The name of the type of activity to create. * @param array $member An array of details for the member to create the activity for. * @param array $fromMember An array of details for the member that the activity is from. * @param array $data An array of custom data that can be used by the type/projection callback functions. * @param array $emailData An array of custom data that can be used only by the EMAIL projection callback function. * (i.e. it is not stored in the database.) * @return bool|int The activity ID, or false if there were errors. */ public function create($type, $member, $fromMember = null, $data = null, $emailData = null) { // Make sure we have a definition for this type of activity. if (empty(self::$types[$type])) { throw new Exception("Cannot create activity with non-existent type '{$type}'."); } // Get the projections that are handled by this type. $projections = self::$types[$type]; // Construct an array of information about the new activity. $activity = array("type" => $type, "memberId" => $member["memberId"], "fromMemberId" => $fromMember ? $fromMember["memberId"] : null, "conversationId" => isset($data["conversationId"]) ? $data["conversationId"] : null, "postId" => isset($data["postId"]) ? $data["postId"] : null, "time" => time()); $activityId = null; // If this activity type has notification or activity projections, we'll need to insert the activity into the database. if (!empty($projections[self::PROJECTION_NOTIFICATION]) or !empty($projections[self::PROJECTION_ACTIVITY])) { $activityId = parent::create($activity + array("data" => serialize($data))); } // Set some more information about the activity. $activity["data"] = (array) $data + (array) $emailData; $activity["fromMemberName"] = $fromMember ? $fromMember["username"] : null; $activity["activityId"] = $activityId; // If this activity type has an email projection, the member wants to receive an email notification // for this type, and we haven't set sent them one in a previous call of this method, then let's send one! if (!empty($projections[self::PROJECTION_EMAIL]) and !empty($member["preferences"]["email.{$type}"]) and !in_array($member["memberId"], $this->membersUsed)) { // Log the member as "used", so we don't send them any more email notifications about the same subject. $this->membersUsed[] = $member["memberId"]; // Load the member's language into esoTalk's memory. ET::saveLanguageState(); ET::loadLanguage(@$member["preferences"]["language"]); // Get the email content by calling the type's email projection function. list($subject, $body) = call_user_func($projections[self::PROJECTION_EMAIL], $activity, $member); // Send the email, prepending/appending a common email header/footer. sendEmail($member["email"], $subject, sprintf(T("email.header"), $member["username"]) . $body . sprintf(T("email.footer"), URL("settings", true))); // Revert back to esoTalk's old language definitions. ET::revertLanguageState(); } return $activity["activityId"]; }