Ejemplo n.º 1
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 = 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;
 }