/** * Render the data array. * * @param null $Data * @return bool * @throws Exception */ public function renderData($Data = null) { if ($Data === null) { $Data = array(); // Remove standard and "protected" data from the top level. foreach ($this->Data as $Key => $Value) { if ($Key && in_array($Key, array('Title', 'Breadcrumbs'))) { continue; } if (isset($Key[0]) && $Key[0] === '_') { continue; // protected } $Data[$Key] = $Value; } unset($this->Data); } // Massage the data for better rendering. foreach ($Data as $Key => $Value) { if (is_a($Value, 'Gdn_DataSet')) { $Data[$Key] = $Value->resultArray(); } } $CleanOutut = c('Api.Clean', true); if ($CleanOutut) { // Remove values that should not be transmitted via api $Remove = array('Password', 'HashMethod', 'TransientKey', 'Permissions', 'Attributes', 'AccessToken'); // Remove PersonalInfo values for unprivileged requests. if (!Gdn::session()->checkPermission('Garden.Moderation.Manage')) { $Remove[] = 'InsertIPAddress'; $Remove[] = 'UpdateIPAddress'; $Remove[] = 'LastIPAddress'; $Remove[] = 'AllIPAddresses'; $Remove[] = 'Fingerprint'; if (c('Api.Clean.Email', true)) { $Remove[] = 'Email'; } $Remove[] = 'DateOfBirth'; $Remove[] = 'Preferences'; $Remove[] = 'Banned'; $Remove[] = 'Admin'; $Remove[] = 'Confirmed'; $Remove[] = 'Verified'; $Remove[] = 'DiscoveryText'; $Remove[] = 'InviteUserID'; $Remove[] = 'DateSetInvitations'; $Remove[] = 'CountInvitations'; $Remove[] = 'CountNotifications'; $Remove[] = 'CountBookmarks'; $Remove[] = 'CountDrafts'; $Remove[] = 'HourOffset'; $Remove[] = 'Gender'; $Remove[] = 'Punished'; $Remove[] = 'Troll'; } $Data = removeKeysFromNestedArray($Data, $Remove); } if (debug() && ($Trace = trace())) { // Clear passwords from the trace. array_walk_recursive($Trace, function (&$Value, $Key) { if (in_array(strtolower($Key), array('password'))) { $Value = '***'; } }); $Data['Trace'] = $Trace; } // Make sure the database connection is closed before exiting. $this->EventArguments['Data'] =& $Data; $this->finalize(); // Add error information from the form. if (isset($this->Form) && sizeof($this->Form->validationResults())) { $this->statusCode(400); $Data['Code'] = 400; $Data['Exception'] = Gdn_Validation::resultsAsText($this->Form->validationResults()); } $this->sendHeaders(); $Data = ipDecodeRecursive($Data); // Check for a special view. $ViewLocation = $this->fetchViewLocation(($this->View ? $this->View : $this->RequestMethod) . '_' . strtolower($this->deliveryMethod()), false, false, false); if (file_exists($ViewLocation)) { include $ViewLocation; return; } // Add schemes to to urls. if (!c('Garden.AllowSSL') || c('Garden.ForceSSL')) { $r = array_walk_recursive($Data, array('Gdn_Controller', '_FixUrlScheme'), Gdn::request()->scheme()); } if (ob_get_level()) { ob_clean(); } switch ($this->deliveryMethod()) { case DELIVERY_METHOD_XML: safeHeader('Content-Type: text/xml', true); echo '<?xml version="1.0" encoding="utf-8"?>' . "\n"; $this->_renderXml($Data); return true; break; case DELIVERY_METHOD_PLAIN: return true; break; case DELIVERY_METHOD_JSON: default: $jsonData = jsonEncodeChecked($Data); if (($Callback = $this->Request->get('callback', false)) && $this->allowJSONP()) { safeHeader('Content-Type: application/javascript; charset=utf-8', true); // This is a jsonp request. echo "{$Callback}({$jsonData});"; return true; } else { safeHeader('Content-Type: application/json; charset=utf-8', true); // This is a regular json request. echo $jsonData; return true; } break; } return false; }
/** * Check whether or not the record is spam. * @param string $RecordType By default, this should be one of the following: * - Comment: A comment. * - Discussion: A discussion. * - User: A user registration. * @param array $Data The record data. * @param array $Options Options for fine-tuning this method call. * - Log: Log the record if it is found to be spam. */ public static function isSpam($RecordType, $Data, $Options = array()) { if (self::$Disabled) { return false; } // Set some information about the user in the data. if ($RecordType == 'Registration') { touchValue('Username', $Data, $Data['Name']); } else { touchValue('InsertUserID', $Data, Gdn::session()->UserID); $User = Gdn::userModel()->getID(val('InsertUserID', $Data), DATASET_TYPE_ARRAY); if ($User) { if (val('Verified', $User)) { // The user has been verified and isn't a spammer. return false; } touchValue('Username', $Data, $User['Name']); touchValue('Email', $Data, $User['Email']); touchValue('IPAddress', $Data, $User['LastIPAddress']); } } if (!isset($Data['Body']) && isset($Data['Story'])) { $Data['Body'] = $Data['Story']; } // Make sure all IP addresses are unpacked. $Data = ipDecodeRecursive($Data); touchValue('IPAddress', $Data, Gdn::request()->ipAddress()); $Sp = self::_Instance(); $Sp->EventArguments['RecordType'] = $RecordType; $Sp->EventArguments['Data'] =& $Data; $Sp->EventArguments['Options'] =& $Options; $Sp->EventArguments['IsSpam'] = false; $Sp->fireEvent('CheckSpam'); $Spam = $Sp->EventArguments['IsSpam']; // Log the spam entry. if ($Spam && val('Log', $Options, true)) { $LogOptions = array(); switch ($RecordType) { case 'Registration': $LogOptions['GroupBy'] = array('RecordIPAddress'); break; case 'Comment': case 'Discussion': case 'Activity': case 'ActivityComment': $LogOptions['GroupBy'] = array('RecordID'); break; } // If this is a discussion or a comment, it needs some special handling. if ($RecordType == 'Comment' || $RecordType == 'Discussion') { // Grab the record ID, if available. $recordID = intval(val("{$RecordType}ID", $Data)); /** * If we have a valid record ID, run it through flagForReview. This will allow us to purge existing * discussions and comments that have been flagged as SPAM after being edited. If there's no valid ID, * just treat it with regular SPAM logging. */ if ($recordID) { self::flagForReview($RecordType, $recordID, $Data); } else { LogModel::insert('Spam', $RecordType, $Data, $LogOptions); } } else { LogModel::insert('Spam', $RecordType, $Data, $LogOptions); } } return $Spam; }
/** * Encode a value in preparation for database storage. * * @param mixed $value A value to be encoded. * @return mixed An encoded string representation of the provided value or false on failure. */ function dbencode($value) { if ($value === null || $value === '') { return null; } if (is_array($value) || is_object($value)) { // IP addresses are binary packed now. // Let's convert them to text so that they can be safely inserted into the text column $value = ipDecodeRecursive($value); } $encodedValue = serialize($value); return $encodedValue; }