Inheritance: extends Gdn_Pluggable
 protected static function _Instance()
 {
     if (!self::$_Instance) {
         self::$_Instance = new SpamModel();
     }
     return self::$_Instance;
 }
Exemple #2
0
 /**
  * Return whether or not the spam model is disabled.
  *
  * @param bool|null $value
  * @return bool
  */
 public static function disabled($value = null)
 {
     if ($value !== null) {
         self::$Disabled = $value;
     }
     return self::$Disabled;
 }
 /**
  * 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.
  * @param array $Settings Currently unused.
  * @return int $DiscussionID Unique ID of the discussion.
  */
 public function save($FormPostValues, $Settings = false)
 {
     $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 = val('CategoryID', $FormPostValues);
     if ($CategoryID > 0) {
         $Category = CategoryModel::categories($CategoryID);
         if ($Category && !$Session->checkPermission('Vanilla.Discussions.Add', true, 'Category', val('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 = val('DiscussionID', $FormPostValues, '');
     // See if there is a source ID.
     if (val('SourceID', $FormPostValues)) {
         $DiscussionID = $this->SQL->getWhere('Discussion', arrayTranslate($FormPostValues, array('Source', 'SourceID')))->value('DiscussionID');
         if ($DiscussionID) {
             $FormPostValues['DiscussionID'] = $DiscussionID;
         }
     } elseif (val('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 (!val('CategoryID', $FormPostValues) && !c('Vanilla.Categories.Use')) {
             $FormPostValues['CategoryID'] = val('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 (val('Announce', $FormPostValues, '') === false) {
         $FormPostValues['Announce'] = 0;
     }
     if (val('Closed', $FormPostValues, '') === false) {
         $FormPostValues['Closed'] = 0;
     }
     if (val('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();
             // Check for spam.
             $spam = SpamModel::isSpam('Discussion', $Fields);
             if ($spam) {
                 return SPAM;
             }
             // Get DiscussionID if one was sent
             $DiscussionID = intval(val('DiscussionID', $Fields, 0));
             // Remove the primary key from the fields for saving.
             unset($Fields['DiscussionID']);
             $StoredCategoryID = false;
             if ($DiscussionID > 0) {
                 // Updating
                 $Stored = $this->getID($DiscussionID, DATASET_TYPE_OBJECT);
                 // Block Format change if we're forcing the formatter.
                 if (c('Garden.ForceInputFormatter')) {
                     unset($Fields['Format']);
                 }
                 // Clear the cache if necessary.
                 $CacheKeys = array();
                 if (val('Announce', $Stored) != val('Announce', $Fields)) {
                     $CacheKeys[] = $this->getAnnouncementCacheKey();
                     $CacheKeys[] = $this->getAnnouncementCacheKey(val('CategoryID', $Stored));
                 }
                 if (val('CategoryID', $Stored) != val('CategoryID', $Fields)) {
                     $CacheKeys[] = $this->getAnnouncementCacheKey(val('CategoryID', $Fields));
                 }
                 foreach ($CacheKeys as $CacheKey) {
                     Gdn::cache()->remove($CacheKey);
                 }
                 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 (val('CategoryID', $Stored) != val('CategoryID', $Fields)) {
                     $StoredCategoryID = val('CategoryID', $Stored);
                 }
             } else {
                 // Inserting.
                 if (!val('Format', $Fields) || c('Garden.ForceInputFormatter')) {
                     $Fields['Format'] = c('Garden.InputFormatter', '');
                 }
                 if (c('Vanilla.QueueNotifications')) {
                     $Fields['Notified'] = ActivityModel::SENT_PENDING;
                 }
                 // Check for approval
                 $ApprovalRequired = checkRestriction('Vanilla.Approval.Require');
                 if ($ApprovalRequired && !val('Verified', Gdn::session()->User)) {
                     LogModel::insert('Pending', 'Discussion', $Fields);
                     return UNAPPROVED;
                 }
                 // Create discussion
                 $this->serializeRow($Fields);
                 $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 (val('Announce', $Fields)) {
                         Gdn::cache()->remove($this->getAnnouncementCacheKey(val('CategoryID', $Fields)));
                         if (val('Announce', $Fields) == 1) {
                             Gdn::cache()->remove($this->getAnnouncementCacheKey());
                         }
                     }
                 }
                 // Update the user's discussion count.
                 $InsertUser = Gdn::userModel()->getID($Fields['InsertUserID']);
                 $this->updateUserDiscussionCount($Fields['InsertUserID'], val('CountDiscussions', $InsertUser, 0) > 100);
                 // Mark the user as participated.
                 $this->SQL->replace('UserDiscussion', array('Participated' => 1), array('DiscussionID' => $DiscussionID, 'UserID' => val('InsertUserID', $Fields)));
                 // Assign the new DiscussionID to the comment before saving.
                 $FormPostValues['IsNewDiscussion'] = true;
                 $FormPostValues['DiscussionID'] = $DiscussionID;
                 // Do data prep.
                 $DiscussionName = val('Name', $Fields, '');
                 $Story = val('Body', $Fields, '');
                 $NotifiedUsers = array();
                 $UserModel = Gdn::userModel();
                 $ActivityModel = new ActivityModel();
                 if (val('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(val('CategoryID', $Fields));
                 $Activity = array('ActivityType' => 'Discussion', 'ActivityUserID' => $Fields['InsertUserID'], 'HeadlineFormat' => $HeadlineFormat, 'RecordType' => 'Discussion', 'RecordID' => $DiscussionID, 'Route' => DiscussionUrl($Fields), 'Data' => array('Name' => $DiscussionName, 'Category' => val('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 = getMentions($DiscussionName . ' ' . $Story);
                 // Use our generic Activity for events, not mentions
                 $this->EventArguments['Activity'] = $Activity;
                 // Notify everyone that has advanced notifications.
                 if (!c('Vanilla.QueueNotifications')) {
                     try {
                         $Fields['DiscussionID'] = $DiscussionID;
                         $this->notifyNewDiscussion($Fields, $ActivityModel, $Activity);
                     } catch (Exception $Ex) {
                         throw $Ex;
                     }
                 }
                 // Notifications for mentions
                 foreach ($Usernames as $Username) {
                     $User = $UserModel->getByUsername($Username);
                     if (!$User) {
                         continue;
                     }
                     // Check user can still see the discussion.
                     if (!$this->canView($Fields, $User->UserID)) {
                         continue;
                     }
                     $Activity['HeadlineFormat'] = t('HeadlineFormat.Mention', '{ActivityUserID,user} mentioned you in <a href="{Url,html}">{Data.Name,text}</a>');
                     $Activity['NotifyUserID'] = val('UserID', $User);
                     $ActivityModel->queue($Activity, 'Mention');
                 }
                 // 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_OBJECT);
             $CategoryID = val('CategoryID', $Discussion, false);
             // Update discussion counter for affected categories.
             if ($Insert || $StoredCategoryID) {
                 $this->incrementNewDiscussion($Discussion);
             }
             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;
 }
Exemple #5
0
 /**
  *
  *
  * @param array $User
  * @return bool|string
  * @since 2.1
  */
 public function validateSpamRegistration($User)
 {
     $DiscoveryText = val('DiscoveryText', $User);
     $Log = validateRequired($DiscoveryText);
     $Spam = SpamModel::isSpam('Registration', $User, ['Log' => $Log]);
     if ($Spam) {
         if ($Log) {
             // The user entered discovery text.
             return self::REDIRECT_APPROVE;
         } else {
             $this->Validation->addValidationResult('DiscoveryText', 'Tell us why you want to join!');
             return false;
         }
     }
     return true;
 }
Exemple #6
0
 /**
  * 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');
     $MaxCommentLength = Gdn::Config('Vanilla.Comment.MaxLength');
     if (is_numeric($MaxCommentLength) && $MaxCommentLength > 0) {
         $this->Validation->SetSchemaProperty('Body', 'Length', $MaxCommentLength);
         $this->Validation->ApplyRule('Body', 'Length');
     }
     // Validate $CommentID and whether this is an insert
     $CommentID = ArrayValue('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->SQL->Put($this->Name, $Fields, array('CommentID' => $CommentID));
             } else {
                 // Make sure that the comments get formatted in the method defined by Garden.
                 if (!GetValue('Format', $Fields)) {
                     $Fields['Format'] = Gdn::Config('Garden.InputFormatter', '');
                 }
                 // Check for spam.
                 $Spam = SpamModel::IsSpam('Comment', $Fields);
                 if (!$Spam) {
                     $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'] = GetValue('IsNewDiscussion', $FormPostValues);
                     $this->FireEvent('AfterSaveComment');
                 } else {
                     return SPAM;
                 }
             }
         }
     }
     // Update discussion's comment count
     $DiscussionID = GetValue('DiscussionID', $FormPostValues);
     $this->UpdateCommentCount($DiscussionID);
     return $CommentID;
 }
 public function Save($Data, $Preference = FALSE, $Options = array())
 {
     Trace('ActivityModel->Save()');
     $Activity = $Data;
     $this->_Touch($Activity);
     if ($Activity['ActivityUserID'] == $Activity['NotifyUserID'] && !GetValue('Force', $Options)) {
         Trace('Skipping activity because it would notify the user of something they did.');
         return;
         // don't notify users of something they did.
     }
     // Check the user's preference.
     if ($Preference) {
         list($Popup, $Email) = self::NotificationPreference($Preference, $Activity['NotifyUserID'], 'both');
         if ($Popup && !$Activity['Notified']) {
             $Activity['Notified'] = self::SENT_PENDING;
         }
         if ($Email && !$Activity['Emailed']) {
             $Activity['Emailed'] = self::SENT_PENDING;
         }
         if (!$Activity['Notified'] && !$Activity['Emailed'] && !GetValue('Force', $Options)) {
             Trace("Skipping activity because the user has no preference set.");
             return;
         }
     }
     $ActivityType = self::GetActivityType($Activity['ActivityType']);
     $ActivityTypeID = ArrayValue('ActivityTypeID', $ActivityType);
     if (!$ActivityTypeID) {
         Trace("There is no {$ActivityType} activity type.", TRACE_WARNING);
         $ActivityType = self::GetActivityType('Default');
         $ActivityTypeID = ArrayValue('ActivityTypeID', $ActivityType);
     }
     $Activity['ActivityTypeID'] = $ActivityTypeID;
     $NotificationInc = 0;
     if ($Activity['NotifyUserID'] > 0 && $Activity['Notified']) {
         $NotificationInc = 1;
     }
     // Check to see if we are sharing this activity with another one.
     if ($CommentActivityID = GetValue('CommentActivityID', $Activity['Data'])) {
         $CommentActivity = $this->GetID($CommentActivityID);
         $Activity['Data']['CommentNotifyUserID'] = $CommentActivity['NotifyUserID'];
     }
     // Make sure this activity isn't a duplicate.
     if (GetValue('CheckRecord', $Options)) {
         // Check to see if this record already notified so we don't notify multiple times.
         $Where = ArrayTranslate($Activity, array('NotifyUserID', 'RecordType', 'RecordID'));
         $Where['DateUpdated >'] = Gdn_Format::ToDateTime(strtotime('-2 days'));
         // index hint
         $CheckActivity = $this->SQL->GetWhere('Activity', $Where)->FirstRow();
         if ($CheckActivity) {
             return FALSE;
         }
     }
     // Check to share the activity.
     if (GetValue('Share', $Options)) {
         $this->Share($Activity);
     }
     // Group he activity.
     if ($GroupBy = GetValue('GroupBy', $Options)) {
         $GroupBy = (array) $GroupBy;
         $Where = array();
         foreach ($GroupBy as $ColumnName) {
             $Where[$ColumnName] = $Activity[$ColumnName];
         }
         $Where['NotifyUserID'] = $Activity['NotifyUserID'];
         // Make sure to only group activities by day.
         $Where['DateInserted >'] = Gdn_Format::ToDateTime(strtotime('-1 day'));
         // See if there is another activity to group these into.
         $GroupActivity = $this->SQL->GetWhere('Activity', $Where)->FirstRow(DATASET_TYPE_ARRAY);
         if ($GroupActivity) {
             $GroupActivity['Data'] = @unserialize($GroupActivity['Data']);
             $Activity = $this->MergeActivities($GroupActivity, $Activity);
             $NotificationInc = 0;
         }
     }
     $Delete = FALSE;
     if ($Activity['Emailed'] == self::SENT_PENDING) {
         $this->Email($Activity);
         $Delete = GetValue('_Delete', $Activity);
     }
     $ActivityData = $Activity['Data'];
     if (isset($Activity['Data']) && is_array($Activity['Data'])) {
         $Activity['Data'] = serialize($Activity['Data']);
     }
     $this->DefineSchema();
     $Activity = $this->FilterSchema($Activity);
     $ActivityID = GetValue('ActivityID', $Activity);
     if (!$ActivityID) {
         if (!$Delete) {
             $this->AddInsertFields($Activity);
             TouchValue('DateUpdated', $Activity, $Activity['DateInserted']);
             $this->EventArguments['Activity'] =& $Activity;
             $this->EventArguments['ActivityID'] = NULL;
             $this->FireEvent('BeforeSave');
             if (count($this->ValidationResults()) > 0) {
                 return FALSE;
             }
             if (GetValue('CheckSpam', $Options)) {
                 // Check for spam
                 $Spam = SpamModel::IsSpam('Activity', $Activity);
                 if ($Spam) {
                     return SPAM;
                 }
                 // Check for approval
                 $ApprovalRequired = CheckRestriction('Vanilla.Approval.Require');
                 if ($ApprovalRequired && !GetValue('Verified', Gdn::Session()->User)) {
                     LogModel::Insert('Pending', 'Activity', $Activity);
                     return UNAPPROVED;
                 }
             }
             $ActivityID = $this->SQL->Insert('Activity', $Activity);
             $Activity['ActivityID'] = $ActivityID;
         }
     } else {
         $Activity['DateUpdated'] = Gdn_Format::ToDateTime();
         unset($Activity['ActivityID']);
         $this->EventArguments['Activity'] =& $Activity;
         $this->EventArguments['ActivityID'] = $ActivityID;
         $this->FireEvent('BeforeSave');
         if (count($this->ValidationResults()) > 0) {
             return FALSE;
         }
         $this->SQL->Put('Activity', $Activity, array('ActivityID' => $ActivityID));
         $Activity['ActivityID'] = $ActivityID;
     }
     $Activity['Data'] = $ActivityData;
     if (isset($CommentActivity)) {
         $CommentActivity['Data']['SharedActivityID'] = $Activity['ActivityID'];
         $CommentActivity['Data']['SharedNotifyUserID'] = $Activity['NotifyUserID'];
         $this->SetField($CommentActivity['ActivityID'], 'Data', $CommentActivity['Data']);
     }
     if ($NotificationInc > 0) {
         $CountNotifications = Gdn::UserModel()->GetID($Activity['NotifyUserID'])->CountNotifications + $NotificationInc;
         Gdn::UserModel()->SetField($Activity['NotifyUserID'], 'CountNotifications', $CountNotifications);
     }
     return $Activity;
 }
 /**
  *
  * @param array $User
  * @return bool|string
  * @since 2.1 
  */
 public function ValidateSpamRegistration($User)
 {
     $DiscoveryText = GetValue('DiscoveryText', $User);
     $Log = ValidateRequired($DiscoveryText);
     $Spam = SpamModel::IsSpam('Registration', $User, array('Log' => $Log));
     if ($Spam) {
         if ($Log) {
             // The user entered discovery text.
             return self::REDIRECT_APPROVE;
         } else {
             $this->Validation->AddValidationResult('DiscoveryText', 'Tell us why you want to join!');
             return FALSE;
         }
     }
     return TRUE;
 }
 /**
  * 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'] = Gdn_Format::ToDateTime();
     } 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);
                 // Block Format change if we're forcing the formatter.
                 if (C('Garden.ForceInputFormatter')) {
                     unset($Fields['Format']);
                 }
                 // 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);
                     $StoredCategoryID = GetValue('CategoryID', $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', '');
                 }
                 // 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;
                 // Notify users of mentions.
                 $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);
                 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.
                 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['Activity'] = $Activity;
                 $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;
 }
Exemple #10
0
 /**
  * Inject into the process of the base connection.
  *
  * @param Gdn_Controller $sender.
  * @param Gdn_Controller $args.
  */
 public function base_connectData_handler($sender, $args)
 {
     if (val(0, $args) != $this->getProviderKey()) {
         return;
     }
     // Retrieve the profile that was saved to the session in the entry controller.
     $savedProfile = Gdn::session()->stash($this->getProviderKey(), '', false);
     if (Gdn::session()->stash($this->getProviderKey(), '', false)) {
         $this->log('Base Connect Data Profile Saved in Session', ['profile' => $savedProfile]);
     }
     $profile = val('Profile', $savedProfile);
     $accessToken = val('AccessToken', $savedProfile);
     trace($profile, 'Profile');
     trace($accessToken, 'Access Token');
     /* @var Gdn_Form $form */
     $form = $sender->Form;
     //new Gdn_Form();
     // Create a form and populate it with values from the profile.
     $originaFormValues = $form->formValues();
     $formValues = array_replace($originaFormValues, $profile);
     $form->formValues($formValues);
     trace($formValues, 'Form Values');
     // Save some original data in the attributes of the connection for later API calls.
     $attributes = [];
     $attributes[$this->getProviderKey()] = ['AccessToken' => $accessToken, 'Profile' => $profile];
     $form->setFormValue('Attributes', $attributes);
     $sender->EventArguments['Profile'] = $profile;
     $sender->EventArguments['Form'] = $form;
     $this->log('Base Connect Data Before OAuth Event', ['profile' => $profile, 'form' => $form]);
     // Throw an event so that other plugins can add/remove stuff from the basic sso.
     $sender->fireEvent('OAuth');
     SpamModel::disabled(true);
     $sender->setData('Trusted', true);
     $sender->setData('Verified', true);
 }
 /**
  * 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;
 }
   public function Register($FormPostValues, $Options = array()) {
      $Valid = TRUE;
      $FormPostValues['LastIPAddress'] = Gdn::Request()->IpAddress();

      // Check for banning first.
      $Valid = BanModel::CheckUser($FormPostValues, $this->Validation, TRUE);

      // Check for spam.
      if ($Valid) {
         $Spam = SpamModel::IsSpam('User', $FormPostValues);
         if ($Spam) {
            $Valid = FALSE;
            $this->Validation->AddValidationResult('Spam', 'You are not allowed to register at this time.');
         }
      }

      // Throw an event to allow plugins to block the registration.
      $this->EventArguments['User'] = $FormPostValues;
      
      $this->EventArguments['Valid'] =& $Valid;
      $this->FireEvent('BeforeRegister');

      if (!$Valid)
         return FALSE; // plugin blocked registration

      switch (strtolower(C('Garden.Registration.Method'))) {
         case 'captcha':
            $UserID = $this->InsertForBasic($FormPostValues, GetValue('CheckCaptcha', $Options, TRUE), $Options);
            break;
         case 'approval':
            $UserID = $this->InsertForApproval($FormPostValues, $Options);
            break;
         case 'invitation':
            $UserID = $this->InsertForInvite($FormPostValues, $Options);
            break;
         case 'closed':
            $UserID = FALSE;
            $this->Validation->AddValidationResult('Registration', 'Registration is closed.');
            break;
         case 'basic':
         default:
            $UserID = $this->InsertForBasic($FormPostValues, GetValue('CheckCaptcha', $Options, FALSE), $Options);
            break;
      }
      return $UserID;
   }
Exemple #13
0
 /**
  *
  *
  * @param array $Data
  * @param bool $Preference
  * @param array $Options
  * @return array|bool|string|null
  * @throws Exception
  */
 public function save($Data, $Preference = false, $Options = [])
 {
     trace('ActivityModel->save()');
     $Activity = $Data;
     $this->_touch($Activity);
     if ($Activity['ActivityUserID'] == $Activity['NotifyUserID'] && !val('Force', $Options)) {
         trace('Skipping activity because it would notify the user of something they did.');
         return null;
         // don't notify users of something they did.
     }
     // Check the user's preference.
     if ($Preference) {
         list($Popup, $Email) = self::notificationPreference($Preference, $Activity['NotifyUserID'], 'both');
         if ($Popup && !$Activity['Notified']) {
             $Activity['Notified'] = self::SENT_PENDING;
         }
         if ($Email && !$Activity['Emailed']) {
             $Activity['Emailed'] = self::SENT_PENDING;
         }
         if (!$Activity['Notified'] && !$Activity['Emailed'] && !val('Force', $Options)) {
             trace("Skipping activity because the user has no preference set.");
             return null;
         }
     }
     $ActivityType = self::getActivityType($Activity['ActivityType']);
     $ActivityTypeID = val('ActivityTypeID', $ActivityType);
     if (!$ActivityTypeID) {
         trace("There is no {$ActivityType} activity type.", TRACE_WARNING);
         $ActivityType = self::getActivityType('Default');
         $ActivityTypeID = val('ActivityTypeID', $ActivityType);
     }
     $Activity['ActivityTypeID'] = $ActivityTypeID;
     $NotificationInc = 0;
     if ($Activity['NotifyUserID'] > 0 && $Activity['Notified']) {
         $NotificationInc = 1;
     }
     // Check to see if we are sharing this activity with another one.
     if ($CommentActivityID = val('CommentActivityID', $Activity['Data'])) {
         $CommentActivity = $this->getID($CommentActivityID);
         $Activity['Data']['CommentNotifyUserID'] = $CommentActivity['NotifyUserID'];
     }
     // Make sure this activity isn't a duplicate.
     if (val('CheckRecord', $Options)) {
         // Check to see if this record already notified so we don't notify multiple times.
         $Where = arrayTranslate($Activity, ['NotifyUserID', 'RecordType', 'RecordID']);
         $Where['DateUpdated >'] = Gdn_Format::toDateTime(strtotime('-2 days'));
         // index hint
         $CheckActivity = $this->SQL->getWhere('Activity', $Where)->firstRow();
         if ($CheckActivity) {
             return false;
         }
     }
     // Check to share the activity.
     if (val('Share', $Options)) {
         $this->share($Activity);
     }
     // Group he activity.
     if ($GroupBy = val('GroupBy', $Options)) {
         $GroupBy = (array) $GroupBy;
         $Where = [];
         foreach ($GroupBy as $ColumnName) {
             $Where[$ColumnName] = $Activity[$ColumnName];
         }
         $Where['NotifyUserID'] = $Activity['NotifyUserID'];
         // Make sure to only group activities by day.
         $Where['DateInserted >'] = Gdn_Format::toDateTime(strtotime('-1 day'));
         // See if there is another activity to group these into.
         $GroupActivity = $this->SQL->getWhere('Activity', $Where)->firstRow(DATASET_TYPE_ARRAY);
         if ($GroupActivity) {
             $GroupActivity['Data'] = dbdecode($GroupActivity['Data']);
             $Activity = $this->mergeActivities($GroupActivity, $Activity);
             $NotificationInc = 0;
         }
     }
     $Delete = false;
     if ($Activity['Emailed'] == self::SENT_PENDING) {
         $this->email($Activity);
         $Delete = val('_Delete', $Activity);
     }
     $ActivityData = $Activity['Data'];
     if (isset($Activity['Data']) && is_array($Activity['Data'])) {
         $Activity['Data'] = dbencode($Activity['Data']);
     }
     $this->defineSchema();
     $Activity = $this->filterSchema($Activity);
     $ActivityID = val('ActivityID', $Activity);
     if (!$ActivityID) {
         if (!$Delete) {
             $this->addInsertFields($Activity);
             touchValue('DateUpdated', $Activity, $Activity['DateInserted']);
             $this->EventArguments['Activity'] =& $Activity;
             $this->EventArguments['ActivityID'] = null;
             $Handled = false;
             $this->EventArguments['Handled'] =& $Handled;
             $this->fireEvent('BeforeSave');
             if (count($this->validationResults()) > 0) {
                 return false;
             }
             if ($Handled) {
                 // A plugin handled this activity so don't save it.
                 return $Activity;
             }
             if (val('CheckSpam', $Options)) {
                 // Check for spam
                 $Spam = SpamModel::isSpam('Activity', $Activity);
                 if ($Spam) {
                     return SPAM;
                 }
                 // Check for approval
                 $ApprovalRequired = checkRestriction('Vanilla.Approval.Require');
                 if ($ApprovalRequired && !val('Verified', Gdn::session()->User)) {
                     LogModel::insert('Pending', 'Activity', $Activity);
                     return UNAPPROVED;
                 }
             }
             $ActivityID = $this->SQL->insert('Activity', $Activity);
             $Activity['ActivityID'] = $ActivityID;
             $this->prune();
         }
     } else {
         $Activity['DateUpdated'] = Gdn_Format::toDateTime();
         unset($Activity['ActivityID']);
         $this->EventArguments['Activity'] =& $Activity;
         $this->EventArguments['ActivityID'] = $ActivityID;
         $this->fireEvent('BeforeSave');
         if (count($this->validationResults()) > 0) {
             return false;
         }
         $this->SQL->put('Activity', $Activity, ['ActivityID' => $ActivityID]);
         $Activity['ActivityID'] = $ActivityID;
     }
     $Activity['Data'] = $ActivityData;
     if (isset($CommentActivity)) {
         $CommentActivity['Data']['SharedActivityID'] = $Activity['ActivityID'];
         $CommentActivity['Data']['SharedNotifyUserID'] = $Activity['NotifyUserID'];
         $this->setField($CommentActivity['ActivityID'], 'Data', $CommentActivity['Data']);
     }
     if ($NotificationInc > 0) {
         $CountNotifications = Gdn::userModel()->getID($Activity['NotifyUserID'])->CountNotifications + $NotificationInc;
         Gdn::userModel()->setField($Activity['NotifyUserID'], 'CountNotifications', $CountNotifications);
     }
     // If this is a wall post then we need to notify on that.
     if (val('Name', $ActivityType) == 'WallPost' && $Activity['NotifyUserID'] == self::NOTIFY_PUBLIC) {
         $this->notifyWallPost($Activity);
     }
     return $Activity;
 }
Exemple #14
0
 /**
  * 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);
     }
     $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');
     }
     $this->AddInsertFields($FormPostValues);
     if ($this->Validate($FormPostValues, TRUE) === TRUE) {
         // Check for spam.
         $Spam = SpamModel::IsSpam('Registration', $FormPostValues);
         if ($Spam) {
             $this->Validation->AddValidationResult('Spam', 'You are not allowed to register at this time.');
             return;
         }
         $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;
         }
         // Define the other required fields:
         $Fields['Email'] = $Email;
         // And insert the new user
         $UserID = $this->_Insert($Fields, $Options);
         AddActivity($UserID, 'Join', T('Welcome Aboard!'));
     }
     return $UserID;
 }
 public function Save($Data, $Preference = FALSE, $Options = array())
 {
     Trace('ActivityModel->Save()');
     $Activity = $Data;
     $this->_Touch($Activity);
     if ($Activity['ActivityUserID'] == $Activity['NotifyUserID'] && !GetValue('Force', $Options)) {
         Trace('Skipping activity because it would notify the user of something they did.');
         return;
         // don't notify users of something they did.
     }
     // Check the user's preference.
     if ($Preference) {
         list($Popup, $Email) = self::NotificationPreference($Preference, $Activity['NotifyUserID'], 'both');
         if ($Popup && !$Activity['Notified']) {
             $Activity['Notified'] = self::SENT_PENDING;
         }
         if ($Email && !$Activity['Emailed']) {
             $Activity['Emailed'] = self::SENT_PENDING;
         }
         if (!$Activity['Notified'] && !$Activity['Emailed'] && !GetValue('Force', $Options)) {
             Trace("Skipping activity because the user has no preference set.");
             return;
         }
     }
     $ActivityType = self::GetActivityType($Activity['ActivityType']);
     $ActivityTypeID = ArrayValue('ActivityTypeID', $ActivityType);
     if (!$ActivityTypeID) {
         Trace("There is no {$ActivityType} activity type.", TRACE_WARNING);
         $ActivityType = self::GetActivityType('Default');
         $ActivityTypeID = ArrayValue('ActivityTypeID', $ActivityType);
     }
     $Activity['ActivityTypeID'] = $ActivityTypeID;
     $NotificationInc = 0;
     if ($Activity['NotifyUserID'] > 0 && $Activity['Notified']) {
         $NotificationInc = 1;
     }
     // Check to see if we are sharing this activity with another one.
     if ($CommentActivityID = GetValue('CommentActivityID', $Activity['Data'])) {
         $CommentActivity = $this->GetID($CommentActivityID);
         $Activity['Data']['CommentNotifyUserID'] = $CommentActivity['NotifyUserID'];
     }
     if ($GroupBy = GetValue('GroupBy', $Options)) {
         $GroupBy = (array) $GroupBy;
         $Where = array();
         foreach ($GroupBy as $ColumnName) {
             $Where[$ColumnName] = $Activity[$ColumnName];
         }
         $Where['NotifyUserID'] = $Activity['NotifyUserID'];
         // Make sure to only group activities by day.
         $Where['DateInserted >'] = Gdn_Format::ToDateTime(strtotime('-1 day'));
         // See if there is another activity to group these into.
         $GroupActivity = $this->SQL->GetWhere('Activity', $Where)->FirstRow(DATASET_TYPE_ARRAY);
         if ($GroupActivity) {
             $GroupActivity['Data'] = @unserialize($GroupActivity['Data']);
             $Activity = $this->MergeActivities($GroupActivity, $Activity);
             $NotificationInc = 0;
         }
     }
     $Delete = FALSE;
     if ($Activity['Emailed'] == self::SENT_PENDING) {
         $this->Email($Activity);
         $Delete = GetValue('_Delete', $Activity);
     }
     $ActivityData = $Activity['Data'];
     if (isset($Activity['Data']) && is_array($Activity['Data'])) {
         $Activity['Data'] = serialize($Activity['Data']);
     }
     $this->DefineSchema();
     $Activity = $this->FilterSchema($Activity);
     $ActivityID = GetValue('ActivityID', $Activity);
     if (!$ActivityID) {
         if (!$Delete) {
             $this->AddInsertFields($Activity);
             TouchValue('DateUpdated', $Activity, $Activity['DateInserted']);
             if (GetValue('CheckSpam', $Options)) {
                 $Spam = SpamModel::IsSpam('Activity', $Activity);
                 if ($Spam) {
                     return SPAM;
                 }
             }
             $ActivityID = $this->SQL->Insert('Activity', $Activity);
             $Activity['ActivityID'] = $ActivityID;
         }
     } else {
         $Activity['DateUpdated'] = Gdn_Format::ToDateTime();
         unset($Activity['ActivityID']);
         $this->SQL->Put('Activity', $Activity, array('ActivityID' => $ActivityID));
         $Activity['ActivityID'] = $ActivityID;
     }
     $Activity['Data'] = $ActivityData;
     if (isset($CommentActivity)) {
         $CommentActivity['Data']['SharedActivityID'] = $Activity['ActivityID'];
         $CommentActivity['Data']['SharedNotifyUserID'] = $Activity['NotifyUserID'];
         $this->SetField($CommentActivity['ActivityID'], 'Data', $CommentActivity['Data']);
     }
     if ($NotificationInc > 0) {
         $CountNotifications = Gdn::UserModel()->GetID($Activity['NotifyUserID'])->CountNotifications + $NotificationInc;
         Gdn::UserModel()->SetField($Activity['NotifyUserID'], 'CountNotifications', $CountNotifications);
     }
     return $Activity;
 }