/** * To be used for basic registration, and captcha registration */ public function InsertForBasic($FormPostValues) { $UserID = FALSE; // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Email', 'Email'); // TODO: DO I NEED THIS?! // Make sure that the checkbox val for email is saved as the appropriate enum if (array_key_exists('ShowEmail', $FormPostValues)) { $FormPostValues['ShowEmail'] = ForceBool($FormPostValues['ShowEmail'], '0', '1', '0'); } $this->AddInsertFields($FormPostValues); if ($this->Validate($FormPostValues, TRUE) === TRUE) { $Fields = $this->Validation->ValidationFields(); // All fields on the form that need to be validated (including non-schema field rules defined above) $Username = ArrayValue('Name', $Fields); $Email = ArrayValue('Email', $Fields); $Fields = $this->Validation->SchemaValidationFields(); // Only fields that are present in the schema $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $Fields['Password'] = array('md5' => $Fields['Password']); // If in Captcha registration mode, check the captcha value if (Gdn::Config('Garden.Registration.Method') == 'Captcha') { $CaptchaPublicKey = ArrayValue('Garden.Registration.CaptchaPublicKey', $FormPostValues, ''); $CaptchaValid = ValidateCaptcha($CaptchaPublicKey); if ($CaptchaValid !== TRUE) { $this->Validation->AddValidationResult('Garden.Registration.CaptchaPublicKey', 'The reCAPTCHA value was not entered correctly. Please try again.'); return FALSE; } } if (!$this->ValidateUniqueFields($Username, $Email)) { return FALSE; } // Define the other required fields: $Fields['Email'] = $Email; // And insert the new user $UserID = $this->_Insert($Fields); AddActivity($UserID, 'Join', T('Welcome Aboard!')); // Now update the role settings if necessary $RoleIDs = Gdn::Config('Garden.Registration.DefaultRoles', array(8)); $this->SaveRoles($UserID, $RoleIDs, FALSE); } return $UserID; }
public function Save($FormPostValues) { // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $this->Validation->ApplyRule('ReplyCommentID', 'Required'); // Add/define extra fields for saving $ReplyCommentID = intval(ArrayValue('ReplyCommentID', $FormPostValues, 0)); $Discussion = $this->SQL->Select('c.DiscussionID, d.Name, d.CategoryID')->From('Comment c')->Join('Discussion d', 'd.DiscussionID = c.DiscussionID')->Where('c.CommentID', $ReplyCommentID)->Get()->FirstRow(); if (is_object($Discussion)) { $FormPostValues['DiscussionID'] = $Discussion->DiscussionID; } $CommentID = ArrayValue('CommentID', $FormPostValues); $Insert = $CommentID === FALSE ? TRUE : FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); // Check for spam $this->CheckForSpam('Comment'); // Comments and replies use the same spam check rules } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validation->Validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $Session = Gdn::Session(); // Make sure there are no reply drafts. if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->UpdateReplyCount($ReplyCommentID); // Report user-comment activity $this->RecordActivity($ReplyCommentID, $Session->UserID, $CommentID); } // Index the comment. $Search = Gdn::Factory('SearchModel'); if (!is_null($Search)) { // Index the discussion. $Document = array('TableName' => 'Comment', 'PrimaryID' => $CommentID, 'PermissionJunctionID' => $Discussion->CategoryID, 'Title' => $Discussion->Name, 'Summary' => $Fields['Body'], 'Url' => '/discussion/comment/' . $ReplyCommentID . '/#Comment_' . $CommentID, 'InsertUserID' => $Session->UserID); $Search->Index($Document); } } return $CommentID; }
/** * Saves the category. * * @since 2.0.0 * @access public * * @param array $FormPostValue The values being posted back from the form. * @return int ID of the saved category. */ public function Save($FormPostValues) { // Define the primary key in this model's table. $this->DefineSchema(); // Get data from form $CategoryID = ArrayValue('CategoryID', $FormPostValues); $NewName = ArrayValue('Name', $FormPostValues, ''); $UrlCode = ArrayValue('UrlCode', $FormPostValues, ''); $AllowDiscussions = ArrayValue('AllowDiscussions', $FormPostValues, ''); $CustomPermissions = (bool) GetValue('CustomPermissions', $FormPostValues); // Is this a new category? $Insert = $CategoryID > 0 ? FALSE : TRUE; if ($Insert) { $this->AddInsertFields($FormPostValues); } $this->AddUpdateFields($FormPostValues); $this->Validation->ApplyRule('UrlCode', 'Required'); $this->Validation->ApplyRule('UrlCode', 'UrlStringRelaxed'); // Make sure that the UrlCode is unique among categories. $this->SQL->Select('CategoryID')->From('Category')->Where('UrlCode', $UrlCode); if ($CategoryID) { $this->SQL->Where('CategoryID <>', $CategoryID); } if ($this->SQL->Get()->NumRows()) { $this->Validation->AddValidationResult('UrlCode', 'The specified url code is already in use by another category.'); } // Prep and fire event. $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['CategoryID'] = $CategoryID; $this->FireEvent('BeforeSaveCategory'); // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, 'CategoryID'); $AllowDiscussions = ArrayValue('AllowDiscussions', $Fields) == '1' ? TRUE : FALSE; $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; if ($Insert === FALSE) { $OldCategory = $this->GetID($CategoryID, DATASET_TYPE_ARRAY); $AllowDiscussions = $OldCategory['AllowDiscussions']; // Force the allowdiscussions property $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; $this->Update($Fields, array('CategoryID' => $CategoryID)); // Check for a change in the parent category. if (isset($Fields['ParentCategoryID']) && $OldCategory['ParentCategoryID'] != $Fields['ParentCategoryID']) { $this->RebuildTree(); } else { $this->SetCache($CategoryID, $Fields); } } else { $CategoryID = $this->Insert($Fields); if ($CustomPermissions && $CategoryID) { $this->SQL->Put('Category', array('PermissionCategoryID' => $CategoryID), array('CategoryID' => $CategoryID)); } $this->RebuildTree(); // Safeguard to make sure that treeleft and treeright cols are added } // Save the permissions if ($AllowDiscussions && $CategoryID) { // Check to see if this category uses custom permissions. if ($CustomPermissions) { $PermissionModel = Gdn::PermissionModel(); $Permissions = $PermissionModel->PivotPermissions(GetValue('Permission', $FormPostValues, array()), array('JunctionID' => $CategoryID)); $PermissionModel->SaveAll($Permissions, array('JunctionID' => $CategoryID, 'JunctionTable' => 'Category')); if (!$Insert) { // Figure out my last permission and tree info. $Data = $this->SQL->Select('PermissionCategoryID, TreeLeft, TreeRight')->From('Category')->Where('CategoryID', $CategoryID)->Get()->FirstRow(DATASET_TYPE_ARRAY); // Update this category's permission. $this->SQL->Put('Category', array('PermissionCategoryID' => $CategoryID), array('CategoryID' => $CategoryID)); // Update all of my children that shared my last category permission. $this->SQL->Put('Category', array('PermissionCategoryID' => $CategoryID), array('TreeLeft >' => $Data['TreeLeft'], 'TreeRight <' => $Data['TreeRight'], 'PermissionCategoryID' => $Data['PermissionCategoryID'])); self::ClearCache(); } } elseif (!$Insert) { // Figure out my parent's permission. $NewPermissionID = $this->SQL->Select('p.PermissionCategoryID')->From('Category c')->Join('Category p', 'c.ParentCategoryID = p.CategoryID')->Where('c.CategoryID', $CategoryID)->Get()->Value('PermissionCategoryID', 0); if ($NewPermissionID != $CategoryID) { // Update all of my children that shared my last permission. $this->SQL->Put('Category', array('PermissionCategoryID' => $NewPermissionID), array('PermissionCategoryID' => $CategoryID)); self::ClearCache(); } // Delete my custom permissions. $this->SQL->Delete('Permission', array('JunctionTable' => 'Category', 'JunctionColumn' => 'PermissionCategoryID', 'JunctionID' => $CategoryID)); } } // Force the user permissions to refresh. Gdn::UserModel()->ClearPermissions(); // $this->RebuildTree(); } else { $CategoryID = FALSE; } return $CategoryID; }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } // Get the DiscussionID from the form so we know if we are inserting or updating. $DiscussionID = ArrayValue('DiscussionID', $FormPostValues, ''); $Insert = $DiscussionID == '' ? TRUE : FALSE; if ($Insert) { unset($FormPostValues['DiscussionID']); // If no categoryid is defined, grab the first available. if (ArrayValue('CategoryID', $FormPostValues) === FALSE) { $FormPostValues['CategoryID'] = $this->SQL->Get('Category', '', '', 1)->FirstRow()->CategoryID; } $this->AddInsertFields($FormPostValues); // $FormPostValues['LastCommentUserID'] = $Session->UserID; $FormPostValues['DateLastComment'] = Gdn_Format::ToDateTime(); } // Add the update fields because this table's default sort is by DateUpdated (see $this->Get()). $this->AddUpdateFields($FormPostValues); // Remove checkboxes from the fields if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { unset($FormPostValues['Announce']); } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { unset($FormPostValues['Closed']); } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { unset($FormPostValues['Sink']); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, make sure the user isn't spamming if (!$Insert || !$this->CheckForSpam('Discussion')) { $Fields = $this->Validation->SchemaValidationFields(); // All fields on the form that relate to the schema $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); // Remove the primary key from the fields for saving $Discussion = FALSE; if ($DiscussionID > 0) { $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); } else { $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $DiscussionID = $this->SQL->Insert($this->Name, $Fields); // Assign the new DiscussionID to the comment before saving $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['InsertFields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); // Notify users of mentions $DiscussionName = ArrayValue('Name', $Fields, ''); $Usernames = GetMentions($DiscussionName); $UserModel = Gdn::UserModel(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { AddActivity($Session->UserID, 'DiscussionMention', '', $User->UserID, '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName)); } } $DiscussionName = ArrayValue('Name', $Fields, ''); $this->RecordActivity($Session->UserID, $DiscussionID, $DiscussionName); } $Data = $this->SQL->Select('CategoryID')->From('Discussion')->Where('DiscussionID', $DiscussionID)->Get(); $CategoryID = FALSE; if ($Data->NumRows() > 0) { $CategoryID = $Data->FirstRow()->CategoryID; } $this->UpdateDiscussionCount($CategoryID); } } return $DiscussionID; }
/** * Insert or update a draft from form values. * * @since 2.0.0 * @access public * * @param array $FormPostValues Form values sent from form model. * @return int Unique ID of draft. */ public function save($FormPostValues) { $Session = Gdn::session(); // Define the primary key in this model's table. $this->defineSchema(); // Add & apply any extra validation rules: $this->Validation->applyRule('Body', 'Required'); $MaxCommentLength = Gdn::config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->applyRule('Body', 'Length'); } // Get the DraftID from the form so we know if we are inserting or updating. $DraftID = val('DraftID', $FormPostValues, ''); $Insert = $DraftID == '' ? true : false; if (!$DraftID) { unset($FormPostValues['DraftID']); } // Remove the discussionid from the form value collection if it's empty if (array_key_exists('DiscussionID', $FormPostValues) && $FormPostValues['DiscussionID'] == '') { unset($FormPostValues['DiscussionID']); } if ($Insert) { // If no categoryid is defined, grab the first available. if (val('CategoryID', $FormPostValues) === false) { $FormPostValues['CategoryID'] = $this->SQL->get('Category', '', '', 1)->firstRow()->CategoryID; } } // Add the update fields because this table's default sort is by DateUpdated (see $this->get()). $this->AddInsertFields($FormPostValues); $this->AddUpdateFields($FormPostValues); // Remove checkboxes from the fields if they were unchecked if (val('Announce', $FormPostValues, '') === false) { unset($FormPostValues['Announce']); } if (val('Closed', $FormPostValues, '') === false) { unset($FormPostValues['Closed']); } if (val('Sink', $FormPostValues, '') === false) { unset($FormPostValues['Sink']); } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['DraftID'] = $DraftID; $this->fireEvent('BeforeSaveDraft'); // Validate the form posted values if ($this->validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); // All fields on the form that relate to the schema $DraftID = intval(val('DraftID', $Fields, 0)); // If the post is new and it validates, make sure the user isn't spamming if ($DraftID > 0) { // Update the draft $Fields = RemoveKeyFromArray($Fields, 'DraftID'); // Remove the primary key from the fields for saving $this->SQL->put($this->Name, $Fields, array($this->PrimaryKey => $DraftID)); } else { // Insert the draft unset($Fields['DraftID']); $DraftID = $this->SQL->insert($this->Name, $Fields); $this->UpdateUser($Session->UserID); } // Fire an event that the draft was saved $this->EventArguments['Fields'] = $Fields; $this->EventArguments['DraftID'] = $DraftID; // Pass updated draft ID $this->fireEvent('AfterSaveDraft'); } return $DraftID; }
/** * Saves the category. * * @param array $FormPostValue The values being posted back from the form. */ public function Save($FormPostValues) { // Define the primary key in this model's table. $this->DefineSchema(); $CategoryID = ArrayValue('CategoryID', $FormPostValues); $NewName = ArrayValue('Name', $FormPostValues, ''); $Insert = $CategoryID > 0 ? FALSE : TRUE; if ($Insert) { $this->AddInsertFields($FormPostValues); } $this->AddUpdateFields($FormPostValues); // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, 'CategoryID'); $AllowDiscussions = ArrayValue('AllowDiscussions', $Fields) == '1' ? TRUE : FALSE; $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; if ($Insert === FALSE) { $OldCategory = $this->GetID($CategoryID); $AllowDiscussions = $OldCategory->AllowDiscussions; // Force the allowdiscussions property $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; $this->Update($Fields, array('CategoryID' => $CategoryID)); } else { // Make sure this category gets added to the end of the sort $SortData = $this->SQL->Select('Sort')->From('Category')->OrderBy('Sort', 'desc')->Limit(1)->Get()->FirstRow(); $Fields['Sort'] = $SortData ? $SortData->Sort + 1 : 1; $CategoryID = $this->Insert($Fields); if ($AllowDiscussions) { // If there are any parent categories, make this a child of the last one $ParentData = $this->SQL->Select('CategoryID')->From('Category')->Where('AllowDiscussions', '0')->OrderBy('Sort', 'desc')->Limit(1)->Get(); if ($ParentData->NumRows() > 0) { $this->SQL->Update('Category')->Set('ParentCategoryID', $ParentData->FirstRow()->CategoryID)->Where('CategoryID', $CategoryID)->Put(); } } else { // If there are any categories without parents, make this one the parent $this->SQL->Update('Category')->Set('ParentCategoryID', $CategoryID)->Where('ParentCategoryID is null')->Where('AllowDiscussions', '1')->Put(); } $this->Organize(); } // Save the permissions $PermissionModel = Gdn::PermissionModel(); $Permissions = $PermissionModel->PivotPermissions($FormPostValues['Permission'], array('JunctionID' => $CategoryID)); $PermissionModel->SaveAll($Permissions, array('JunctionID' => $CategoryID)); } else { $CategoryID = FALSE; } return $CategoryID; }
public function Save($FormPostValues) { // Define the primary key in this model's table. $this->DefineSchema(); $RoleID = ArrayValue('RoleID', $FormPostValues); $Insert = $RoleID > 0 ? FALSE : TRUE; if ($Insert) { // Figure out the next role ID which is the next biggest power of two. $MaxRoleID = $this->SQL->Select('r.RoleID', 'MAX')->From('Role r')->Get()->Value('RoleID', 0); $RoleID = pow(2, ceil(log($MaxRoleID + 1, 2))); $this->AddInsertFields($FormPostValues); $FormPostValues['RoleID'] = strval($RoleID); // string for validation } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { $this->Validation->AddValidationField('Permission', $FormPostValues); $Fields = $this->Validation->ValidationFields(); $Permissions = ArrayValue('Permission', $Fields); $Fields = $this->Validation->SchemaValidationFields(); if ($Insert === FALSE) { $Fields = RemoveKeyFromArray($Fields, 'RoleID'); // Don't update the primary key $this->Update($Fields, array('RoleID' => $RoleID)); } else { $this->Insert($Fields); } // Now update the role permissions $Role = $this->GetByRoleID($RoleID); $PermissionModel = Gdn::PermissionModel(); $Permissions = $PermissionModel->PivotPermissions($Permissions, array('RoleID' => $RoleID)); $PermissionModel->SaveAll($Permissions, array('RoleID' => $RoleID)); // Remove the cached permissions for all users with this role. $this->SQL->Update('User')->Join('UserRole', 'User.UserID = UserRole.UserID')->Set('Permissions', '')->Where(array('UserRole.RoleID' => $RoleID))->Put(); } else { $RoleID = FALSE; } return $RoleID; }
/** * Takes a set of form data ($Form->_PostValues), validates them, and * inserts or updates them to the datatabase. * * @param array $FormPostValues An associative array of $Field => $Value pairs that represent data posted * from the form in the $_POST or $_GET collection. * @param array $Settings If a custom model needs special settings in order to perform a save, they * would be passed in using this variable as an associative array. * @return unknown */ public function Save($FormPostValues, $Settings = FALSE) { // Define the primary key in this model's table. $this->DefineSchema(); // See if a primary key value was posted and decide how to save $PrimaryKeyVal = GetValue($this->PrimaryKey, $FormPostValues, FALSE); $Insert = $PrimaryKeyVal === FALSE ? TRUE : FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert) === TRUE) { $Fields = $this->Validation->ValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); // Don't try to insert or update the primary key if ($Insert === FALSE) { $this->Update($Fields, array($this->PrimaryKey => $PrimaryKeyVal)); } else { $PrimaryKeyVal = $this->Insert($Fields); } } else { $PrimaryKeyVal = FALSE; } return $PrimaryKeyVal; }
/** * To be used for basic registration, and captcha registration */ public function InsertForBasic($FormPostValues, $CheckCaptcha = TRUE, $Options = array()) { $RoleIDs = Gdn::Config('Garden.Registration.DefaultRoles'); if (!is_array($RoleIDs) || count($RoleIDs) == 0) { throw new Exception(T('The default role has not been configured.'), 400); } if (GetValue('SaveRoles', $Options)) { $RoleIDs = GetValue('RoleID', $FormPostValues); } $UserID = FALSE; // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules. if (GetValue('ValidateEmail', $Options, TRUE)) { $this->Validation->ApplyRule('Email', 'Email'); } // TODO: DO I NEED THIS?! // Make sure that the checkbox val for email is saved as the appropriate enum if (array_key_exists('ShowEmail', $FormPostValues)) { $FormPostValues['ShowEmail'] = ForceBool($FormPostValues['ShowEmail'], '0', '1', '0'); } if (array_key_exists('Banned', $FormPostValues)) { $FormPostValues['Banned'] = ForceBool($FormPostValues['Banned'], '0', '1', '0'); } $this->AddInsertFields($FormPostValues); if ($this->Validate($FormPostValues, TRUE) === TRUE) { $Fields = $this->Validation->ValidationFields(); // All fields on the form that need to be validated (including non-schema field rules defined above) $Username = ArrayValue('Name', $Fields); $Email = ArrayValue('Email', $Fields); $Fields = $this->Validation->SchemaValidationFields(); // Only fields that are present in the schema $Fields['Roles'] = $RoleIDs; $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); // If in Captcha registration mode, check the captcha value if ($CheckCaptcha && Gdn::Config('Garden.Registration.Method') == 'Captcha') { $CaptchaPublicKey = ArrayValue('Garden.Registration.CaptchaPublicKey', $FormPostValues, ''); $CaptchaValid = ValidateCaptcha($CaptchaPublicKey); if ($CaptchaValid !== TRUE) { $this->Validation->AddValidationResult('Garden.Registration.CaptchaPublicKey', 'The reCAPTCHA value was not entered correctly. Please try again.'); return FALSE; } } if (!$this->ValidateUniqueFields($Username, $Email)) { return FALSE; } // Check for spam. if (GetValue('ValidateSpam', $Options, TRUE)) { $ValidateSpam = $this->ValidateSpamRegistration($FormPostValues); if ($ValidateSpam !== TRUE) { return $ValidateSpam; } } // Define the other required fields: $Fields['Email'] = $Email; // And insert the new user $UserID = $this->_Insert($Fields, $Options); if ($UserID && !GetValue('NoActivity', $Options)) { $ActivityModel = new ActivityModel(); $ActivityModel->Save(array('ActivityUserID' => $UserID, 'ActivityType' => 'Registration', 'HeadlineFormat' => T('HeadlineFormat.Registration', '{ActivityUserID,You} joined.'), 'Story' => T('Welcome Aboard!')), FALSE, array('GroupBy' => 'ActivityTypeID')); } } return $UserID; }
/** * Saves the category. * * @since 2.0.0 * @access public * * @param array $FormPostValue The values being posted back from the form. * @return int ID of the saved category. */ public function save($FormPostValues) { // Define the primary key in this model's table. $this->defineSchema(); // Get data from form $CategoryID = val('CategoryID', $FormPostValues); $NewName = val('Name', $FormPostValues, ''); $UrlCode = val('UrlCode', $FormPostValues, ''); $AllowDiscussions = val('AllowDiscussions', $FormPostValues, ''); $CustomPermissions = (bool) GetValue('CustomPermissions', $FormPostValues); $CustomPoints = val('CustomPoints', $FormPostValues, null); if (isset($FormPostValues['AllowedDiscussionTypes']) && is_array($FormPostValues['AllowedDiscussionTypes'])) { $FormPostValues['AllowedDiscussionTypes'] = serialize($FormPostValues['AllowedDiscussionTypes']); } // Is this a new category? $Insert = $CategoryID > 0 ? false : true; if ($Insert) { $this->AddInsertFields($FormPostValues); } $this->AddUpdateFields($FormPostValues); $this->Validation->applyRule('UrlCode', 'Required'); $this->Validation->applyRule('UrlCode', 'UrlStringRelaxed'); // Url slugs cannot be the name of a CategoriesController method or fully numeric. $this->Validation->addRule('CategorySlug', 'regex:/^(?!(all|archives|discussions|index|table|[0-9]+)$).*/'); $this->Validation->applyRule('UrlCode', 'CategorySlug', 'Url code cannot be numeric or the name of an internal method.'); // Make sure that the UrlCode is unique among categories. $this->SQL->select('CategoryID')->from('Category')->where('UrlCode', $UrlCode); if ($CategoryID) { $this->SQL->where('CategoryID <>', $CategoryID); } if ($this->SQL->get()->numRows()) { $this->Validation->addValidationResult('UrlCode', 'The specified url code is already in use by another category.'); } // Prep and fire event. $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['CategoryID'] = $CategoryID; $this->fireEvent('BeforeSaveCategory'); // Validate the form posted values if ($this->validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, 'CategoryID'); $AllowDiscussions = val('AllowDiscussions', $Fields) == '1' ? true : false; $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; if ($Insert === false) { $OldCategory = $this->getID($CategoryID, DATASET_TYPE_ARRAY); if (null === val('AllowDiscussions', $FormPostValues, null)) { $AllowDiscussions = $OldCategory['AllowDiscussions']; // Force the allowdiscussions property } $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; // Figure out custom points. if ($CustomPoints !== null) { if ($CustomPoints) { $Fields['PointsCategoryID'] = $CategoryID; } else { $Parent = self::categories(val('ParentCategoryID', $Fields, $OldCategory['ParentCategoryID'])); $Fields['PointsCategoryID'] = val('PointsCategoryID', $Parent, 0); } } $this->update($Fields, array('CategoryID' => $CategoryID)); // Check for a change in the parent category. if (isset($Fields['ParentCategoryID']) && $OldCategory['ParentCategoryID'] != $Fields['ParentCategoryID']) { $this->RebuildTree(); } else { $this->SetCache($CategoryID, $Fields); } } else { $CategoryID = $this->insert($Fields); if ($CategoryID) { if ($CustomPermissions) { $this->SQL->put('Category', array('PermissionCategoryID' => $CategoryID), array('CategoryID' => $CategoryID)); } if ($CustomPoints) { $this->SQL->put('Category', array('PointsCategoryID' => $CategoryID), array('CategoryID' => $CategoryID)); } } $this->RebuildTree(); // Safeguard to make sure that treeleft and treeright cols are added } // Save the permissions if ($CategoryID) { // Check to see if this category uses custom permissions. if ($CustomPermissions) { $PermissionModel = Gdn::permissionModel(); $Permissions = $PermissionModel->PivotPermissions(val('Permission', $FormPostValues, array()), array('JunctionID' => $CategoryID)); $PermissionModel->SaveAll($Permissions, array('JunctionID' => $CategoryID, 'JunctionTable' => 'Category')); if (!$Insert) { // Figure out my last permission and tree info. $Data = $this->SQL->select('PermissionCategoryID, TreeLeft, TreeRight')->from('Category')->where('CategoryID', $CategoryID)->get()->firstRow(DATASET_TYPE_ARRAY); // Update this category's permission. $this->SQL->put('Category', array('PermissionCategoryID' => $CategoryID), array('CategoryID' => $CategoryID)); // Update all of my children that shared my last category permission. $this->SQL->put('Category', array('PermissionCategoryID' => $CategoryID), array('TreeLeft >' => $Data['TreeLeft'], 'TreeRight <' => $Data['TreeRight'], 'PermissionCategoryID' => $Data['PermissionCategoryID'])); self::ClearCache(); } } elseif (!$Insert) { // Figure out my parent's permission. $NewPermissionID = $this->SQL->select('p.PermissionCategoryID')->from('Category c')->join('Category p', 'c.ParentCategoryID = p.CategoryID')->where('c.CategoryID', $CategoryID)->get()->value('PermissionCategoryID', 0); if ($NewPermissionID != $CategoryID) { // Update all of my children that shared my last permission. $this->SQL->put('Category', array('PermissionCategoryID' => $NewPermissionID), array('PermissionCategoryID' => $CategoryID)); self::ClearCache(); } // Delete my custom permissions. $this->SQL->delete('Permission', array('JunctionTable' => 'Category', 'JunctionColumn' => 'PermissionCategoryID', 'JunctionID' => $CategoryID)); } } // Force the user permissions to refresh. Gdn::userModel()->ClearPermissions(); // $this->RebuildTree(); } else { $CategoryID = false; } return $CategoryID; }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } $CommentID = ArrayValue('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : FALSE; $Insert = $CommentID === FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $DiscussionModel = new Gdn_DiscussionModel(); $DiscussionID = ArrayValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); $DiscussionAuthorMentioned = FALSE; if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->EventArguments['CommentID'] = $CommentID; $this->FireEvent('SaveCommentAfter'); // Notify any users who were mentioned in the comment $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $DiscussionName = ''; foreach ($Usernames as $Username) { $User = $UserModel->GetWhere(array('Name' => $Username))->FirstRow(); if ($User && $User->UserID != $Session->UserID) { if ($User->UserID == $Discussion->InsertUserID) { $DiscussionAuthorMentioned = TRUE; } AddActivity($Session->UserID, 'CommentMention', Anchor(Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID); } } } // Record user-comment activity if ($Insert === TRUE && $Discussion !== FALSE && $DiscussionAuthorMentioned === FALSE) { $this->RecordActivity($Discussion, $Session->UserID, $CommentID); } // Only record activity if inserting a comment, not on edit. $this->UpdateCommentCount($DiscussionID); // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $Data = $this->SQL->Select('d.InsertUserID')->Select('d.DiscussionID', 'count', 'CountDiscussions')->From('Discussion d')->Join('Comment c', 'd.DiscussionID = c.DiscussionID')->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID')->Where('w.CountComments >', 0)->Where('c.InsertUserID', $Session->UserID)->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE)->GroupBy('d.InsertUserID')->Get(); if ($Data->NumRows() > 0) { $UserData = $Data->FirstRow(); $this->SQL->Update('User')->Set('CountUnreadDiscussions', $UserData->CountDiscussions)->Where('UserID', $UserData->InsertUserID)->Put(); } // Index the post. $Search = Gdn::Factory('SearchModel'); if (!is_null($Search)) { if (array_key_exists('Name', $FormPostValues) && array_key_exists('CategoryID', $FormPostValues)) { $Title = $FormPostValues['Name']; $CategoryID = $FormPostValues['CategoryID']; } else { // Get the name from the discussion. $Row = $this->SQL->GetWhere('Discussion', array('DiscussionID' => $DiscussionID))->FirstRow(); if (is_object($Row)) { $Title = $Row->Name; $CategoryID = $Row->CategoryID; } } $Offset = $this->GetOffset($CommentID); // Index the discussion. $Document = array('TableName' => 'Comment', 'PrimaryID' => $CommentID, 'PermissionJunctionID' => $CategoryID, 'Title' => $Title, 'Summary' => $FormPostValues['Body'], 'Url' => '/discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, 'InsertUserID' => $Session->UserID); $Search->Index($Document, $Offset == 1 ? $Document['Title'] . ' ' . $Document['Summary'] : NULL); } $this->UpdateUser($Session->UserID); } } return $CommentID; }
/** * Saves the category. * * @param array $FormPostValue The values being posted back from the form. */ public function Save($FormPostValues) { // Define the primary key in this model's table. $this->DefineSchema(); $CategoryID = ArrayValue('CategoryID', $FormPostValues); $NewName = ArrayValue('Name', $FormPostValues, ''); $UrlCode = ArrayValue('UrlCode', $FormPostValues, ''); $Insert = $CategoryID > 0 ? FALSE : TRUE; if ($Insert) { $this->AddInsertFields($FormPostValues); } $this->AddUpdateFields($FormPostValues); $this->Validation->ApplyRule('UrlCode', 'Required'); $this->Validation->ApplyRule('UrlCode', 'UrlString', 'Url code can only contain letters, numbers, underscores and dashes.'); // Make sure that the UrlCode is unique among categories. $this->SQL->Select('CategoryID')->From('Category')->Where('UrlCode', $UrlCode); if ($CategoryID) { $this->SQL->Where('CategoryID <>', $CategoryID); } if ($this->SQL->Get()->NumRows()) { $this->Validation->AddValidationResult('UrlCode', 'The specified url code is already in use by another category.'); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, 'CategoryID'); $AllowDiscussions = ArrayValue('AllowDiscussions', $Fields) == '1' ? TRUE : FALSE; $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; if ($Insert === FALSE) { $OldCategory = $this->GetID($CategoryID); $AllowDiscussions = $OldCategory->AllowDiscussions; // Force the allowdiscussions property $Fields['AllowDiscussions'] = $AllowDiscussions ? '1' : '0'; $this->Update($Fields, array('CategoryID' => $CategoryID)); } else { // Make sure this category gets added to the end of the sort $SortData = $this->SQL->Select('Sort')->From('Category')->OrderBy('Sort', 'desc')->Limit(1)->Get()->FirstRow(); $Fields['Sort'] = $SortData ? $SortData->Sort + 1 : 1; $CategoryID = $this->Insert($Fields); if ($AllowDiscussions) { // If there are any parent categories, make this a child of the last one $ParentData = $this->SQL->Select('CategoryID')->From('Category')->Where('AllowDiscussions', '0')->OrderBy('Sort', 'desc')->Limit(1)->Get(); if ($ParentData->NumRows() > 0) { $this->SQL->Update('Category')->Set('ParentCategoryID', $ParentData->FirstRow()->CategoryID)->Where('CategoryID', $CategoryID)->Put(); } } else { // If there are any categories without parents, make this one the parent $this->SQL->Update('Category')->Set('ParentCategoryID', $CategoryID)->Where('ParentCategoryID is null')->Where('AllowDiscussions', '1')->Put(); } $this->Organize(); } // Save the permissions if ($AllowDiscussions) { $PermissionModel = Gdn::PermissionModel(); $Permissions = $PermissionModel->PivotPermissions($FormPostValues['Permission'], array('JunctionID' => $CategoryID)); $PermissionModel->SaveAll($Permissions, array('JunctionID' => $CategoryID)); } // Force the user permissions to refresh. $this->SQL->Put('User', array('Permissions' => ''), array('Permissions <>' => '')); } else { $CategoryID = FALSE; } return $CategoryID; }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } $CommentID = ArrayValue('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : FALSE; $Insert = $CommentID === FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); $DiscussionModel = new DiscussionModel(); $DiscussionID = ArrayValue('DiscussionID', $Fields); $Discussion = $DiscussionModel->GetID($DiscussionID); if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->EventArguments['CommentID'] = $CommentID; // IsNewDiscussion is passed when the first comment for new discussions are created. $this->EventArguments['IsNewDiscussion'] = ArrayValue('IsNewDiscussion', $FormPostValues); $this->FireEvent('AfterSaveComment'); // Notify any users who were mentioned in the comment $Usernames = GetMentions($Fields['Body']); $UserModel = Gdn::UserModel(); $Story = ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { $NotifiedUsers[] = $User->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $User->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } // Notify users who have bookmarked the discussion $BookmarkData = $DiscussionModel->GetBookmarkUsers($DiscussionID); foreach ($BookmarkData->Result() as $Bookmark) { if (!in_array($Bookmark->UserID, $NotifiedUsers) && $Bookmark->UserID != $Session->UserID) { $NotifiedUsers[] = $Bookmark->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'BookmarkComment', Anchor(Gdn_Format::Text($Discussion->Name), 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID), $Bookmark->UserID, '', 'discussion/comment/' . $CommentID . '/#Comment_' . $CommentID, FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } } // Record user-comment activity if ($Insert === TRUE && $Discussion !== FALSE && !in_array($Session->UserID, $NotifiedUsers)) { $this->RecordActivity($Discussion, $Session->UserID, $CommentID); } $this->UpdateCommentCount($DiscussionID); // Update the discussion author's CountUnreadDiscussions (ie. // the number of discussions created by the user that s/he has // unread messages in) if this comment was not added by the // discussion author. $Data = $this->SQL->Select('d.InsertUserID')->Select('d.DiscussionID', 'count', 'CountDiscussions')->From('Discussion d')->Join('Comment c', 'd.DiscussionID = c.DiscussionID')->Join('UserDiscussion w', 'd.DiscussionID = w.DiscussionID and w.UserID = d.InsertUserID')->Where('w.CountComments >', 0)->Where('c.InsertUserID', $Session->UserID)->Where('c.InsertUserID <>', 'd.InsertUserID', TRUE, FALSE)->GroupBy('d.InsertUserID')->Get(); if ($Data->NumRows() > 0) { $UserData = $Data->FirstRow(); $this->SQL->Update('User')->Set('CountUnreadDiscussions', $UserData->CountDiscussions)->Where('UserID', $UserData->InsertUserID)->Put(); } $this->UpdateUser($Session->UserID); } } return $CommentID; }
/** * Inserts or updates the discussion via form values. * * Events: BeforeSaveDiscussion, AfterSaveDiscussion. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data sent from the form model. * @return int $DiscussionID Unique ID of the discussion. */ public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } // Get the DiscussionID from the form so we know if we are inserting or updating. $DiscussionID = ArrayValue('DiscussionID', $FormPostValues, ''); // See if there is a source ID. if (array_key_exists('SourceID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', ArrayTranslate($FormPostValues, array('Source', 'SourceID')))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } $Insert = $DiscussionID == '' ? TRUE : FALSE; $this->EventArguments['Insert'] = $Insert; if ($Insert) { unset($FormPostValues['DiscussionID']); // If no categoryid is defined, grab the first available. if (ArrayValue('CategoryID', $FormPostValues) === FALSE) { $FormPostValues['CategoryID'] = $this->SQL->Get('Category', 'CategoryID', '', 1)->FirstRow()->CategoryID; } $this->AddInsertFields($FormPostValues); // $FormPostValues['LastCommentUserID'] = $Session->UserID; $FormPostValues['DateLastComment'] = Gdn_Format::ToDateTime(); } // Add the update fields because this table's default sort is by DateUpdated (see $this->Get()). $this->AddUpdateFields($FormPostValues); // Set checkbox values to zero if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { $FormPostValues['Announce'] = 0; } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { $FormPostValues['Closed'] = 0; } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { $FormPostValues['Sink'] = 0; } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('BeforeSaveDiscussion'); // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, make sure the user isn't spamming if (!$Insert || !$this->CheckForSpam('Discussion')) { // Get all fields on the form that relate to the schema $Fields = $this->Validation->SchemaValidationFields(); // Get DiscussionID if one was sent $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); // Remove the primary key from the fields for saving $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); $Discussion = FALSE; $StoredCategoryID = FALSE; if ($DiscussionID > 0) { // Updating $Stored = $this->GetID($DiscussionID); // Clear the cache if necessary. if (GetValue('Announce', $Stored) != GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements', 'Announcements_' . GetValue('CategoryID', $Fields)); $Announce = GetValue('Announce', $Discussion); $this->SQL->Cache($CacheKeys); } $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); $Fields['DiscussionID'] = $DiscussionID; LogModel::LogChange('Edit', 'Discussion', (array) $Fields, (array) $Stored); if ($Stored->CategoryID != $Fields['CategoryID']) { $StoredCategoryID = $Stored->CategoryID; } } else { // Inserting. if (!GetValue('Format', $Fields)) { $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); } // Check for spam. $Spam = SpamModel::IsSpam('Discussion', $Fields); // Clear the cache if necessary. if (GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements', 'Announcements_' . GetValue('CategoryID', $Fields)); $Announce = GetValue('Announce', $Discussion); $this->SQL->Cache($CacheKeys); } if (!$Spam) { $DiscussionID = $this->SQL->Insert($this->Name, $Fields); } else { return SPAM; } // Assign the new DiscussionID to the comment before saving $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; // Notify users of mentions $DiscussionName = ArrayValue('Name', $Fields, ''); $Usernames = GetMentions($DiscussionName); $UserModel = Gdn::UserModel(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { AddActivity($Session->UserID, 'DiscussionMention', '', $User->UserID, '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName)); } } // Notify any users who were mentioned in the comment $DiscussionName = ArrayValue('Name', $Fields, ''); $Story = ArrayValue('Body', $Fields, ''); $Usernames = GetMentions($Story); $NotifiedUsers = array(); foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if ($User && $User->UserID != $Session->UserID) { $NotifiedUsers[] = $User->UserID; $ActivityModel = new ActivityModel(); $ActivityID = $ActivityModel->Add($Session->UserID, 'CommentMention', Anchor(Gdn_Format::Text($DiscussionName), '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName), FALSE), $User->UserID, '', '/discussion/' . $DiscussionID . '/' . Gdn_Format::Url($DiscussionName), FALSE); $ActivityModel->SendNotification($ActivityID, $Story); } } $this->RecordActivity($Session->UserID, $DiscussionID, $DiscussionName); try { $Fields['DiscussionID'] = $DiscussionID; $this->NotifyNewDiscussion($Fields); } catch (Exception $Ex) { throw $Ex; } } // Get CategoryID of this discussion $Data = $this->SQL->Select('CategoryID')->From('Discussion')->Where('DiscussionID', $DiscussionID)->Get(); $CategoryID = FALSE; if ($Data->NumRows() > 0) { $CategoryID = $Data->FirstRow()->CategoryID; } // Update discussion counter for affected categories $this->UpdateDiscussionCount($CategoryID, $Insert ? $DiscussionID : FALSE); if ($StoredCategoryID) { $this->UpdateDiscussionCount($StoredCategoryID); } // Fire an event that the discussion was saved. $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['Fields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); } } return $DiscussionID; }
/** * Returns the xhtml for a list of checkboxes; sorted into groups related to * the TextField value of the dataset. * * @param string $FieldName The name of the field that is being displayed/posted with this input. It * should related directly to a field name in a user junction table. * ie. LUM_UserRole.RoleID * * @param mixed $DataSet The data to fill the options in the select list. Either an associative * array or a database dataset. ie. RoleID, Name from LUM_Role. * * @param mixed $ValueDataSet The data that should be checked in $DataSet. Either an associative array * or a database dataset. ie. RoleID from LUM_UserRole for a single user. * * @param array $Attributes An associative array of attributes for the select. Here is a list of * "special" attributes and their default values: * * Attribute Options Default * ------------------------------------------------------------------------ * ValueField The name of the field in 'value' * $DataSet that contains the * option values. * TextField The name of the field in 'text' * $DataSet that contains the * option text. * * @return string */ public function CheckBoxGrid($FieldName, $DataSet, $ValueDataSet, $Attributes) { // Never display individual inline errors for these CheckBoxes $Attributes['InlineErrors'] = FALSE; $Return = ''; $CheckedValues = $ValueDataSet; if (is_object($ValueDataSet)) { $CheckedValues = ConsolidateArrayValuesByKey($ValueDataSet->ResultArray(), $FieldName); } $i = 1; if (is_object($DataSet)) { $ValueField = ArrayValueI('ValueField', $Attributes, 'value'); $TextField = ArrayValueI('TextField', $Attributes, 'text'); $LastGroup = ''; $Group = array(); $Rows = array(); $Cols = array(); $CheckBox = ''; foreach ($DataSet->Result() as $Data) { // Define the checkbox $Instance = $Attributes; $Instance = RemoveKeyFromArray($Instance, array('TextField', 'ValueField')); $Instance['value'] = $Data->{$ValueField}; $Instance['id'] = $FieldName . $i; if (is_array($CheckedValues) && in_array($Data->{$ValueField}, $CheckedValues)) { $Instance['checked'] = 'checked'; } $CheckBox = $this->CheckBox($FieldName . '[]', '', $Instance); // Organize the checkbox into an array for this group $CurrentTextField = $Data->{$TextField}; $aCurrentTextField = explode('.', $CurrentTextField); $aCurrentTextFieldCount = count($aCurrentTextField); $GroupName = array_shift($aCurrentTextField); $ColName = array_pop($aCurrentTextField); if ($aCurrentTextFieldCount >= 3) { $RowName = implode('.', $aCurrentTextField); if ($GroupName != $LastGroup && $LastGroup != '') { // Render the last group $Return .= $this->GetCheckBoxGridGroup($LastGroup, $Group, $Rows, $Cols); // Clean out the $Group array & Rowcount $Group = array(); $Rows = array(); $Cols = array(); } if (array_key_exists($ColName, $Group) === FALSE || is_array($Group[$ColName]) === FALSE) { $Group[$ColName] = array(); if (!in_array($ColName, $Cols)) { $Cols[] = $ColName; } } if (!in_array($RowName, $Rows)) { $Rows[] = $RowName; } $Group[$ColName][$RowName] = $CheckBox; $LastGroup = $GroupName; } ++$i; } } /*elseif (is_array($DataSet)) { foreach ($DataSet as $Text => $ID) { $Instance = $Attributes; $Instance = RemoveKeyFromArray($Instance, array('TextField', 'ValueField')); $Instance['id'] = $FieldName.$i; if (is_numeric($Text)) $Text = $ID; $Instance['value'] = $ID; if (in_array($ID, $CheckedValues)) $Instance['checked'] = 'checked'; $Return .= $this->CheckBox($FieldName.'[]', $Text, $Instance)."\n"; $i++; } } */ return $Return . $this->GetCheckBoxGridGroup($LastGroup, $Group, $Rows, $Cols); }
/** * Insert or update core data about the comment. * * Events: BeforeSaveComment, AfterSaveComment. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data from the form model. * @return int $CommentID */ public function save($FormPostValues) { $Session = Gdn::session(); // Define the primary key in this model's table. $this->defineSchema(); // Add & apply any extra validation rules: $this->Validation->applyRule('Body', 'Required'); $this->Validation->addRule('MeAction', 'function:ValidateMeAction'); $this->Validation->applyRule('Body', 'MeAction'); $MaxCommentLength = Gdn::config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->applyRule('Body', 'Length'); } $MinCommentLength = c('Vanilla.Comment.MinLength'); if ($MinCommentLength && is_numeric($MinCommentLength)) { $this->Validation->SetSchemaProperty('Body', 'MinLength', $MinCommentLength); $this->Validation->addRule('MinTextLength', 'function:ValidateMinTextLength'); $this->Validation->applyRule('Body', 'MinTextLength'); } // Validate $CommentID and whether this is an insert $CommentID = val('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : false; $Insert = $CommentID === false; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['CommentID'] = $CommentID; $this->fireEvent('BeforeSaveComment'); // Validate the form posted values if ($this->validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); if ($Insert === false) { // Log the save. LogModel::LogChange('Edit', 'Comment', array_merge($Fields, array('CommentID' => $CommentID))); // Save the new value. $this->SerializeRow($Fields); $this->SQL->put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden. if (!val('Format', $Fields) || c('Garden.ForceInputFormatter')) { $Fields['Format'] = Gdn::config('Garden.InputFormatter', ''); } // Check for spam $Spam = SpamModel::IsSpam('Comment', $Fields); if ($Spam) { return SPAM; } // Check for approval $ApprovalRequired = CheckRestriction('Vanilla.Approval.Require'); if ($ApprovalRequired && !val('Verified', Gdn::session()->User)) { $DiscussionModel = new DiscussionModel(); $Discussion = $DiscussionModel->getID(val('DiscussionID', $Fields)); $Fields['CategoryID'] = val('CategoryID', $Discussion); LogModel::insert('Pending', 'Comment', $Fields); return UNAPPROVED; } // Create comment. $this->SerializeRow($Fields); $CommentID = $this->SQL->insert($this->Name, $Fields); } if ($CommentID) { $this->EventArguments['CommentID'] = $CommentID; $this->EventArguments['Insert'] = $Insert; // IsNewDiscussion is passed when the first comment for new discussions are created. $this->EventArguments['IsNewDiscussion'] = val('IsNewDiscussion', $FormPostValues); $this->fireEvent('AfterSaveComment'); } } } // Update discussion's comment count $DiscussionID = val('DiscussionID', $FormPostValues); $this->UpdateCommentCount($DiscussionID, array('Slave' => false)); return $CommentID; }
/** * Inserts or updates the discussion via form values. * * Events: BeforeSaveDiscussion, AfterSaveDiscussion. * * @since 2.0.0 * @access public * * @param array $FormPostValues Data sent from the form model. * @return int $DiscussionID Unique ID of the discussion. */ public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $this->Validation->AddRule('MeAction', 'function:ValidateMeAction'); $this->Validation->ApplyRule('Body', 'MeAction'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } // Validate category permissions. $CategoryID = GetValue('CategoryID', $FormPostValues); if ($CategoryID > 0) { $Category = CategoryModel::Categories($CategoryID); if ($Category && !$Session->CheckPermission('Vanilla.Discussions.Add', TRUE, 'Category', GetValue('PermissionCategoryID', $Category))) { $this->Validation->AddValidationResult('CategoryID', 'You do not have permission to post in this category'); } } // Get the DiscussionID from the form so we know if we are inserting or updating. $DiscussionID = ArrayValue('DiscussionID', $FormPostValues, ''); // See if there is a source ID. if (GetValue('SourceID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', ArrayTranslate($FormPostValues, array('Source', 'SourceID')))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } elseif (GetValue('ForeignID', $FormPostValues)) { $DiscussionID = $this->SQL->GetWhere('Discussion', array('ForeignID' => $FormPostValues['ForeignID']))->Value('DiscussionID'); if ($DiscussionID) { $FormPostValues['DiscussionID'] = $DiscussionID; } } $Insert = $DiscussionID == '' ? TRUE : FALSE; $this->EventArguments['Insert'] = $Insert; if ($Insert) { unset($FormPostValues['DiscussionID']); // If no categoryid is defined, grab the first available. if (!GetValue('CategoryID', $FormPostValues) && !C('Vanilla.Categories.Use')) { $FormPostValues['CategoryID'] = GetValue('CategoryID', CategoryModel::DefaultCategory(), -1); } $this->AddInsertFields($FormPostValues); // The UpdateUserID used to be required. Just add it if it still is. if (!$this->Schema->GetProperty('UpdateUserID', 'AllowNull', TRUE)) { $FormPostValues['UpdateUserID'] = $FormPostValues['InsertUserID']; } // $FormPostValues['LastCommentUserID'] = $Session->UserID; $FormPostValues['DateLastComment'] = $FormPostValues['DateInserted']; } else { // Add the update fields. $this->AddUpdateFields($FormPostValues); } // Set checkbox values to zero if they were unchecked if (ArrayValue('Announce', $FormPostValues, '') === FALSE) { $FormPostValues['Announce'] = 0; } if (ArrayValue('Closed', $FormPostValues, '') === FALSE) { $FormPostValues['Closed'] = 0; } if (ArrayValue('Sink', $FormPostValues, '') === FALSE) { $FormPostValues['Sink'] = 0; } // Prep and fire event $this->EventArguments['FormPostValues'] =& $FormPostValues; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('BeforeSaveDiscussion'); // Validate the form posted values $this->Validate($FormPostValues, $Insert); $ValidationResults = $this->ValidationResults(); // If the body is not required, remove it's validation errors. $BodyRequired = C('Vanilla.DiscussionBody.Required', TRUE); if (!$BodyRequired && array_key_exists('Body', $ValidationResults)) { unset($ValidationResults['Body']); } if (count($ValidationResults) == 0) { // If the post is new and it validates, make sure the user isn't spamming if (!$Insert || !$this->CheckForSpam('Discussion')) { // Get all fields on the form that relate to the schema $Fields = $this->Validation->SchemaValidationFields(); // Get DiscussionID if one was sent $DiscussionID = intval(ArrayValue('DiscussionID', $Fields, 0)); // Remove the primary key from the fields for saving $Fields = RemoveKeyFromArray($Fields, 'DiscussionID'); $StoredCategoryID = FALSE; if ($DiscussionID > 0) { // Updating $Stored = $this->GetID($DiscussionID, DATASET_TYPE_ARRAY); // Clear the cache if necessary. if (GetValue('Announce', $Stored) != GetValue('Announce', $Fields)) { $CacheKeys = array('Announcements'); $this->SQL->Cache($CacheKeys); } self::SerializeRow($Fields); $this->SQL->Put($this->Name, $Fields, array($this->PrimaryKey => $DiscussionID)); SetValue('DiscussionID', $Fields, $DiscussionID); LogModel::LogChange('Edit', 'Discussion', (array) $Fields, $Stored); if (GetValue('CategoryID', $Stored) != GetValue('CategoryID', $Fields)) { $StoredCategoryID = GetValue('CategoryID', $Stored); } } else { // Inserting. if (!GetValue('Format', $Fields) || C('Garden.ForceInputFormatter')) { $Fields['Format'] = C('Garden.InputFormatter', ''); } if (C('Vanilla.QueueNotifications')) { $Fields['Notified'] = ActivityModel::SENT_PENDING; } // Check for spam. $Spam = SpamModel::IsSpam('Discussion', $Fields); if ($Spam) { return SPAM; } // Check for approval $ApprovalRequired = CheckRestriction('Vanilla.Approval.Require'); if ($ApprovalRequired && !GetValue('Verified', Gdn::Session()->User)) { LogModel::Insert('Pending', 'Discussion', $Fields); return UNAPPROVED; } // Create discussion $DiscussionID = $this->SQL->Insert($this->Name, $Fields); $Fields['DiscussionID'] = $DiscussionID; // Update the cache. if ($DiscussionID && Gdn::Cache()->ActiveEnabled()) { $CategoryCache = array('LastDiscussionID' => $DiscussionID, 'LastCommentID' => NULL, 'LastTitle' => Gdn_Format::Text($Fields['Name']), 'LastUserID' => $Fields['InsertUserID'], 'LastDateInserted' => $Fields['DateInserted'], 'LastUrl' => DiscussionUrl($Fields)); CategoryModel::SetCache($Fields['CategoryID'], $CategoryCache); // Clear the cache if necessary. if (GetValue('Announce', $Fields)) { Gdn::Cache()->Remove('Announcements'); } } // Update the user's discussion count. $this->UpdateUserDiscussionCount(Gdn::Session()->UserID); // Assign the new DiscussionID to the comment before saving. $FormPostValues['IsNewDiscussion'] = TRUE; $FormPostValues['DiscussionID'] = $DiscussionID; // Do data prep. $DiscussionName = ArrayValue('Name', $Fields, ''); $Story = ArrayValue('Body', $Fields, ''); $NotifiedUsers = array(); $UserModel = Gdn::UserModel(); $ActivityModel = new ActivityModel(); if (GetValue('Type', $FormPostValues)) { $Code = 'HeadlineFormat.Discussion.' . $FormPostValues['Type']; } else { $Code = 'HeadlineFormat.Discussion'; } $HeadlineFormat = T($Code, '{ActivityUserID,user} started a new discussion: <a href="{Url,html}">{Data.Name,text}</a>'); $Category = CategoryModel::Categories(GetValue('CategoryID', $Fields)); $Activity = array('ActivityType' => 'Discussion', 'ActivityUserID' => $Fields['InsertUserID'], 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Discussion', 'RecordID' => $DiscussionID, 'Route' => DiscussionUrl($Fields), 'Data' => array('Name' => $DiscussionName, 'Category' => GetValue('Name', $Category))); // Allow simple fulltext notifications if (C('Vanilla.Activity.ShowDiscussionBody', FALSE)) { $Activity['Story'] = $Story; } // Notify all of the users that were mentioned in the discussion. $Usernames = array_merge(GetMentions($DiscussionName), GetMentions($Story)); $Usernames = array_unique($Usernames); // Use our generic Activity for events, not mentions $this->EventArguments['Activity'] = $Activity; // Notifications for mentions foreach ($Usernames as $Username) { $User = $UserModel->GetByUsername($Username); if (!$User) { continue; } // Check user can still see the discussion. if (!$UserModel->GetCategoryViewPermission($User->UserID, GetValue('CategoryID', $Fields))) { continue; } $Activity['HeadlineFormat'] = T('HeadlineFormat.Mention', '{ActivityUserID,user} mentioned you in <a href="{Url,html}">{Data.Name,text}</a>'); $Activity['NotifyUserID'] = GetValue('UserID', $User); $ActivityModel->Queue($Activity, 'Mention'); } // Notify everyone that has advanced notifications. if (!C('Vanilla.QueueNotifications')) { try { $Fields['DiscussionID'] = $DiscussionID; $this->NotifyNewDiscussion($Fields, $ActivityModel, $Activity); } catch (Exception $Ex) { throw $Ex; } } // Throw an event for users to add their own events. $this->EventArguments['Discussion'] = $Fields; $this->EventArguments['NotifiedUsers'] = $NotifiedUsers; $this->EventArguments['MentionedUsers'] = $Usernames; $this->EventArguments['ActivityModel'] = $ActivityModel; $this->FireEvent('BeforeNotification'); // Send all notifications. $ActivityModel->SaveQueue(); } // Get CategoryID of this discussion $Discussion = $this->GetID($DiscussionID, DATASET_TYPE_ARRAY); $CategoryID = GetValue('CategoryID', $Discussion, FALSE); // Update discussion counter for affected categories $this->UpdateDiscussionCount($CategoryID, $Insert ? $Discussion : FALSE); if ($StoredCategoryID) { $this->UpdateDiscussionCount($StoredCategoryID); } // Fire an event that the discussion was saved. $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['Fields'] = $Fields; $this->EventArguments['DiscussionID'] = $DiscussionID; $this->FireEvent('AfterSaveDiscussion'); } } return $DiscussionID; }
public function Save($FormPostValues) { $Session = Gdn::Session(); // Define the primary key in this model's table. $this->DefineSchema(); // Add & apply any extra validation rules: $this->Validation->ApplyRule('Body', 'Required'); $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength'); if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) { $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength); $this->Validation->ApplyRule('Body', 'Length'); } $CommentID = ArrayValue('CommentID', $FormPostValues); $CommentID = is_numeric($CommentID) && $CommentID > 0 ? $CommentID : FALSE; $Insert = $CommentID === FALSE; if ($Insert) { $this->AddInsertFields($FormPostValues); } else { $this->AddUpdateFields($FormPostValues); } $this->EventArguments['FormPostValues'] = $FormPostValues; $this->EventArguments['CommentID'] = $CommentID; $this->FireEvent('BeforeSaveComment'); // Validate the form posted values if ($this->Validate($FormPostValues, $Insert)) { // If the post is new and it validates, check for spam if (!$Insert || !$this->CheckForSpam('Comment')) { $Fields = $this->Validation->SchemaValidationFields(); $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); if ($Insert === FALSE) { $this->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID)); } else { // Make sure that the comments get formatted in the method defined by Garden $Fields['Format'] = Gdn::Config('Garden.InputFormatter', ''); $CommentID = $this->SQL->Insert($this->Name, $Fields); $this->EventArguments['CommentID'] = $CommentID; // IsNewDiscussion is passed when the first comment for new discussions are created. $this->EventArguments['IsNewDiscussion'] = ArrayValue('IsNewDiscussion', $FormPostValues); $this->FireEvent('AfterSaveComment'); } } } return $CommentID; }
/** * {@inheritDoc} * @param array $Data * @param bool $Settings * @return bool|mixed Primary Key Value */ public function Save($Data, $Settings = FALSE) { $this->DefineSchema(); $SchemaFields = $this->Schema->Fields(); $SaveData = array(); $Attributes = array(); // Grab the current attachment. if (isset($Data['AttachmentID'])) { $PrimaryKeyVal = $Data['AttachmentID']; $CurrentAttachment = $this->SQL->GetWhere('Attachment', array('AttachmentID' => $PrimaryKeyVal))->FirstRow(DATASET_TYPE_ARRAY); if ($CurrentAttachment) { $Attributes = @unserialize($CurrentAttachment['Attributes']); if (!$Attributes) { $Attributes = array(); } $Insert = FALSE; } else { $Insert = TRUE; } } else { $PrimaryKeyVal = FALSE; $Insert = TRUE; } // Grab any values that aren't in the db schema and stick them in attributes. foreach ($Data as $Name => $Value) { if ($Name == 'Attributes') { continue; } if (isset($SchemaFields[$Name])) { $SaveData[$Name] = $Value; } elseif ($Value === NULL) { unset($Attributes[$Name]); } else { $Attributes[$Name] = $Value; } } if (sizeof($Attributes)) { $SaveData['Attributes'] = $Attributes; } else { $SaveData['Attributes'] = NULL; } if ($Insert) { $this->AddInsertFields($SaveData); } else { $this->AddUpdateFields($SaveData); } // Validate the form posted values. if ($this->Validate($SaveData, $Insert) === TRUE) { $Fields = $this->Validation->ValidationFields(); if ($Insert === FALSE) { $Fields = RemoveKeyFromArray($Fields, $this->PrimaryKey); // Don't try to update the primary key $this->Update($Fields, array($this->PrimaryKey => $PrimaryKeyVal)); } else { $PrimaryKeyVal = $this->Insert($Fields); } } else { $PrimaryKeyVal = FALSE; } return $PrimaryKeyVal; }