public function create($values, $wheres = array()) { if (in_array($values["type"], array("select", "radios", "checkboxes"))) { $this->validate("options", $values["options"], array($this, "validateOptions")); } if ($this->errorCount()) { return false; } return parent::create($values); }
public function setData($values) { if (!isset($values["title"])) { $values["title"] = ""; } $this->validate("title", $values["title"], array($this, "validateTitle")); if (!isset($values["menu"])) { $values["menu"] = "user"; } $this->validate("menu", $values["menu"], array($this, "validateMenu")); if (!isset($values["slug"])) { $values["slug"] = ""; } $this->validate("slug", $values["slug"], array($this, "validateSlug")); $values["slug"] = slug($values["slug"]); if ($this->errorCount()) { return false; } $pageId = parent::create($values); return $pageId; }
public function __construct($table = "", $primaryKey = "") { parent::__construct("conversation_tags", "conversationId"); }
/** * Class constructor. Sets up the inherited model functions to handle data in the search table * (used for logging search activity -> flood control.) * * @return void */ public function __construct() { parent::__construct("search"); }
/** * 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"]; }
/** * Update a member's details. * * @param array $values An array of fields to update and their values. * @param array $wheres An array of WHERE conditions. * @return bool|ETSQLResult */ public function update($values, $wheres = array()) { if (isset($values["username"])) { $this->validate("username", $values["username"], array($this, "validateUsername")); } if (isset($values["email"])) { $this->validate("email", $values["email"], array($this, "validateEmail")); } if (isset($values["password"])) { $this->validate("password", $values["password"], array($this, "validatePassword")); $values["password"] = $this->hashPassword($values["password"]); } // MD5 the "reset password" hash for storage (for extra safety). if (isset($values["resetPassword"])) { $values["resetPassword"] = md5($values["resetPassword"]); } if ($this->errorCount()) { return false; } return parent::update($values, $wheres); }
/** * Delete a channel and its conversations (or optionally move its conversations to another channel.) * * @param int $channelId The ID of the channel to delete. * @param bool|int $moveToChannelId The ID of the channel to move conversations to, or false to delete them. * @return bool true on success, false on error. */ public function deleteById($channelId, $moveToChannelId = false) { $channelId = (int) $channelId; // Do we want to move the conversations to another channel? if ($moveToChannelId !== false) { // If the channel does exist, move all the conversation over to it. if (array_key_exists((int) $moveToChannelId, $this->getAll())) { ET::SQL()->update("conversation")->set("channelId", (int) $moveToChannelId)->where("channelId=:channelId")->bind(":channelId", $channelId)->exec(); } else { $this->error("moveToChannelId", "invalidChannel"); } } else { ET::conversationModel()->delete(array("channelId" => $channelId)); } if ($this->errorCount()) { return false; } $result = parent::deleteById($channelId); // Reset channels in the global cache. ET::$cache->remove(self::CACHE_KEY); return $result; }
/** * Start a new converastion. Assumes the creator is the currently logged in user. * * @param array $data An array of the conversation's details: title, channelId, content. * @param array $membersAllowed An array of entities allowed to view the conversation, in the same format * as the return value of getMembersAllowed() * @param bool $isDraft Whether or not the conversation is a draft. * @return bool|array An array containing the new conversation ID and the new post ID, or false if * there was an error. */ public function create($data, $membersAllowed = array(), $isDraft = false) { // We can't do this if we're not logged in. if (!ET::$session->user) { return false; } // If the title is blank but the user is only saving a draft, call it "Untitled conversation." if ($isDraft and !$data["title"]) { $data["title"] = T("Untitled conversation"); } // Check for errors; validate the title and the post content. $this->validate("title", $data["title"], array($this, "validateTitle")); $this->validate("content", $data["content"], array(ET::postModel(), "validateContent")); $content = $data["content"]; unset($data["content"]); // Flood control! if (ET::$session->isFlooding()) { $this->error("flooding", "waitToReply"); } // Make sure that we have permission to post in this channel. $data["channelId"] = (int) $data["channelId"]; if (!ET::channelModel()->hasPermission($data["channelId"], "start")) { $this->error("channelId", "invalidChannel"); } // Did we encounter any errors? Don't continue. if ($this->errorCount()) { return false; } // Add some more data fields to insert into the database. $time = time(); $data["startMemberId"] = ET::$session->userId; $data["startTime"] = $time; $data["lastPostMemberId"] = ET::$session->userId; $data["lastPostTime"] = $time; $data["private"] = !empty($membersAllowed); $data["countPosts"] = $isDraft ? 0 : 1; // Insert the conversation into the database. $conversationId = parent::create($data); // Update the member's conversation count. ET::SQL()->update("member")->set("countConversations", "countConversations + 1", false)->where("memberId", ET::$session->userId)->exec(); // Update the channel's converastion count. ET::SQL()->update("channel")->set("countConversations", "countConversations + 1", false)->where("channelId", $data["channelId"])->exec(); // Whip up a little array fo conversation details for this model's functions to work with. $conversation = array("conversationId" => $conversationId, "title" => $data["title"], "canReply" => true, "labels" => array()); // Add the first post or save the draft. $postId = null; if ($isDraft) { $this->setDraft($conversation, ET::$session->userId, $content); } else { $postId = ET::postModel()->create($conversationId, ET::$session->userId, $content); // If the conversation is private, send out notifications to the allowed members. if (!empty($membersAllowed)) { $memberIds = array(); foreach ($membersAllowed as $member) { if ($member["type"] == "member") { $memberIds[] = $member["id"]; } } ET::conversationModel()->privateAddNotification($conversation, $memberIds, true); } } // If the conversation is private, add the allowed members to the database. if (!empty($membersAllowed)) { $inserts = array(); foreach ($membersAllowed as $member) { $inserts[] = array($conversationId, $member["type"], $member["id"], 1); } ET::SQL()->insert("member_conversation")->setMultiple(array("conversationId", "type", "id", "allowed"), $inserts)->setOnDuplicateKey("allowed", 1)->exec(); } return array($conversationId, $postId); }
/** * Start a new converastion. Assumes the creator is the currently logged in user. * * @param array $data An array of the conversation's details: title, channelId, content. * @param array $membersAllowed An array of entities allowed to view the conversation, in the same format * as the return value of getMembersAllowed() * @param bool $isDraft Whether or not the conversation is a draft. * @return bool|array An array containing the new conversation ID and the new post ID, or false if * there was an error. */ public function create($data, $membersAllowed = array(), $isDraft = false) { // We can't do this if we're not logged in. if (!ET::$session->user) { return false; } // If the title is blank but the user is only saving a draft, call it "Untitled conversation." if ($isDraft and !$data["title"]) { $data["title"] = T("Untitled conversation"); } // Check for errors; validate the title and the post content. $this->validate("title", $data["title"], array($this, "validateTitle")); $this->validate("content", $data["content"], array(ET::postModel(), "validateContent")); $content = $data["content"]; unset($data["content"]); // Flood control! if (ET::$session->isFlooding()) { $this->error("flooding", sprintf(T("message.waitToReply"), C("esoTalk.conversation.timeBetweenPosts"))); } // Make sure that we have permission to post in this channel. $data["channelId"] = (int) $data["channelId"]; if (!ET::channelModel()->hasPermission($data["channelId"], "start")) { $this->error("channelId", "invalidChannel"); } // Did we encounter any errors? Don't continue. if ($this->errorCount()) { return false; } // Start a notification group. This means that for all notifications sent out until endNotifcationGroup // is called, each individual user will receive a maximum of one. ET::activityModel()->startNotificationGroup(); // Add some more data fields to insert into the database. $time = time(); $data["startMemberId"] = ET::$session->userId; $data["startTime"] = $time; $data["lastPostMemberId"] = ET::$session->userId; $data["lastPostTime"] = $time; $data["private"] = !empty($membersAllowed); $data["countPosts"] = $isDraft ? 0 : 1; // Insert the conversation into the database. $conversationId = parent::create($data); // Update the member's conversation count. ET::SQL()->update("member")->set("countConversations", "countConversations + 1", false)->where("memberId", ET::$session->userId)->exec(); // Update the channel's converastion count. ET::SQL()->update("channel")->set("countConversations", "countConversations + 1", false)->where("channelId", $data["channelId"])->exec(); // Get our newly created conversation. $conversation = $this->getById($conversationId); // Add the first post or save the draft. $postId = null; if ($isDraft) { $this->setDraft($conversation, ET::$session->userId, $content); } else { $postId = ET::postModel()->create($conversationId, ET::$session->userId, $content, $conversation["title"]); // If the conversation is private, send out notifications to the allowed members. if (!empty($membersAllowed)) { $memberIds = array(); foreach ($membersAllowed as $member) { if ($member["type"] == "member") { $memberIds[] = $member["id"]; } } ET::conversationModel()->privateAddNotification($conversation, $memberIds, true, $content); } } // If the conversation is private, add the allowed members to the database. if (!empty($membersAllowed)) { $inserts = array(); foreach ($membersAllowed as $member) { $inserts[] = array($conversationId, $member["type"], $member["id"], 1); } ET::SQL()->insert("member_conversation")->setMultiple(array("conversationId", "type", "id", "allowed"), $inserts)->setOnDuplicateKey("allowed", 1)->exec(); } // If the user has the "star on reply" or "star private" preferences checked, star the conversation. if (ET::$session->preference("starOnReply") or $conversation["private"] and ET::$session->preference("starPrivate")) { $this->setStatus($conversation["conversationId"], ET::$session->userId, array("starred" => true)); } $this->trigger("createAfter", array($conversation, $postId, $content)); ET::activityModel()->endNotificationGroup(); return array($conversationId, $postId); }
public function __construct() { parent::__construct("reputation"); }
/** * Create a post in the specified conversation. * * This function will go through the post content and notify any members who are @mentioned. * * @param int $conversationId The ID of the conversation to create the post in. * @param int $memberId The ID of the author of the post. * @param string $content The post content. * @param string $title The title of the conversation (so it can be added alongside the post, for fulltext purposes.) * @return bool|int The new post's ID, or false if there were errors. */ public function create($conversationId, $memberId, $content, $title = "") { // Validate the post content. $this->validate("content", $content, array($this, "validateContent")); if ($this->errorCount()) { return false; } // Prepare the post details for the query. $data = array("conversationId" => $conversationId, "memberId" => $memberId, "time" => time(), "content" => $content, "title" => $title); $id = parent::create($data); // Update the member's post count. ET::SQL()->update("member")->set("countPosts", "countPosts + 1", false)->where("memberId", $memberId)->exec(); // Update the channel's post count. ET::SQL()->update("channel")->set("countPosts", "countPosts + 1", false)->where("channelId", ET::SQL()->select("channelId")->from("conversation")->where("conversationId=:conversationId")->bind(":conversationId", $conversationId)->exec()->result())->exec(); // Parse the post content for @mentions, and notify any members who were mentioned. if (C("esoTalk.format.mentions")) { $names = ET::formatter()->getMentions($content); if (count($names)) { // Get the member details from the database. $sql = ET::SQL()->where("m.username IN (:names)")->bind(":names", $names)->where("m.memberId != :userId")->bind(":userId", $memberId); $members = ET::memberModel()->getWithSQL($sql); $data = array("conversationId" => $conversationId, "postId" => (int) $id, "title" => $title); $emailData = array("content" => $content); $i = 0; foreach ($members as $member) { // Only send notifications to the first 10 members who are mentioned to prevent abuse of the system. if ($i++ > 10) { break; } // Check if this member is allowed to view this conversation before sending them a notification. $sql = ET::SQL()->select("conversationId")->from("conversation c")->where("conversationId", $conversationId); ET::conversationModel()->addAllowedPredicate($sql, $member); if (!$sql->exec()->numRows()) { continue; } ET::activityModel()->create("mention", $member, ET::$session->user, $data, $emailData); } } } return $id; }
/** * Update a member's details. * * @param array $values An array of fields to update and their values. * @param array $wheres An array of WHERE conditions. * @return bool|ETSQLResult */ public function update($values, $wheres = array()) { if (isset($values["username"])) { $values["username"] = trim($values["username"]); $this->validate("username", $values["username"], array($this, "validateUsername")); } if (isset($values["email"])) { $this->validate("email", $values["email"], array($this, "validateEmail")); } if (isset($values["password"])) { $this->validate("password", $values["password"], array($this, "validatePassword")); $values["password"] = $this->hashPassword($values["password"]); } // Serialize preferences. if (isset($values["preferences"])) { $values["preferences"] = serialize($values["preferences"]); } if ($this->errorCount()) { return false; } return parent::update($values, $wheres); }
/** * Class constructor; sets up the base model functions to use the group table. * * @return void */ public function __construct() { parent::__construct("group"); }
public function __construct() { parent::__construct("attachment"); }