/**
* Save conversation from form submission.
*
* @since 2.0.0
* @access public
*
* @param array $FormPostValues Values submitted via form.
* @param ConversationMessageModel $MessageModel Message starting the conversation.
* @return int Unique ID of conversation created or updated.
*/
public function save($FormPostValues, $MessageModel)
{
// Define the primary key in this model's table.
$this->defineSchema();
$MessageModel->defineSchema();
$this->EventArguments['FormPostValues'] = $FormPostValues;
$this->fireEvent('BeforeSaveValidation');
if (!val('RecipientUserID', $FormPostValues) && isset($FormPostValues['To'])) {
$To = explode(',', $FormPostValues['To']);
$To = array_map('trim', $To);
$RecipientUserIDs = $this->SQL->select('UserID')->from('User')->whereIn('Name', $To)->get()->resultArray();
$RecipientUserIDs = array_column($RecipientUserIDs, 'UserID');
$FormPostValues['RecipientUserID'] = $RecipientUserIDs;
}
if (c('Garden.ForceInputFormatter')) {
$FormPostValues['Format'] = c('Garden.InputFormatter');
}
// Add & apply any extra validation rules:
$this->Validation->applyRule('Body', 'Required');
$MessageModel->Validation->applyRule('Body', 'Required');
// Make sure that there is at least one recipient
$this->Validation->addRule('OneOrMoreArrayItemRequired', 'function:ValidateOneOrMoreArrayItemRequired');
$this->Validation->applyRule('RecipientUserID', 'OneOrMoreArrayItemRequired');
// Add insert/update fields
$this->addInsertFields($FormPostValues);
$this->addUpdateFields($FormPostValues);
// Validate the form posted values
$ConversationID = false;
if ($this->validate($FormPostValues) && $MessageModel->validate($FormPostValues) && !$this->checkForSpam('Conversation')) {
$Fields = $this->Validation->validationFields();
// All fields on the form that relate to the schema
// Define the recipients, and make sure that the sender is in the list
$RecipientUserIDs = val('RecipientUserID', $Fields, 0);
if (!in_array($FormPostValues['InsertUserID'], $RecipientUserIDs)) {
$RecipientUserIDs[] = $FormPostValues['InsertUserID'];
}
// Also make sure there are no duplicates in the recipient list
$RecipientUserIDs = array_unique($RecipientUserIDs);
sort($RecipientUserIDs);
$Fields = $this->Validation->schemaValidationFields();
// All fields on the form that relate to the schema
$ConversationID = $this->SQL->insert($this->Name, $Fields);
$FormPostValues['ConversationID'] = $ConversationID;
// Notify the message model that it's being called as a direct result
// of a new conversation being created. As of now, this is being used
// so that spam checks between new conversations and conversation
// messages each have a separate counter. Without this, a new
// conversation will cause itself AND the message model spam counter
// to increment by 1.
$MessageID = $MessageModel->save($FormPostValues, null, array('NewConversation' => true));
$this->SQL->update('Conversation')->set('FirstMessageID', $MessageID)->where('ConversationID', $ConversationID)->put();
// Now that the message & conversation have been inserted, insert all of the recipients
foreach ($RecipientUserIDs as $UserID) {
$CountReadMessages = $UserID == $FormPostValues['InsertUserID'] ? 1 : 0;
$this->SQL->options('Ignore', true)->insert('UserConversation', array('UserID' => $UserID, 'ConversationID' => $ConversationID, 'LastMessageID' => $MessageID, 'CountReadMessages' => $CountReadMessages, 'DateConversationUpdated' => $FormPostValues['DateUpdated']));
}
// And update the CountUnreadConversations count on each user related to the discussion.
$this->updateUserUnreadCount(array_diff($RecipientUserIDs, array($FormPostValues['InsertUserID'])));
$this->updateParticipantCount($ConversationID);
$this->EventArguments['Recipients'] = $RecipientUserIDs;
$Conversation = $this->getID($ConversationID);
$this->EventArguments['Conversation'] = $Conversation;
$Message = $MessageModel->getID($MessageID, DATASET_TYPE_ARRAY);
$this->EventArguments['Message'] = $Message;
$this->fireEvent('AfterAdd');
// Add notifications (this isn't done by the conversationmessagemodule
// because the conversation has not yet been created at the time they are
// inserted)
$UnreadData = $this->SQL->select('uc.UserID')->from('UserConversation uc')->where('uc.ConversationID', $ConversationID)->where('uc.UserID <>', $FormPostValues['InsertUserID'])->get();
$Activity = array('ActivityType' => 'ConversationMessage', 'ActivityUserID' => $FormPostValues['InsertUserID'], 'HeadlineFormat' => t('HeadlineFormat.ConversationMessage', '{ActivityUserID,User} sent you a <a href="{Url,html}">message</a>'), 'RecordType' => 'Conversation', 'RecordID' => $ConversationID, 'Story' => val('Body', $FormPostValues), 'Format' => val('Format', $FormPostValues, c('Garden.InputFormatter')), 'Route' => "/messages/{$ConversationID}#Message_{$MessageID}");
$Subject = val('Subject', $Fields);
if ($Subject) {
$Activity['HeadlineFormat'] = $Subject;
}
$ActivityModel = new ActivityModel();
foreach ($UnreadData->result() as $User) {
$Activity['NotifyUserID'] = $User->UserID;
$ActivityModel->queue($Activity, 'ConversationMessage');
}
$ActivityModel->saveQueue();
} else {
// Make sure that all of the validation results from both validations are present for view by the form
foreach ($MessageModel->validationResults() as $FieldName => $Results) {
foreach ($Results as $Result) {
$this->Validation->addValidationResult($FieldName, $Result);
}
}
}
return $ConversationID;
}