예제 #1
0
 /**
  * Synchronizes the user based on a given UserKey.
  *
  * @param string $UserKey A string that uniquely identifies this user.
  * @param array $Data Information to put in the user table.
  * @return int The ID of the user.
  */
 public function synchronize($UserKey, $Data)
 {
     $UserID = 0;
     $Attributes = val('Attributes', $Data);
     if (is_string($Attributes)) {
         $Attributes = dbdecode($Attributes);
     }
     if (!is_array($Attributes)) {
         $Attributes = [];
     }
     // If the user didnt log in, they won't have a UserID yet. That means they want a new
     // account. So create one for them.
     if (!isset($Data['UserID']) || $Data['UserID'] <= 0) {
         // Prepare the user data.
         $UserData = [];
         $UserData['Name'] = $Data['Name'];
         $UserData['Password'] = randomString(16);
         $UserData['Email'] = val('Email', $Data, '*****@*****.**');
         $UserData['Gender'] = strtolower(substr(val('Gender', $Data, 'u'), 0, 1));
         $UserData['HourOffset'] = val('HourOffset', $Data, 0);
         $UserData['DateOfBirth'] = val('DateOfBirth', $Data, '');
         $UserData['CountNotifications'] = 0;
         $UserData['Attributes'] = $Attributes;
         $UserData['InsertIPAddress'] = ipEncode(Gdn::request()->ipAddress());
         if ($UserData['DateOfBirth'] == '') {
             $UserData['DateOfBirth'] = '1975-09-16';
         }
         // Make sure there isn't another user with this username.
         if ($this->validateUniqueFields($UserData['Name'], $UserData['Email'])) {
             if (!BanModel::checkUser($UserData, $this->Validation, true)) {
                 throw permissionException('Banned');
             }
             // Insert the new user.
             $this->addInsertFields($UserData);
             $UserID = $this->insertInternal($UserData);
         }
         if ($UserID > 0) {
             $NewUserRoleIDs = $this->newUserRoleIDs();
             // Save the roles.
             $Roles = val('Roles', $Data, false);
             if (empty($Roles)) {
                 $Roles = $NewUserRoleIDs;
             }
             $this->saveRoles($UserID, $Roles, false);
         }
     } else {
         $UserID = $Data['UserID'];
     }
     // Synchronize the transientkey from the external user data source if it is present (eg. WordPress' wpnonce).
     if (array_key_exists('TransientKey', $Attributes) && $Attributes['TransientKey'] != '' && $UserID > 0) {
         $this->setTransientKey($UserID, $Attributes['TransientKey']);
     }
     return $UserID;
 }
 /**
  *
  *
  * @param $Sender
  * @param $Args
  */
 public function base_checkSpam_handler($Sender, $Args)
 {
     // Don't check for spam if another plugin has already determined it is.
     if ($Sender->EventArguments['IsSpam']) {
         return;
     }
     $RecordType = $Args['RecordType'];
     $Data =& $Args['Data'];
     $Options =& $Args['Options'];
     // Detect our favorite bot and short-circuit
     if ($Reason = val('DiscoveryText', $Data)) {
         if (substr($Reason, 0, 1) === '{') {
             $Sender->EventArguments['IsSpam'] = true;
             $Data['Log_InsertUserID'] = $this->userID();
             $Data['RecordIPAddress'] = ipEncode(Gdn::request()->ipAddress());
             return;
         }
     }
     $Result = false;
     switch ($RecordType) {
         case 'Registration':
             $Result = self::check($Data, $Options);
             if ($Result) {
                 $Data['Log_InsertUserID'] = $this->userID();
                 $Data['RecordIPAddress'] = ipEncode(Gdn::request()->ipAddress());
             }
             break;
         case 'Comment':
         case 'Discussion':
         case 'Activity':
             //            $Result = $this->CheckTest($RecordType, $Data) || $this->CheckStopForumSpam($RecordType, $Data) || $this->CheckAkismet($RecordType, $Data);
             break;
     }
     $Sender->EventArguments['IsSpam'] = $Result;
 }
예제 #3
0
 /**
  * Log an operation into the log table.
  *
  * @param string $Operation The operation being performed. This is usually one of:
  *  - Delete: The record has been deleted.
  *  - Edit: The record has been edited.
  *  - Spam: The record has been marked spam.
  *  - Moderate: The record requires moderation.
  *  - Pending: The record needs pre-moderation.
  * @param string $RecordType The type of record being logged. This usually correspond to the tablename of the record.
  * @param array $Data The record data.
  *  - If you are logging just one row then pass the row as an array.
  *  - You can pass an additional _New element to tell the logger what the new data is.
  * @param array $Options Additional options to affect the insert.
  * @return int|false The log ID or **false** if there was a problem.
  */
 public static function insert($Operation, $RecordType, $Data, $Options = [])
 {
     if ($Operation === false) {
         return false;
     }
     if (!is_array($Data)) {
         $Data = [$Data];
     }
     // Check to see if we are storing two versions of the data.
     if (($InsertUserID = self::logValue($Data, 'Log_InsertUserID')) === null) {
         $InsertUserID = Gdn::session()->UserID;
     }
     if (($InsertIPAddress = self::logValue($Data, 'Log_InsertIPAddress')) == null) {
         $InsertIPAddress = ipEncode(Gdn::request()->ipAddress());
     }
     // Do some known translations for the parent record ID.
     if (($ParentRecordID = self::logValue($Data, 'ParentRecordID')) === null) {
         switch ($RecordType) {
             case 'Activity':
                 $ParentRecordID = self::logValue($Data, 'CommentActivityID', 'CommentActivityID');
                 break;
             case 'Comment':
                 $ParentRecordID = self::logValue($Data, 'DiscussionID', 'DiscussionID');
                 break;
         }
     }
     // Get the row information from the data or determine it based on the type.
     $LogRow = ['Operation' => $Operation, 'RecordType' => $RecordType, 'RecordID' => self::logValue($Data, 'RecordID', $RecordType . 'ID'), 'RecordUserID' => self::logValue($Data, 'RecordUserID', 'UpdateUserID', 'InsertUserID'), 'RecordIPAddress' => self::logValue($Data, 'RecordIPAddress', 'LastIPAddress', 'InsertIPAddress'), 'RecordDate' => self::logValue($Data, 'RecordDate', 'DateUpdated', 'DateInserted'), 'InsertUserID' => $InsertUserID, 'InsertIPAddress' => $InsertIPAddress, 'DateInserted' => Gdn_Format::toDateTime(), 'ParentRecordID' => $ParentRecordID, 'CategoryID' => self::logValue($Data, 'CategoryID'), 'OtherUserIDs' => implode(',', val('OtherUserIDs', $Options, [])), 'Data' => dbencode($Data)];
     if ($LogRow['RecordDate'] == null) {
         $LogRow['RecordDate'] = Gdn_Format::toDateTime();
     }
     $GroupBy = val('GroupBy', $Options);
     // Make sure we aren't grouping by null values.
     if (is_array($GroupBy)) {
         foreach ($GroupBy as $Name) {
             if (val($Name, $LogRow) === null) {
                 $GroupBy = false;
                 break;
             }
         }
     }
     if ($GroupBy) {
         $GroupBy[] = 'Operation';
         $GroupBy[] = 'RecordType';
         // Check to see if there is a record already logged here.
         $Where = array_combine($GroupBy, arrayTranslate($LogRow, $GroupBy));
         $LogRow2 = Gdn::sql()->getWhere('Log', $Where)->firstRow(DATASET_TYPE_ARRAY);
         if ($LogRow2) {
             $LogID = $LogRow2['LogID'];
             $Set = [];
             $Data = array_merge(dbdecode($LogRow2['Data']), $Data);
             $OtherUserIDs = explode(',', $LogRow2['OtherUserIDs']);
             if (!is_array($OtherUserIDs)) {
                 $OtherUserIDs = [];
             }
             if (!$LogRow2['InsertUserID']) {
                 $Set['InsertUserID'] = $InsertUserID;
             } elseif ($InsertUserID != $LogRow2['InsertUserID'] && !in_array($InsertUserID, $OtherUserIDs)) {
                 $OtherUserIDs[] = $InsertUserID;
             }
             if (array_key_exists('OtherUserIDs', $Options)) {
                 $OtherUserIDs = array_merge($OtherUserIDs, $Options['OtherUserIDs']);
                 $OtherUserIDs = array_unique($OtherUserIDs);
                 $OtherUserIDs = array_diff($OtherUserIDs, [$InsertUserID]);
                 $Count = count($OtherUserIDs) + 1;
             } else {
                 $Count = (int) $LogRow2['CountGroup'] + 1;
             }
             $Set['OtherUserIDs'] = implode(',', $OtherUserIDs);
             $Set['CountGroup'] = $Count;
             $Set['Data'] = dbencode($Data);
             $Set['DateUpdated'] = Gdn_Format::toDateTime();
             if (self::$transactionID > 0) {
                 $Set['TransactionLogID'] = self::$transactionID;
             } elseif (self::$transactionID === true) {
                 if ($LogRow2['TransactionLogID']) {
                     self::$transactionID = $LogRow2['TransactionLogID'];
                 } else {
                     self::$transactionID = $LogID;
                     $Set['TransactionLogID'] = $LogID;
                 }
             }
             Gdn::sql()->put('Log', $Set, ['LogID' => $LogID]);
         } else {
             $L = self::instance();
             $L->EventArguments['Log'] =& $LogRow;
             $L->fireEvent('BeforeInsert');
             if (self::$transactionID > 0) {
                 $LogRow['TransactionLogID'] = self::$transactionID;
             }
             $LogID = Gdn::sql()->insert('Log', $LogRow);
             if (self::$transactionID === true) {
                 // A new transaction was started and needs to assigned.
                 self::$transactionID = $LogID;
                 Gdn::sql()->put('Log', ['TransactionLogID' => $LogID], ['LogID' => $LogID]);
             }
             $L->EventArguments['LogID'] = $LogID;
             $L->fireEvent('AfterInsert');
         }
     } else {
         if (self::$transactionID > 0) {
             $LogRow['TransactionLogID'] = self::$transactionID;
         }
         // Insert the log entry.
         $L = self::instance();
         $L->EventArguments['Log'] =& $LogRow;
         $L->fireEvent('BeforeInsert');
         $LogID = Gdn::sql()->insert('Log', $LogRow);
         if (self::$transactionID === true) {
             // A new transaction was started and needs to assigned.
             self::$transactionID = $LogID;
             Gdn::sql()->put('Log', ['TransactionLogID' => $LogID], ['LogID' => $LogID]);
         }
         $L->EventArguments['LogID'] = $LogID;
         $L->fireEvent('AfterInsert');
     }
     return $LogID;
 }
예제 #4
0
 /**
  * Save a comment on an activity.
  *
  * @param array $Comment
  * @return int|bool|string
  * @since 2.1
  */
 public function comment($Comment)
 {
     $Comment['InsertUserID'] = Gdn::session()->UserID;
     $Comment['DateInserted'] = Gdn_Format::toDateTime();
     $Comment['InsertIPAddress'] = ipEncode(Gdn::request()->ipAddress());
     $this->Validation->applyRule('ActivityID', 'Required');
     $this->Validation->applyRule('Body', 'Required');
     $this->Validation->applyRule('DateInserted', 'Required');
     $this->Validation->applyRule('InsertUserID', 'Required');
     $this->EventArguments['Comment'] =& $Comment;
     $this->fireEvent('BeforeSaveComment');
     if ($this->validate($Comment)) {
         $Activity = $this->getID($Comment['ActivityID'], DATASET_TYPE_ARRAY);
         Gdn::controller()->json('Activity', $Activity);
         $_ActivityID = $Comment['ActivityID'];
         // Check to see if this is a shared activity/notification.
         if ($CommentActivityID = val('CommentActivityID', $Activity['Data'])) {
             Gdn::controller()->json('CommentActivityID', $CommentActivityID);
             $Comment['ActivityID'] = $CommentActivityID;
         }
         // Check for spam.
         $Spam = SpamModel::isSpam('ActivityComment', $Comment);
         if ($Spam) {
             return SPAM;
         }
         // Check for approval
         $ApprovalRequired = checkRestriction('Vanilla.Approval.Require');
         if ($ApprovalRequired && !val('Verified', Gdn::session()->User)) {
             LogModel::insert('Pending', 'ActivityComment', $Comment);
             return UNAPPROVED;
         }
         $ID = $this->SQL->insert('ActivityComment', $Comment);
         if ($ID) {
             // Check to see if this comment bumps the activity.
             if ($Activity && val('Bump', $Activity['Data'])) {
                 $this->SQL->put('Activity', ['DateUpdated' => $Comment['DateInserted']], ['ActivityID' => $Activity['ActivityID']]);
                 if ($_ActivityID != $Comment['ActivityID']) {
                     $this->SQL->put('Activity', ['DateUpdated' => $Comment['DateInserted']], ['ActivityID' => $_ActivityID]);
                 }
             }
             // Send a notification to the original person.
             if (val('ActivityType', $Activity) === 'WallPost') {
                 $this->notifyWallComment($Comment, $Activity);
             }
         }
         return $ID;
     }
     return false;
 }
예제 #5
0
 /**
  * Recursively walk through all array elements or object properties and encode IP fields.
  *
  * @param array|object $input
  * @return array|object
  */
 function ipEncodeRecursive($input)
 {
     walkAllRecursive($input, function (&$val, $key = null, $parent = null) {
         if (is_string($val)) {
             if (stringEndsWith($key, 'IPAddress', true) || stringEndsWith($parent, 'IPAddresses', true)) {
                 $val = ipEncode($val);
             }
         }
     });
     return $input;
 }
예제 #6
0
 /**
  * Adds $this->UpdateUserID and $this->DateUpdated fields to an associative
  * array of fieldname/values if those fields exist on the table being updated.
  *
  * @param array $Fields The array of fields to add the values to.
  */
 protected function addUpdateFields(&$Fields)
 {
     $this->defineSchema();
     if ($this->Schema->fieldExists($this->Name, $this->DateUpdated)) {
         if (!isset($Fields[$this->DateUpdated])) {
             $Fields[$this->DateUpdated] = Gdn_Format::toDateTime();
         }
     }
     $Session = Gdn::session();
     if ($Session->UserID > 0 && $this->Schema->fieldExists($this->Name, $this->UpdateUserID)) {
         if (!isset($Fields[$this->UpdateUserID])) {
             $Fields[$this->UpdateUserID] = $Session->UserID;
         }
     }
     if ($this->Schema->FieldExists($this->Name, 'UpdateIPAddress') && !isset($Fields['UpdateIPAddress'])) {
         $Fields['UpdateIPAddress'] = ipEncode(Gdn::request()->ipAddress());
     }
 }