/** * * * @param $Row */ protected static function calculate(&$Row) { if (!$Row) { return; } $Attributes = dbdecode($Row['Attributes']); if (is_array($Attributes)) { $Row = array_merge($Attributes, $Row); } unset($Row['Attributes']); }
/** * {@inheritDoc} * @param array $Data * @param bool $Settings * @return bool|mixed Primary Key Value */ public function save($Data, $Settings = false) { $this->defineSchema(); $SchemaFields = $this->Schema->fields(); $SaveData = array(); $Attributes = array(); // Grab the current attachment. if (isset($Data['AttachmentID'])) { $PrimaryKeyVal = $Data['AttachmentID']; $CurrentAttachment = $this->SQL->getWhere('Attachment', array('AttachmentID' => $PrimaryKeyVal))->firstRow(DATASET_TYPE_ARRAY); if ($CurrentAttachment) { $Attributes = dbdecode($CurrentAttachment['Attributes']); if (!$Attributes) { $Attributes = array(); } $Insert = false; } else { $Insert = true; } } else { $PrimaryKeyVal = false; $Insert = true; } // Grab any values that aren't in the db schema and stick them in attributes. foreach ($Data as $Name => $Value) { if ($Name == 'Attributes') { continue; } if (isset($SchemaFields[$Name])) { $SaveData[$Name] = $Value; } elseif ($Value === null) { unset($Attributes[$Name]); } else { $Attributes[$Name] = $Value; } } if (sizeof($Attributes)) { $SaveData['Attributes'] = $Attributes; } else { $SaveData['Attributes'] = null; } if ($Insert) { $this->addInsertFields($SaveData); } else { $this->addUpdateFields($SaveData); } // Validate the form posted values. if ($this->validate($SaveData, $Insert) === true) { $Fields = $this->Validation->validationFields(); if ($Insert === false) { unset($Fields[$this->PrimaryKey]); // Don't try to update the primary key $this->update($Fields, array($this->PrimaryKey => $PrimaryKeyVal)); } else { $PrimaryKeyVal = $this->insert($Fields); } } else { $PrimaryKeyVal = false; } return $PrimaryKeyVal; }
/** * * * @param string $Column * @param int $RowID * @param string $Name * @param string $Value * @return bool|Gdn_DataSet|object|string * @throws Exception */ public function saveToSerializedColumn($Column, $RowID, $Name, $Value = '') { if (!isset($this->Schema)) { $this->defineSchema(); } // TODO: need to be sure that $this->PrimaryKey is only one primary key $FieldName = $this->PrimaryKey; // Load the existing values $Row = $this->SQL->select($Column)->from($this->Name)->where($FieldName, $RowID)->get()->firstRow(); if (!$Row) { throw new Exception(T('ErrorRecordNotFound')); } $Values = dbdecode($Row->{$Column}); if (is_string($Values) && $Values != '') { throw new Exception(T('Serialized column failed to be unserialized.')); } if (!is_array($Values)) { $Values = array(); } if (!is_array($Name)) { // Assign the new value(s) $Name = array($Name => $Value); } $Values = dbencode(array_merge($Values, $Name)); // Save the values back to the db return $this->SQL->from($this->Name)->where($FieldName, $RowID)->set($Column, $Values)->put(); }
/** * * * @param $Table * @param $Key * @param int $Limit * @param bool $Max * @return array|mixed */ public function getBatch($Table, $Key, $Limit = 10000, $Max = false) { $Key = "DBA.Range.{$Key}"; // See if there is already a range. $Current = dbdecode(Gdn::get($Key, '')); if (!is_array($Current) || !isset($Current['Min']) || !isset($Current['Max'])) { list($Current['Min'], $Current['Max']) = $this->primaryKeyRange($Table); if ($Max && $Current['Max'] > $Max) { $Current['Max'] = $Max; } } if (!isset($Current['To'])) { $Current['To'] = $Current['Max']; } else { $Current['To'] -= $Limit - 1; } $Current['From'] = $Current['To'] - $Limit; Gdn::set($Key, dbencode($Current)); $Current['Complete'] = $Current['To'] < $Current['Min']; $Total = $Current['Max'] - $Current['Min']; if ($Total > 0) { $Complete = $Current['Max'] - $Current['From']; $Percent = 100 * $Complete / $Total; if ($Percent > 100) { $Percent = 100; } $Current['Percent'] = round($Percent) . '%'; } return $Current; }
/** * * * @param $Sender */ public function discussionController_beforeDiscussionRender_handler($Sender) { if (!Gdn::session()->isValid()) { return; } $UserPrefs = dbdecode(Gdn::session()->User->Preferences); if (!is_array($UserPrefs)) { $UserPrefs = array(); } $QuoteFolding = val('Quotes.Folding', $UserPrefs, '1'); $Sender->addDefinition('QuotesFolding', $QuoteFolding); }
/** * * * @param null $client_id * @return array|mixed */ public static function getProvider($client_id = null) { if ($client_id !== null) { $Where = ['AuthenticationKey' => $client_id]; } else { $Where = ['AuthenticationSchemeAlias' => 'jsconnect']; } $Result = Gdn::sql()->getWhere('UserAuthenticationProvider', $Where)->resultArray(); foreach ($Result as &$Row) { $Attributes = dbdecode($Row['Attributes']); if (is_array($Attributes)) { $Row = array_merge($Attributes, $Row); } } if ($client_id) { return val(0, $Result, false); } else { return $Result; } return $Result; }
/** * 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; }
/** * Edit user's preferences (mostly notification settings). * * @since 2.0.0 * @access public * @param mixed $UserReference Unique identifier, possibly username or ID. * @param string $Username . * @param int $UserID Unique identifier. */ public function preferences($UserReference = '', $Username = '', $UserID = '') { $this->addJsFile('profile.js'); $Session = Gdn::session(); $this->permission('Garden.SignIn.Allow'); // Get user data $this->getUserInfo($UserReference, $Username, $UserID, true); $UserPrefs = dbdecode($this->User->Preferences); if ($this->User->UserID != $Session->UserID) { $this->permission(array('Garden.Users.Edit', 'Moderation.Profiles.Edit'), false); } if (!is_array($UserPrefs)) { $UserPrefs = array(); } $MetaPrefs = UserModel::GetMeta($this->User->UserID, 'Preferences.%', 'Preferences.'); // Define the preferences to be managed $Notifications = array(); if (c('Garden.Profile.ShowActivities', true)) { $Notifications = array('Email.WallComment' => t('Notify me when people write on my wall.'), 'Email.ActivityComment' => t('Notify me when people reply to my wall comments.'), 'Popup.WallComment' => t('Notify me when people write on my wall.'), 'Popup.ActivityComment' => t('Notify me when people reply to my wall comments.')); } $this->Preferences = array('Notifications' => $Notifications); // Allow email notification of applicants (if they have permission & are using approval registration) if (checkPermission('Garden.Users.Approve') && c('Garden.Registration.Method') == 'Approval') { $this->Preferences['Notifications']['Email.Applicant'] = array(t('NotifyApplicant', 'Notify me when anyone applies for membership.'), 'Meta'); } $this->fireEvent('AfterPreferencesDefined'); // Loop through the preferences looking for duplicates, and merge into a single row $this->PreferenceGroups = array(); $this->PreferenceTypes = array(); foreach ($this->Preferences as $PreferenceGroup => $Preferences) { $this->PreferenceGroups[$PreferenceGroup] = array(); $this->PreferenceTypes[$PreferenceGroup] = array(); foreach ($Preferences as $Name => $Description) { $Location = 'Prefs'; if (is_array($Description)) { list($Description, $Location) = $Description; } $NameParts = explode('.', $Name); $PrefType = val('0', $NameParts); $SubName = val('1', $NameParts); if ($SubName != false) { // Save an array of all the different types for this group if (!in_array($PrefType, $this->PreferenceTypes[$PreferenceGroup])) { $this->PreferenceTypes[$PreferenceGroup][] = $PrefType; } // Store all the different subnames for the group if (!array_key_exists($SubName, $this->PreferenceGroups[$PreferenceGroup])) { $this->PreferenceGroups[$PreferenceGroup][$SubName] = array($Name); } else { $this->PreferenceGroups[$PreferenceGroup][$SubName][] = $Name; } } else { $this->PreferenceGroups[$PreferenceGroup][$Name] = array($Name); } } } // Loop the preferences, setting defaults from the configuration. $CurrentPrefs = array(); foreach ($this->Preferences as $PrefGroup => $Prefs) { foreach ($Prefs as $Pref => $Desc) { $Location = 'Prefs'; if (is_array($Desc)) { list($Desc, $Location) = $Desc; } if ($Location == 'Meta') { $CurrentPrefs[$Pref] = val($Pref, $MetaPrefs, false); } else { $CurrentPrefs[$Pref] = val($Pref, $UserPrefs, c('Preferences.' . $Pref, '0')); } unset($MetaPrefs[$Pref]); } } $CurrentPrefs = array_merge($CurrentPrefs, $MetaPrefs); $CurrentPrefs = array_map('intval', $CurrentPrefs); $this->setData('Preferences', $CurrentPrefs); if (UserModel::noEmail()) { $this->PreferenceGroups = self::_removeEmailPreferences($this->PreferenceGroups); $this->PreferenceTypes = self::_removeEmailPreferences($this->PreferenceTypes); $this->setData('NoEmail', true); } $this->setData('PreferenceGroups', $this->PreferenceGroups); $this->setData('PreferenceTypes', $this->PreferenceTypes); $this->setData('PreferenceList', $this->Preferences); if ($this->Form->authenticatedPostBack()) { // Get, assign, and save the preferences. $NewMetaPrefs = array(); foreach ($this->Preferences as $PrefGroup => $Prefs) { foreach ($Prefs as $Pref => $Desc) { $Location = 'Prefs'; if (is_array($Desc)) { list($Desc, $Location) = $Desc; } $Value = $this->Form->getValue($Pref, null); if (is_null($Value)) { continue; } if ($Location == 'Meta') { $NewMetaPrefs[$Pref] = $Value ? $Value : null; if ($Value) { $UserPrefs[$Pref] = $Value; // dup for notifications code. } } else { if (!$CurrentPrefs[$Pref] && !$Value) { unset($UserPrefs[$Pref]); // save some space } else { $UserPrefs[$Pref] = $Value; } } } } $this->UserModel->savePreference($this->User->UserID, $UserPrefs); UserModel::setMeta($this->User->UserID, $NewMetaPrefs, 'Preferences.'); $this->setData('Preferences', array_merge($this->data('Preferences', array()), $UserPrefs, $NewMetaPrefs)); if (count($this->Form->errors() == 0)) { $this->informMessage(sprite('Check', 'InformSprite') . t('Your preferences have been saved.'), 'Dismissable AutoDismiss HasSprite'); } } else { $this->Form->setData($CurrentPrefs); } $this->title(t('Notification Preferences')); $this->_setBreadcrumbs($this->data('Title'), $this->canonicalUrl()); $this->render(); }
/** * Unserialize the fields in the dataset. * * @param array $Fields * @since 2.1 */ public function unserialize($Fields = array('Attributes', 'Data')) { $Result =& $this->result(); $First = true; foreach ($Result as &$Row) { if ($First) { // Check which fields are in the dataset. foreach ($Fields as $Index => $Field) { if (val($Field, $Row, false) === false) { unset($Fields[$Index]); } } $First = false; } foreach ($Fields as $Field) { if (is_object($Row)) { if (is_string($Row->{$Field})) { $Row->{$Field} = dbdecode($Row->{$Field}); } } else { if (is_string($Row[$Field])) { $Row[$Field] = dbdecode($Row[$Field]); } } } } }
/** * * * @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; }
/** * Restores a single entry from the log. * * @param array $Log The log entry. * @param bool $DeleteLog Whether or not to delete the log entry after the restore. * @throws Exception Throws an exception if restoring the record causes a validation error. */ private function restoreOne($Log, $DeleteLog = true) { // Throw an event to see if the restore is being overridden. $Handled = false; $this->EventArguments['Handled'] =& $Handled; $this->EventArguments['Log'] =& $Log; $this->fireEvent('BeforeRestore'); if ($Handled) { return; // a plugin handled the restore. } if ($Log['RecordType'] == 'Configuration') { throw new Gdn_UserException('Restoring configuration edits is currently not supported.'); } if ($Log['RecordType'] == 'Registration') { $TableName = 'User'; } else { $TableName = $Log['RecordType']; } $Data = $Log['Data']; if (isset($Data['Attributes'])) { $Attr = 'Attributes'; } elseif (isset($Data['Data'])) { $Attr = 'Data'; } else { $Attr = ''; } if ($Attr) { if (is_string($Data[$Attr])) { $Data[$Attr] = dbdecode($Data[$Attr]); } // Record a bit of information about the restoration. if (!is_array($Data[$Attr])) { $Data[$Attr] = []; } $Data[$Attr]['RestoreUserID'] = Gdn::session()->UserID; $Data[$Attr]['DateRestored'] = Gdn_Format::toDateTime(); } if (!isset($Columns[$TableName])) { $Columns[$TableName] = Gdn::sql()->fetchColumns($TableName); } $Set = array_flip($Columns[$TableName]); // Set the sets from the data. foreach ($Set as $Key => $Value) { if (isset($Data[$Key])) { $Value = $Data[$Key]; if (is_array($Value)) { $Value = dbencode($Value); } $Set[$Key] = $Value; } else { unset($Set[$Key]); } } switch ($Log['Operation']) { case 'Edit': // We are restoring an edit so just update the record. $IDColumn = $Log['RecordType'] . 'ID'; $Where = [$IDColumn => $Log['RecordID']]; unset($Set[$IDColumn]); Gdn::sql()->put($TableName, $Set, $Where); break; case 'Delete': case 'Spam': case 'Moderate': case 'Pending': case 'Ban': if (!$Log['RecordID']) { // This log entry was never in the table. if (isset($Set['DateInserted'])) { $Set['DateInserted'] = Gdn_Format::toDateTime(); } } // Insert the record back into the db. if ($Log['Operation'] == 'Spam' && $Log['RecordType'] == 'Registration') { saveToConfig(['Garden.Registration.NameUnique' => false, 'Garden.Registration.EmailUnique' => false], '', false); if (isset($Data['Username'])) { $Set['Name'] = $Data['Username']; } $ID = Gdn::userModel()->insertForBasic($Set, false, ['ValidateSpam' => false]); if (!$ID) { throw new Exception(Gdn::userModel()->Validation->resultsText()); } else { Gdn::userModel()->sendWelcomeEmail($ID, '', 'Register'); } } else { $ID = Gdn::sql()->options('Replace', true)->insert($TableName, $Set); if (!$ID && isset($Log['RecordID'])) { $ID = $Log['RecordID']; } // Unban a user. if ($Log['RecordType'] == 'User' && $Log['Operation'] == 'Ban') { Gdn::userModel()->setField($ID, 'Banned', 0); } // Keep track of a discussion ID so that its count can be recalculated. if ($Log['Operation'] != 'Edit') { switch ($Log['RecordType']) { case 'Discussion': $this->recalcIDs['Discussion'][$ID] = true; break; case 'Comment': $this->recalcIDs['Discussion'][$Log['ParentRecordID']] = true; break; } } if ($Log['Operation'] == 'Pending') { switch ($Log['RecordType']) { case 'Discussion': if (val('UserDiscussion', $this->recalcIDs) && val($Log['RecordUserID'], $this->recalcIDs['UserDiscussion'])) { $this->recalcIDs['UserDiscussion'][$Log['RecordUserID']]++; } else { $this->recalcIDs['UserDiscussion'][$Log['RecordUserID']] = 1; } break; case 'Comment': if (val('UserComment', $this->recalcIDs) && val($Log['RecordUserID'], $this->recalcIDs['UserComment'])) { $this->recalcIDs['UserComment'][$Log['RecordUserID']]++; } else { $this->recalcIDs['UserComment'][$Log['RecordUserID']] = 1; } break; } } } break; } // Fire 'after' event if (isset($ID)) { $this->EventArguments['InsertID'] = $ID; } $this->fireEvent('AfterRestore'); if ($DeleteLog) { Gdn::sql()->delete('Log', ['LogID' => $Log['LogID']]); } }
/** * Used by $this->stash() to create & manage sessions for users & guests. * * This is a stop-gap solution until full session management for users & * guests can be implemented. * * @param Gdn_SQLDriver $sql Local clone of the sql driver. * @param string $valueToStash The value of the stash to set. * * @return bool|Gdn_DataSet Current session. */ private function getStashSession($sql, $valueToStash) { $cookieName = c('Garden.Cookie.Name', 'Vanilla'); $name = $cookieName . '-sid'; // Grab the entire session record. $sessionID = val($name, $_COOKIE, ''); // If there is no session, and no value for saving, return. if ($sessionID == '' && $valueToStash == '') { return false; } $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow(); if (!$session) { $sessionID = betterRandomString(32); $transientKey = substr(md5(mt_rand()), 0, 11) . '!'; // Save the session information to the database. $sql->insert('Session', ['SessionID' => $sessionID, 'UserID' => Gdn::session()->UserID, 'TransientKey' => $transientKey, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime()]); trace("Inserting session stash {$sessionID}"); $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow(); // Save a session cookie. $path = c('Garden.Cookie.Path', '/'); $domain = c('Garden.Cookie.Domain', ''); $expire = 0; // If the domain being set is completely incompatible with the // current domain then make the domain work. $currentHost = Gdn::request()->host(); if (!stringEndsWith($currentHost, trim($domain, '.'))) { $domain = ''; } safeCookie($name, $sessionID, $expire, $path, $domain); $_COOKIE[$name] = $sessionID; } $session->Attributes = dbdecode($session->Attributes); if (!$session->Attributes) { $session->Attributes = []; } return $session; }
/** * Convert tags from stored format to user-presentable format. * * @param string $Tags A string encoded with {@link dbencode()}. * @return string Comma-separated tags. * @since 2.1 */ private function formatTags($Tags) { // Don't bother if there aren't any tags if (!$Tags) { return ''; } // Get the array. if (preg_match('`^(a:)|{|\\[`', $Tags)) { $TagsArray = dbdecode($Tags); } else { $TagsArray = $Tags; } // Compensate for deprecated space-separated format if (is_string($TagsArray) && $TagsArray == $Tags) { $TagsArray = explode(' ', $Tags); } // Safe format $TagsArray = Gdn_Format::text($TagsArray); // Send back an comma-separated string return is_array($TagsArray) ? implode(',', $TagsArray) : ''; }
/** * Calculate dynamic data on a category. * * @param array &$category The category to calculate. */ private function calculate(&$category) { $category['CountAllDiscussions'] = $category['CountDiscussions']; $category['CountAllComments'] = $category['CountComments']; // $category['Url'] = self::categoryUrl($category, false, '/'); $category['ChildIDs'] = []; // if (val('Photo', $category)) { // $category['PhotoUrl'] = Gdn_Upload::url($category['Photo']); // } else { // $category['PhotoUrl'] = ''; // } if ($category['DisplayAs'] == 'Default') { if ($category['Depth'] <= $this->config('Vanilla.Categories.NavDepth', 0)) { $category['DisplayAs'] = 'Categories'; } elseif ($category['Depth'] == $this->config('Vanilla.Categories.NavDepth', 0) + 1 && $this->config('Vanilla.Categories.DoHeadings')) { $category['DisplayAs'] = 'Heading'; } else { $category['DisplayAs'] = 'Discussions'; } } if (!val('CssClass', $category)) { $category['CssClass'] = 'Category-' . $category['UrlCode']; } if (isset($category['AllowedDiscussionTypes']) && is_string($category['AllowedDiscussionTypes'])) { $category['AllowedDiscussionTypes'] = dbdecode($category['AllowedDiscussionTypes']); } }
/** * Calculate dynamic data on a category. * * This method is passed as a callback by default in {@link setCalculator}, but may not show up as used. * * @param array &$category The category to calculate. */ private function defaultCalculator(&$category) { $category['CountAllDiscussions'] = $category['CountDiscussions']; $category['CountAllComments'] = $category['CountComments']; // $category['Url'] = self::categoryUrl($category, false, '/'); $category['ChildIDs'] = []; // if (val('Photo', $category)) { // $category['PhotoUrl'] = Gdn_Upload::url($category['Photo']); // } else { // $category['PhotoUrl'] = ''; // } CategoryModel::calculateDisplayAs($category); if (!val('CssClass', $category)) { $category['CssClass'] = 'Category-' . $category['UrlCode']; } if (isset($category['AllowedDiscussionTypes']) && is_string($category['AllowedDiscussionTypes'])) { $category['AllowedDiscussionTypes'] = dbdecode($category['AllowedDiscussionTypes']); } }
/** * Format an encoded string of image properties as HTML. * * @param string $Body a encoded array of image properties (Image, Thumbnail, Caption) * @return string HTML */ public static function image($Body) { if (is_string($Body)) { $Image = dbdecode($Body); if (!$Image) { return Gdn_Format::html($Body); } } $Url = val('Image', $Image); $Caption = Gdn_Format::plainText(val('Caption', $Image)); return '<div class="ImageWrap">' . '<div class="Image">' . img($Url, array('alt' => $Caption, 'title' => $Caption)) . '</div>' . '<div class="Caption">' . $Caption . '</div>' . '</div>'; }
public function controller_index($Sender) { $Sender->Permission(array('Garden.Profiles.Edit')); $Args = $Sender->RequestArgs; if (sizeof($Args) < 2) { $Args = array_merge($Args, array(0, 0)); } elseif (sizeof($Args) > 2) { $Args = array_slice($Args, 0, 2); } list($UserReference, $Username) = $Args; $canEditSignatures = CheckPermission('Plugins.Signatures.Edit'); // Normalize no image config setting if (C('Plugins.Signatures.MaxNumberImages') === 0 || C('Plugins.Signatures.MaxNumberImages') === '0') { SaveToConfig('Plugins.Signatures.MaxNumberImages', 'None'); } $Sender->GetUserInfo($UserReference, $Username); $UserPrefs = dbdecode($Sender->User->Preferences); if (!is_array($UserPrefs)) { $UserPrefs = array(); } $Validation = new Gdn_Validation(); $ConfigurationModel = new Gdn_ConfigurationModel($Validation); $ConfigArray = array('Plugin.Signatures.Sig' => NULL, 'Plugin.Signatures.HideAll' => NULL, 'Plugin.Signatures.HideImages' => NULL, 'Plugin.Signatures.HideMobile' => NULL, 'Plugin.Signatures.Format' => NULL); $SigUserID = $ViewingUserID = Gdn::Session()->UserID; if ($Sender->User->UserID != $ViewingUserID) { $Sender->Permission(array('Garden.Users.Edit', 'Moderation.Signatures.Edit'), FALSE); $SigUserID = $Sender->User->UserID; $canEditSignatures = true; } $Sender->SetData('CanEdit', $canEditSignatures); $Sender->SetData('Plugin-Signatures-ForceEditing', $SigUserID == Gdn::Session()->UserID ? FALSE : $Sender->User->Name); $UserMeta = $this->GetUserMeta($SigUserID, '%'); if ($Sender->Form->AuthenticatedPostBack() === FALSE && is_array($UserMeta)) { $ConfigArray = array_merge($ConfigArray, $UserMeta); } $ConfigurationModel->SetField($ConfigArray); // Set the model on the form. $Sender->Form->SetModel($ConfigurationModel); $Data = $ConfigurationModel->Data; $Sender->SetData('Signature', $Data); $this->SetSignatureRules($Sender); // Form submission handling. if ($Sender->Form->AuthenticatedPostBack()) { $Values = $Sender->Form->FormValues(); if ($canEditSignatures) { $Values['Plugin.Signatures.Sig'] = GetValue('Body', $Values, NULL); $Values['Plugin.Signatures.Format'] = GetValue('Format', $Values, NULL); } //$this->StripLineBreaks($Values['Plugin.Signatures.Sig']); $FrmValues = array_intersect_key($Values, $ConfigArray); if (sizeof($FrmValues)) { if (!GetValue($this->MakeMetaKey('Sig'), $FrmValues)) { // Delete the signature. $FrmValues[$this->MakeMetaKey('Sig')] = NULL; $FrmValues[$this->MakeMetaKey('Format')] = NULL; } $this->CrossCheckSignature($Values, $Sender); if ($Sender->Form->ErrorCount() == 0) { foreach ($FrmValues as $UserMetaKey => $UserMetaValue) { $Key = $this->TrimMetaKey($UserMetaKey); switch ($Key) { case 'Format': if (strcasecmp($UserMetaValue, 'Raw') == 0) { $UserMetaValue = NULL; } // don't allow raw signatures. break; } $this->SetUserMeta($SigUserID, $Key, $UserMetaValue); } $Sender->InformMessage(T("Your changes have been saved.")); } } } else { // Load form data. $Data['Body'] = GetValue('Plugin.Signatures.Sig', $Data); $Data['Format'] = GetValue('Plugin.Signatures.Format', $Data) ?: Gdn_Format::DefaultFormat(); // Apply the config settings to the form. $Sender->Form->SetData($Data); } $Sender->Render('signature', '', 'plugins/Signatures'); }
/** * Get data for a single category selected by ID. Disregards permissions. * * @since 2.0.0 * * @param int $categoryID The unique ID of category we're getting data for. * @param string $datasetType Not used. * @param array $options Not used. * @return object|array SQL results. */ public function getID($categoryID, $datasetType = DATASET_TYPE_OBJECT, $options = []) { $category = $this->SQL->getWhere('Category', array('CategoryID' => $categoryID))->firstRow($datasetType); if (val('AllowedDiscussionTypes', $category) && is_string(val('AllowedDiscussionTypes', $category))) { setValue('AllowedDiscussionTypes', $category, dbdecode(val('AllowedDiscussionTypes', $category))); } return $category; }
function writeReactions($Row) { $Attributes = GetValue('Attributes', $Row); if (is_string($Attributes)) { $Attributes = dbdecode($Attributes); SetValue('Attributes', $Row, $Attributes); } Gdn::controller()->EventArguments['ReactionTypes'] = array(); if ($ID = GetValue('CommentID', $Row)) { $RecordType = 'comment'; } elseif ($ID = GetValue('ActivityID', $Row)) { $RecordType = 'activity'; } else { $RecordType = 'discussion'; $ID = GetValue('DiscussionID', $Row); } Gdn::controller()->EventArguments['RecordType'] = $RecordType; Gdn::controller()->EventArguments['RecordID'] = $ID; echo '<div class="Reactions">'; Gdn_Theme::bulletRow(); // Write the flags. static $Flags = null; if ($Flags === null) { Gdn::controller()->EventArguments['Flags'] =& $Flags; Gdn::controller()->fireEvent('Flags'); } // Allow addons to work with flags Gdn::controller()->EventArguments['Flags'] =& $Flags; Gdn::controller()->fireEvent('BeforeFlag'); if (!empty($Flags) && is_array($Flags)) { echo Gdn_Theme::bulletItem('Flags'); echo ' <span class="FlagMenu ToggleFlyout">'; // Write the handle. echo anchor(sprite('ReactFlag', 'ReactSprite') . ' ' . wrap(t('Flag'), 'span', array('class' => 'ReactLabel')), '', 'Hijack ReactButton-Flag FlyoutButton', array('title' => t('Flag')), true); echo sprite('SpFlyoutHandle', 'Arrow'); echo '<ul class="Flyout MenuItems Flags" style="display: none;">'; foreach ($Flags as $Flag) { if (is_callable($Flag)) { echo '<li>' . call_user_func($Flag, $Row, $RecordType, $ID) . '</li>'; } else { echo '<li>' . reactionButton($Row, $Flag['UrlCode']) . '</li>'; } } Gdn::controller()->fireEvent('AfterFlagOptions'); echo '</ul>'; echo '</span> '; } Gdn::controller()->fireEvent('AfterFlag'); Gdn::controller()->fireEvent('AfterReactions'); echo '</div>'; Gdn::controller()->fireEvent('Replies'); }
/** * Modifies comment data before it is returned. * * @since 2.1a32 * @access public * * @param object $Data SQL result. */ public function calculate($Comment) { // Do nothing yet. if ($Attributes = val('Attributes', $Comment)) { setValue('Attributes', $Comment, dbdecode($Attributes)); } $this->EventArguments['Comment'] = $Comment; $this->fireEvent('SetCalculatedFields'); }
/** * Grab second forum's data and merge with current forum. * * Merge Users on email address. Keeps this forum's username/password. * Merge Roles, Tags, and Categories on precise name matches. * * @todo Compare column names between forums and use intersection */ public function MergeForums($OldDatabase, $OldPrefix, $LegacySlug) { $NewPrefix = C('Database.DatabasePrefix'); $this->OldDatabase = $OldDatabase; $this->OldPrefix = $OldPrefix; $DoLegacy = !empty($LegacySlug); // USERS // if ($this->OldTableExists('User')) { $UserColumns = $this->GetColumns('User', $OldDatabase, $OldPrefix); // Merge IDs of duplicate users Gdn::SQL()->Query('update ' . $NewPrefix . 'User u set u.OldID = (select u2.UserID from `' . $OldDatabase . '`.' . $OldPrefix . 'User u2 where u2.Email = u.Email limit 1)'); // Copy non-duplicate users Gdn::SQL()->Query('insert into ' . $NewPrefix . 'User (' . $UserColumns . ', OldID) select ' . $UserColumns . ', UserID from `' . $OldDatabase . '`.' . $OldPrefix . 'User where Email not in (select Email from ' . $NewPrefix . 'User)'); // UserMeta if ($this->OldTableExists('UserMeta')) { Gdn::SQL()->Query('insert ignore into ' . $NewPrefix . 'UserMeta (UserID, Name, Value) select u.UserID, um.Name, um.Value from ' . $NewPrefix . 'User u, `' . $OldDatabase . '`.' . $OldPrefix . 'UserMeta um where u.OldID = um.UserID'); } } // ROLES // if ($this->OldTableExists('Role')) { $RoleColumns = $this->GetColumns('Role', $OldDatabase, $OldPrefix); // Merge IDs of duplicate roles Gdn::SQL()->Query('update ' . $NewPrefix . 'Role r set r.OldID = (select r2.RoleID from `' . $OldDatabase . '`.' . $OldPrefix . 'Role r2 where r2.Name = r.Name)'); // Copy non-duplicate roles Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Role (' . $RoleColumns . ', OldID) select ' . $RoleColumns . ', RoleID from `' . $OldDatabase . '`.' . $OldPrefix . 'Role where Name not in (select Name from ' . $NewPrefix . 'Role)'); // UserRole if ($this->OldTableExists('UserRole')) { Gdn::SQL()->Query('insert ignore into ' . $NewPrefix . 'UserRole (RoleID, UserID) select r.RoleID, u.UserID from ' . $NewPrefix . 'User u, ' . $NewPrefix . 'Role r, `' . $OldDatabase . '`.' . $OldPrefix . 'UserRole ur where u.OldID = (ur.UserID) and r.OldID = (ur.RoleID)'); } } // CATEGORIES // if ($this->OldTableExists('Category')) { $CategoryColumnOptions = array('Legacy' => $DoLegacy); $CategoryColumns = $this->GetColumns('Category', $OldDatabase, $OldPrefix, $CategoryColumnOptions); /*if ($this->MergeCategories) { // Merge IDs of duplicate category names Gdn::SQL()->Query('update '.$NewPrefix.'Category c set c.OldID = (select c2.CategoryID from `'.$OldDatabase.'`.'.$OldPrefix.'Category c2 where c2.Name = c.Name)'); // Copy non-duplicate categories Gdn::SQL()->Query('insert into '.$NewPrefix.'Category ('.$CategoryColumns.', OldID) select '.$CategoryColumns.', CategoryID from `'.$OldDatabase.'`.'.$OldPrefix.'Category where Name not in (select Name from '.$NewPrefix.'Category)'); } else {*/ // Import categories if ($DoLegacy) { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Category (' . $CategoryColumns . ', OldID, ForeignID) select ' . $CategoryColumns . ', CategoryID, concat(\'' . $LegacySlug . '-\', CategoryID) from `' . $OldDatabase . '`.' . $OldPrefix . 'Category where Name <> "Root"'); } else { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Category (' . $CategoryColumns . ', OldID) select ' . $CategoryColumns . ', CategoryID from `' . $OldDatabase . '`.' . $OldPrefix . 'Category where Name <> "Root"'); } // Remap hierarchy in the ugliest way possible $CategoryMap = array(); $Categories = Gdn::SQL()->Select('CategoryID')->Select('ParentCategoryID')->Select('OldID')->From('Category')->Where(array('OldID >' => 0))->Get()->Result(DATASET_TYPE_ARRAY); foreach ($Categories as $Category) { $CategoryMap[$Category['OldID']] = $Category['CategoryID']; } foreach ($Categories as $Category) { if ($Category['ParentCategoryID'] > 0 && !empty($CategoryMap[$Category['ParentCategoryID']])) { $ParentID = $CategoryMap[$Category['ParentCategoryID']]; Gdn::SQL()->Update('Category')->Set(array('ParentCategoryID' => $ParentID))->Where(array('CategoryID' => $Category['CategoryID']))->Put(); } } $CategoryModel = new CategoryModel(); $CategoryModel->RebuildTree(); //} // UserCategory } // DISCUSSIONS // if ($this->OldTableExists('Discussion')) { $DiscussionColumnOptions = array('Legacy' => $DoLegacy); $DiscussionColumns = $this->GetColumns('Discussion', $OldDatabase, $OldPrefix, $DiscussionColumnOptions); // Copy over all discussions if ($DoLegacy) { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Discussion (' . $DiscussionColumns . ', OldID, ForeignID) select ' . $DiscussionColumns . ', DiscussionID, concat(\'' . $LegacySlug . '-\', DiscussionID) from `' . $OldDatabase . '`.' . $OldPrefix . 'Discussion'); } else { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Discussion (' . $DiscussionColumns . ', OldID) select ' . $DiscussionColumns . ', DiscussionID from `' . $OldDatabase . '`.' . $OldPrefix . 'Discussion'); } // Convert imported discussions to use new UserIDs Gdn::SQL()->Query('update ' . $NewPrefix . 'Discussion d set d.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = d.InsertUserID) where d.OldID > 0'); Gdn::SQL()->Query('update ' . $NewPrefix . 'Discussion d set d.UpdateUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = d.UpdateUserID) where d.OldID > 0 and d.UpdateUserID is not null'); Gdn::SQL()->Query('update ' . $NewPrefix . 'Discussion d set d.CategoryID = (SELECT c.CategoryID from ' . $NewPrefix . 'Category c where c.OldID = d.CategoryID) where d.OldID > 0'); // UserDiscussion if ($this->OldTableExists('UserDiscussion')) { Gdn::SQL()->Query('insert ignore into ' . $NewPrefix . 'UserDiscussion (DiscussionID, UserID, Score, CountComments, DateLastViewed, Dismissed, Bookmarked) select d.DiscussionID, u.UserID, ud.Score, ud.CountComments, ud.DateLastViewed, ud.Dismissed, ud.Bookmarked from ' . $NewPrefix . 'User u, ' . $NewPrefix . 'Discussion d, `' . $OldDatabase . '`.' . $OldPrefix . 'UserDiscussion ud where u.OldID = (ud.UserID) and d.OldID = (ud.DiscussionID)'); } } // COMMENTS // if ($this->OldTableExists('Comment')) { $CommentColumnOptions = array('Legacy' => $DoLegacy); $CommentColumns = $this->GetColumns('Comment', $OldDatabase, $OldPrefix, $CommentColumnOptions); // Copy over all comments if ($DoLegacy) { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Comment (' . $CommentColumns . ', OldID, ForeignID) select ' . $CommentColumns . ', CommentID, concat(\'' . $LegacySlug . '-\', CommentID) from `' . $OldDatabase . '`.' . $OldPrefix . 'Comment'); } else { Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Comment (' . $CommentColumns . ', OldID) select ' . $CommentColumns . ', CommentID from `' . $OldDatabase . '`.' . $OldPrefix . 'Comment'); } // Convert imported comments to use new UserIDs Gdn::SQL()->Query('update ' . $NewPrefix . 'Comment c set c.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = c.InsertUserID) where c.OldID > 0'); Gdn::SQL()->Query('update ' . $NewPrefix . 'Comment c set c.UpdateUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = c.UpdateUserID) where c.OldID > 0 and c.UpdateUserID is not null'); // Convert imported comments to use new DiscussionIDs Gdn::SQL()->Query('update ' . $NewPrefix . 'Comment c set c.DiscussionID = (SELECT d.DiscussionID from ' . $NewPrefix . 'Discussion d where d.OldID = c.DiscussionID) where c.OldID > 0'); } // MEDIA // if ($this->OldTableExists('Media')) { $MediaColumns = $this->GetColumns('Media', $OldDatabase, $OldPrefix); // Copy over all media Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Media (' . $MediaColumns . ', OldID) select ' . $MediaColumns . ', MediaID from `' . $OldDatabase . '`.' . $OldPrefix . 'Media'); // InsertUserID Gdn::SQL()->Query('update ' . $NewPrefix . 'Media m set m.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = m.InsertUserID) where m.OldID > 0'); // ForeignID / ForeignTable //Gdn::SQL()->Query('update '.$NewPrefix.'Media m // set m.ForeignID = (SELECT c.CommentID from '.$NewPrefix.'Comment c where c.OldID = m.ForeignID) // where m.OldID > 0 and m.ForeignTable = \'comment\''); Gdn::SQL()->Query('update ' . $NewPrefix . 'Media m set m.ForeignID = (SELECT d.DiscussionID from ' . $NewPrefix . 'Discussion d where d.OldID = m.ForeignID) where m.OldID > 0 and m.ForeignTable = \'discussion\''); } // CONVERSATION // if ($this->OldTableExists('Conversation')) { $ConversationColumns = $this->GetColumns('Conversation', $OldDatabase, $OldPrefix); // Copy over all Conversations Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Conversation (' . $ConversationColumns . ', OldID) select ' . $ConversationColumns . ', ConversationID from `' . $OldDatabase . '`.' . $OldPrefix . 'Conversation'); // InsertUserID Gdn::SQL()->Query('update ' . $NewPrefix . 'Conversation c set c.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = c.InsertUserID) where c.OldID > 0'); // UpdateUserID Gdn::SQL()->Query('update ' . $NewPrefix . 'Conversation c set c.UpdateUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = c.UpdateUserID) where c.OldID > 0'); // Contributors // a. Build userid lookup $Users = Gdn::SQL()->Query('select UserID, OldID from ' . $NewPrefix . 'User'); $UserIDLookup = array(); foreach ($Users->Result() as $User) { $OldID = GetValue('OldID', $User); $UserIDLookup[$OldID] = GetValue('UserID', $User); } // b. Translate contributor userids $Conversations = Gdn::SQL()->Query('select ConversationID, Contributors from ' . $NewPrefix . 'Conversation where Contributors <> ""'); foreach ($Conversations->Result() as $Conversation) { $Contributors = dbdecode(GetValue('Contributors', $Conversation)); if (!is_array($Contributors)) { continue; } $UpdatedContributors = array(); foreach ($Contributors as $UserID) { if (isset($UserIDLookup[$UserID])) { $UpdatedContributors[] = $UserIDLookup[$UserID]; } } // c. Update each conversation $ConversationID = GetValue('ConversationID', $Conversation); Gdn::SQL()->Query('update ' . $NewPrefix . 'Conversation set Contributors = "' . mysql_real_escape_string(dbencode($UpdatedContributors)) . '" where ConversationID = ' . $ConversationID); } // ConversationMessage // Copy over all ConversationMessages Gdn::SQL()->Query('insert into ' . $NewPrefix . 'ConversationMessage (ConversationID,Body,Format, InsertUserID,DateInserted,InsertIPAddress,OldID) select ConversationID,Body,Format,InsertUserID,DateInserted,InsertIPAddress,MessageID from `' . $OldDatabase . '`.' . $OldPrefix . 'ConversationMessage'); // ConversationID Gdn::SQL()->Query('update ' . $NewPrefix . 'ConversationMessage cm set cm.ConversationID = (SELECT c.ConversationID from ' . $NewPrefix . 'Conversation c where c.OldID = cm.ConversationID) where cm.OldID > 0'); // InsertUserID Gdn::SQL()->Query('update ' . $NewPrefix . 'ConversationMessage c set c.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = c.InsertUserID) where c.OldID > 0'); // Conversation FirstMessageID Gdn::SQL()->Query('update ' . $NewPrefix . 'Conversation c set c.FirstMessageID = (SELECT cm.MessageID from ' . $NewPrefix . 'ConversationMessage cm where cm.OldID = c.FirstMessageID) where c.OldID > 0'); // Conversation LastMessageID Gdn::SQL()->Query('update ' . $NewPrefix . 'Conversation c set c.LastMessageID = (SELECT cm.MessageID from ' . $NewPrefix . 'ConversationMessage cm where cm.OldID = c.LastMessageID) where c.OldID > 0'); // UserConversation Gdn::SQL()->Query('insert ignore into ' . $NewPrefix . 'UserConversation (ConversationID, UserID, CountReadMessages, DateLastViewed, DateCleared, Bookmarked, Deleted, DateConversationUpdated) select c.ConversationID, u.UserID, uc.CountReadMessages, uc.DateLastViewed, uc.DateCleared, uc.Bookmarked, uc.Deleted, uc.DateConversationUpdated from ' . $NewPrefix . 'User u, ' . $NewPrefix . 'Conversation c, `' . $OldDatabase . '`.' . $OldPrefix . 'UserConversation uc where u.OldID = (uc.UserID) and c.OldID = (uc.ConversationID)'); } // POLLS // if ($this->OldTableExists('Poll')) { $PollColumns = $this->GetColumns('Poll', $OldDatabase, $OldPrefix); $PollOptionColumns = $this->GetColumns('PollOption', $OldDatabase, $OldPrefix); // Copy over all polls & options Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Poll (' . $PollColumns . ', OldID) select ' . $PollColumns . ', PollID from `' . $OldDatabase . '`.' . $OldPrefix . 'Poll'); Gdn::SQL()->Query('insert into ' . $NewPrefix . 'PollOption (' . $PollOptionColumns . ', OldID) select ' . $PollOptionColumns . ', PollOptionID from `' . $OldDatabase . '`.' . $OldPrefix . 'PollOption'); // Convert imported options to use new PollIDs Gdn::SQL()->Query('update ' . $NewPrefix . 'PollOption o set o.PollID = (SELECT p.DiscussionID from ' . $NewPrefix . 'Poll p where p.OldID = o.PollID) where o.OldID > 0'); // Convert imported polls & options to use new UserIDs Gdn::SQL()->Query('update ' . $NewPrefix . 'Poll p set p.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = p.InsertUserID) where p.OldID > 0'); Gdn::SQL()->Query('update ' . $NewPrefix . 'PollOption o set o.InsertUserID = (SELECT u.UserID from ' . $NewPrefix . 'User u where u.OldID = o.InsertUserID) where o.OldID > 0'); } // TAGS // if ($this->OldTableExists('Tag')) { $TagColumns = $this->GetColumns('Tag', $OldDatabase, $OldPrefix); $TagDiscussionColumns = $this->GetColumns('TagDiscussion', $OldDatabase, $OldPrefix); // Record reference of source forum tag ID Gdn::SQL()->Query('update ' . $NewPrefix . 'Tag t set t.OldID = (select t2.TagID from `' . $OldDatabase . '`.' . $OldPrefix . 'Tag t2 where t2.Name = t.Name limit 1)'); // Import tags not present in destination forum Gdn::SQL()->Query('insert into ' . $NewPrefix . 'Tag (' . $TagColumns . ', OldID) select ' . $TagColumns . ', TagID from `' . $OldDatabase . '`.' . $OldPrefix . 'Tag where Name not in (select Name from ' . $NewPrefix . 'Tag)'); // TagDiscussion if ($this->OldTableExists('TagDiscussion')) { // Insert source tag:discussion mapping Gdn::SQL()->Query('insert ignore into ' . $NewPrefix . 'TagDiscussion (TagID, DiscussionID, OldCategoryID) select t.TagID, d.DiscussionID, td.CategoryID from ' . $NewPrefix . 'Tag t, ' . $NewPrefix . 'Discussion d, `' . $OldDatabase . '`.' . $OldPrefix . 'TagDiscussion td where t.OldID = (td.TagID) and d.OldID = (td.DiscussionID)'); /** * Incoming tags may or may not have CategoryIDs associated with them, so we'll need to update them with a * current CategoryID, if applicable, based on the original category ID (OldCategoryID) from the source */ Gdn::SQL()->Query('update ' . $NewPrefix . 'TagDiscussion td set CategoryID = (select c.CategoryID from ' . $NewPrefix . 'Category c where c.OldID = td.OldCategoryID limit 1) where OldCategoryID > 0'); } } //// // Draft - new UserIDs // Activity - wallpost, activitycomment // Tag - new UserID, merge on name // TagDiscussion - new DiscussionID, TagID // Update counters // LastCommentID }