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); }
/** * Create a member. * * @param array $values An array of fields and their values to insert. * @return bool|int The new member ID, or false if there were errors. */ public function create(&$values) { // Validate the username, email, and password. $this->validate("username", $values["username"], array($this, "validateUsername")); $this->validate("email", $values["email"], array($this, "validateEmail")); $this->validate("password", $values["password"], array($this, "validatePassword")); // Hash the password and set the join time. $values["password"] = $this->hashPassword($values["password"]); $values["joinTime"] = time(); // MD5 the "reset password" hash for storage (for extra safety). $oldHash = isset($values["resetPassword"]) ? $values["resetPassword"] : null; if (isset($values["resetPassword"])) { $values["resetPassword"] = md5($values["resetPassword"]); } // Set default preferences. if (empty($values["preferences"])) { $preferences = array("email.privateAdd", "email.post", "starOnReply"); foreach ($preferences as $p) { $values["preferences"][$p] = C("esoTalk.preferences." . $p); } } $values["preferences"] = serialize($values["preferences"]); if ($this->errorCount()) { return false; } // Delete any members with the same email or username but who haven't confirmed their email address. ET::SQL()->delete()->from("member")->where("email=:email OR username=:username")->bind(":email", $values["email"])->bind(":username", $values["username"])->where("confirmedEmail", 0)->exec(); $memberId = parent::create($values); $values["memberId"] = $memberId; // Create "join" activity for this member. ET::activityModel()->create("join", $values); // Go through the list of channels and unsubscribe from any ones that have that attribute set. $channels = ET::channelModel()->getAll(); $inserts = array(); foreach ($channels as $channel) { if (!empty($channel["attributes"]["defaultUnsubscribed"])) { $inserts[] = array($memberId, $channel["channelId"], 1); } } if (count($inserts)) { ET::SQL()->insert("member_channel")->setMultiple(array("memberId", "channelId", "unsubscribed"), $inserts)->exec(); } // Revert the "reset password" hash to what it was before we MD5'd it. $values["resetPassword"] = $oldHash; return $memberId; }
/** * Create a member. * * @param array $values An array of fields and their values to insert. * @return bool|int The new member ID, or false if there were errors. */ public function create(&$values) { // 2016/02 以下チェック不要 // // Validate the username, email, and password. // $this->validate("username", $values["username"], array($this, "validateUsername")); // $this->validate("email", $values["email"], array($this, "validateEmail")); // $this->validate("password", $values["password"], array($this, "validatePassword")); // // // Hash the password and set the join time. // $values["password"] = $this->hashPassword($values["password"]); // $values["joinTime"] = time(); // SWCユーザID $memberId = $values['memberId']; // Set default preferences. if (empty($values["preferences"])) { $preferences = array("email.privateAdd", "email.post", "starOnReply"); foreach ($preferences as $p) { $values["preferences"][$p] = C("esoTalk.preferences." . $p); } } $values["preferences"] = serialize($values["preferences"]); if ($this->errorCount()) { return false; } // メンバーテーブル追加登録 $memberId = parent::create($values); // $values["memberId"] = $memberId; $this->trigger("createAfter", array($values)); // TODO: "join" のアクティビティログ登録確認要 // Create "join" activity for this member. // ET::activityModel()->create("join", $values); // Go through the list of channels and unsubscribe from any ones that have that attribute set. $channels = ET::channelModel()->getAll(); $inserts = array(); foreach ($channels as $channel) { if (!empty($channel["attributes"]["defaultUnsubscribed"])) { $inserts[] = array($memberId, $channel["channelId"], 1); } } if (count($inserts)) { ET::SQL()->insert("member_channel")->setMultiple(array("memberId", "channelId", "unsubscribed"), $inserts)->exec(); } return $memberId; }
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; }
/** * 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"]; }
/** * Create a channel. * * @param array $values An array of fields and their values to insert. * @return bool|int The new channel ID, or false if there are errors. */ public function create($values) { // Check that a channel title has been entered. if (!isset($values["title"])) { $values["title"] = ""; } $this->validate("title", $values["title"], array($this, "validateTitle")); // Check that a channel slug has been entered and isn't already in use. if (!isset($values["slug"])) { $values["slug"] = ""; } $this->validate("slug", $values["slug"], array($this, "validateSlug")); // Add the channel at the end at the root level. $right = ET::SQL()->select("MAX(rgt)")->from("channel")->exec()->result(); $values["lft"] = ++$right; $values["rgt"] = ++$right; // Collapse the attributes. if (isset($values["attributes"])) { $values["attributes"] = serialize($value["attributes"]); } if ($this->errorCount()) { return false; } $channelId = parent::create($values); // Reset channels in the global cache. ET::$cache->remove(self::CACHE_KEY); return $channelId; }
/** * 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); }
/** * 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; }