/** * List all update checks. * * @param bool|false $Offset * @param string $SortField */ public function index($Offset = false, $SortField = '') { $this->permission('Garden.Settings.Manage'); $this->addSideMenu('updates'); $this->addJsFile('jquery.gardenmorepager.js'); $this->title('Remote Updates'); $this->Form->Method = 'get'; $Limit = 30; $SortField = $SortField == 'CountComments' ? 'c.CountComments' : 'c.DateInserted'; // Input Validation $Offset = is_numeric($Offset) ? $Offset : 0; // What the actual model in my controller, guy? $this->UpdateData = Gdn::sql()->query("\n select s.Location, s.RemoteIp, c.DateInserted, c.CountUsers, c.CountDiscussions, c.CountComments\n from GDN_UpdateCheckSource s\n join (select SourceID, max(UpdateCheckID) as UpdateCheckID from GDN_UpdateCheck group by SourceID) mc\n on s.SourceID = mc.SourceID\n join GDN_UpdateCheck c\n on mc.UpdateCheckID = c.UpdateCheckID\n order by {$SortField} desc\n limit {$Offset}, {$Limit}"); $TotalRecords = Gdn::sql()->select('SourceID', 'count', 'CountSources')->from('UpdateCheckSource')->get()->firstRow()->CountSources; // Build a pager $PagerFactory = new Gdn_PagerFactory(); $this->Pager = $PagerFactory->getPager('MorePager', $this); $this->Pager->MoreCode = 'More'; $this->Pager->LessCode = 'Previous'; $this->Pager->ClientID = 'Pager'; $this->Pager->Wrapper = '<tr %1$s><td colspan="6">%2$s</td></tr>'; $this->Pager->configure($Offset, $Limit, $TotalRecords, 'updates/index/%1$s/' . urlencode($SortField)); // Deliver json data if necessary if ($this->_DeliveryType != DELIVERY_TYPE_ALL) { $this->setJson('LessRow', $this->Pager->toString('less')); $this->setJson('MoreRow', $this->Pager->toString('more')); } $this->render(); }
/** * * * @param $ForeignType * @param array $ForeignIDs * @return Gdn_DataSet */ public function getAll($ForeignType, $ForeignIDs = array()) { if (count($ForeignIDs) == 0) { return new Gdn_DataSet(array()); } return Gdn::sql()->select('*')->from('Regarding')->where('ForeignType', $ForeignType)->whereIn('ForeignID', $ForeignIDs)->get(); }
public function pluginController_quoteMention_create($sender, $discussionID, $commentID, $username) { $sender->deliveryMethod(DELIVERY_METHOD_JSON); $user = Gdn::userModel()->getByUsername($username); $discussionModel = new DiscussionModel(); $discussion = $discussionModel->getID($discussionID); if (!$user || !$discussion) { throw notFoundException(); } // Make sure this endpoint can't be used to snoop around. $sender->permission('Vanilla.Discussions.View', true, 'Category', $discussion->PermissionCategoryID); // Find the previous comment of the mentioned user in this discussion. $item = Gdn::sql()->getWhere('Comment', ['DiscussionID' => $discussion->DiscussionID, 'InsertUserID' => $user->UserID, 'CommentID <' => $commentID], 'CommentID', 'desc', 1)->firstRow(); // The items ID in the DOM used for highlighting. if ($item) { $target = '#Comment_' . $item->CommentID; // The mentioned user might be the discussion creator. } elseif ($discussion->InsertUserID == $user->UserID) { $item = $discussion; $target = '#Discussion_' . $item->DiscussionID; } if (!$item) { // A success response code always means that a comment was found. $sender->statusCode(404); } $sender->renderData($item ? ['html' => nl2br(sliceString(Gdn_Format::plainText($item->Body, $item->Format), c('QuoteMention.MaxLength', 400))), 'target' => $target] : []); }
public function structure() { // Get a user for operations. $UserID = Gdn::sql()->GetWhere('User', array('Name' => 'Akismet', 'Admin' => 2))->Value('UserID'); if (!$UserID) { $UserID = Gdn::sql()->Insert('User', array('Name' => 'Akismet', 'Password' => RandomString('20'), 'HashMethod' => 'Random', 'Email' => '*****@*****.**', 'DateInserted' => Gdn_Format::toDateTime(), 'Admin' => '2')); } saveToConfig('Plugins.Akismet.UserID', $UserID); }
/** * Initialize a new instance of the {@link CategoryCollection} class. * * @param Gdn_SQLDriver|null $sql The database layer dependency. * @param Gdn_Cache|null $cache The cache layer dependency. */ public function __construct(Gdn_SQLDriver $sql = null, Gdn_Cache $cache = null) { if ($sql === null) { $sql = Gdn::sql(); } $this->sql = $sql; if ($cache === null) { $cache = Gdn::cache(); } $this->cache = $cache; }
protected function getCount($Table) { // Try and get the count from the cache. $Key = "{$Table}.CountRows"; $Count = Gdn::cache()->get($Key); if ($Count !== Gdn_Cache::CACHEOP_FAILURE) { return $Count; } // The count wasn't in the cache so grab it from the table. $Count = Gdn::sql()->select($Table . 'ID', 'count', 'CountRows')->from($Table)->get()->value('CountRows'); // Save the value to the cache. Gdn::cache()->store($Key, $Count, array(Gdn_Cache::FEATURE_EXPIRY => 5 * 60 + mt_rand(0, 30))); return $Count; }
/** * Initialize a new instance of the {@link CategoryCollection} class. * * @param Gdn_SQLDriver|null $sql The database layer dependency. * @param Gdn_Cache|null $cache The cache layer dependency. */ public function __construct(Gdn_SQLDriver $sql = null, Gdn_Cache $cache = null) { if ($sql === null) { $sql = Gdn::sql(); } $this->sql = $sql; if ($cache === null) { $cache = Gdn::cache(); } $this->cache = $cache; $this->setStaticCalculator([$this, 'defaultCalculator']); $this->setUserCalculator(function (&$category) { // do nothing }); }
public function getData() { if (Gdn::session()->isValid()) { $BookmarkIDs = Gdn::sql()->select('DiscussionID')->from('UserDiscussion')->where('UserID', Gdn::session()->UserID)->where('Bookmarked', 1)->get()->resultArray(); $BookmarkIDs = consolidateArrayValuesByKey($BookmarkIDs, 'DiscussionID'); if (count($BookmarkIDs)) { $DiscussionModel = new DiscussionModel(); DiscussionModel::CategoryPermissions(); $DiscussionModel->SQL->whereIn('d.DiscussionID', $BookmarkIDs); $Bookmarks = $DiscussionModel->get(0, $this->Limit, array('w.Bookmarked' => '1')); $this->setData('Bookmarks', $Bookmarks); } else { $this->setData('Bookmarks', new Gdn_DataSet()); } } }
/** * Add new filters to the discussion model * * @param DiscussionModel $sender Sending controller instance. * @param array $args Event arguments. */ public function discussionModel_initStatic_handler($sender, $args) { DiscussionModel::addFilterSet('prefix', 'Prefixes'); DiscussionModel::addFilter('has-prefix', 'Has prefix', ['d.Prefix IS NOT NULL' => null], 'base-filter', 'prefix'); DiscussionModel::addFilter('no-prefix', 'No prefix', ['d.Prefix IS NULL' => null], 'base-filter', 'prefix'); $currentPrefixes = PrefixDiscussionPlugin::getPrefixes(); unset($currentPrefixes['-']); $usedPrefixesResult = Gdn::sql()->select('Prefix')->from('Discussion')->where('Prefix IS NOT NULL')->get()->resultArray(); foreach ($usedPrefixesResult as $row) { $prefix = $row['Prefix']; if (!isset($currentPrefixes[$prefix])) { $currentPrefixes[$prefix] = $prefix; } } natsort($currentPrefixes); foreach ($currentPrefixes as $prefix) { DiscussionModel::addFilter('prefix-' . $this->stringToSlug($prefix), $prefix, ['d.Prefix' => $prefix], 'prefix-filter', 'prefix'); } }
/** * Delete all of the Vanilla related information for a specific user. * * @since 2.1 * * @param int $userID The ID of the user to delete. * @param array $options An array of options: * - DeleteMethod: One of delete, wipe, or NULL */ public function deleteUserData($userID, $options = array(), &$data = null) { $sql = Gdn::sql(); // Remove discussion watch records and drafts. $sql->delete('UserDiscussion', array('UserID' => $userID)); Gdn::userModel()->getDelete('Draft', array('InsertUserID' => $userID), $data); // Comment deletion depends on method selected $deleteMethod = val('DeleteMethod', $options, 'delete'); if ($deleteMethod == 'delete') { // Get a list of category IDs that has this user as the most recent poster. $discussionCats = $sql->select('cat.CategoryID')->from('Category cat')->join('Discussion d', 'd.DiscussionID = cat.LastDiscussionID')->where('d.InsertUserID', $userID)->get()->resultArray(); $commentCats = $sql->select('cat.CategoryID')->from('Category cat')->join('Comment c', 'c.CommentID = cat.LastCommentID')->where('c.InsertUserID', $userID)->get()->resultArray(); $categoryIDs = array_unique(array_merge(array_column($discussionCats, 'CategoryID'), array_column($commentCats, 'CategoryID'))); // Grab all of the discussions that the user has engaged in. $discussionIDs = $sql->select('DiscussionID')->from('Comment')->where('InsertUserID', $userID)->groupBy('DiscussionID')->get()->resultArray(); $discussionIDs = array_column($discussionIDs, 'DiscussionID'); Gdn::userModel()->getDelete('Comment', array('InsertUserID' => $userID), $data); // Update the comment counts. $commentCounts = $sql->select('DiscussionID')->select('CommentID', 'count', 'CountComments')->select('CommentID', 'max', 'LastCommentID')->whereIn('DiscussionID', $discussionIDs)->groupBy('DiscussionID')->get('Comment')->resultArray(); foreach ($commentCounts as $row) { $sql->put('Discussion', array('CountComments' => $row['CountComments'] + 1, 'LastCommentID' => $row['LastCommentID']), array('DiscussionID' => $row['DiscussionID'])); } // Update the last user IDs. $sql->update('Discussion d')->join('Comment c', 'd.LastCommentID = c.CommentID', 'left')->set('d.LastCommentUserID', 'c.InsertUserID', false, false)->set('d.DateLastComment', 'coalesce(c.DateInserted, d.DateInserted)', false, false)->whereIn('d.DiscussionID', $discussionIDs)->put(); // Update the last posts. $discussions = $sql->whereIn('DiscussionID', $discussionIDs)->where('LastCommentUserID', $userID)->get('Discussion'); // Delete the user's discussions. Gdn::userModel()->getDelete('Discussion', array('InsertUserID' => $userID), $data); // Update the appropriate recent posts in the categories. $categoryModel = new CategoryModel(); foreach ($categoryIDs as $categoryID) { $categoryModel->setRecentPost($categoryID); } } elseif ($deleteMethod == 'wipe') { // Erase the user's discussions. $sql->update('Discussion')->set('Body', t('The user and all related content has been deleted.'))->set('Format', 'Deleted')->where('InsertUserID', $userID)->put(); $sql->update('Comment')->set('Body', t('The user and all related content has been deleted.'))->set('Format', 'Deleted')->where('InsertUserID', $userID)->put(); } else { // Leave comments } // Remove the user's profile information related to this application $sql->update('User')->set(array('CountDiscussions' => 0, 'CountUnreadDiscussions' => 0, 'CountComments' => 0, 'CountDrafts' => 0, 'CountBookmarks' => 0))->where('UserID', $userID)->put(); }
/** * Delete all of the Vanilla related information for a specific user. * * @since 2.1 * * @param int $UserID The ID of the user to delete. * @param array $Options An array of options: * - DeleteMethod: One of delete, wipe, or NULL */ public function deleteUserData($UserID, $Options = array(), &$Data = null) { $SQL = Gdn::sql(); // Remove discussion watch records and drafts. $SQL->delete('UserDiscussion', array('UserID' => $UserID)); Gdn::userModel()->GetDelete('Draft', array('InsertUserID' => $UserID), $Data); // Comment deletion depends on method selected $DeleteMethod = val('DeleteMethod', $Options, 'delete'); if ($DeleteMethod == 'delete') { // Clear out the last posts to the categories. $SQL->update('Category c')->join('Discussion d', 'd.DiscussionID = c.LastDiscussionID')->where('d.InsertUserID', $UserID)->set('c.LastDiscussionID', null)->set('c.LastCommentID', null)->put(); $SQL->update('Category c')->join('Comment d', 'd.CommentID = c.LastCommentID')->where('d.InsertUserID', $UserID)->set('c.LastDiscussionID', null)->set('c.LastCommentID', null)->put(); // Grab all of the discussions that the user has engaged in. $DiscussionIDs = $SQL->select('DiscussionID')->from('Comment')->where('InsertUserID', $UserID)->groupBy('DiscussionID')->get()->resultArray(); $DiscussionIDs = consolidateArrayValuesByKey($DiscussionIDs, 'DiscussionID'); Gdn::userModel()->GetDelete('Comment', array('InsertUserID' => $UserID), $Data); // Update the comment counts. $CommentCounts = $SQL->select('DiscussionID')->select('CommentID', 'count', 'CountComments')->select('CommentID', 'max', 'LastCommentID')->whereIn('DiscussionID', $DiscussionIDs)->groupBy('DiscussionID')->get('Comment')->resultArray(); foreach ($CommentCounts as $Row) { $SQL->put('Discussion', array('CountComments' => $Row['CountComments'] + 1, 'LastCommentID' => $Row['LastCommentID']), array('DiscussionID' => $Row['DiscussionID'])); } // Update the last user IDs. $SQL->update('Discussion d')->join('Comment c', 'd.LastCommentID = c.CommentID', 'left')->set('d.LastCommentUserID', 'c.InsertUserID', false, false)->set('d.DateLastComment', 'c.DateInserted', false, false)->whereIn('d.DiscussionID', $DiscussionIDs)->put(); // Update the last posts. $Discussions = $SQL->whereIn('DiscussionID', $DiscussionIDs)->where('LastCommentUserID', $UserID)->get('Discussion'); // Delete the user's dicussions Gdn::userModel()->GetDelete('Discussion', array('InsertUserID' => $UserID), $Data); // Update the appropriat recent posts in the categories. $CategoryModel = new CategoryModel(); $Categories = $CategoryModel->getWhere(array('LastDiscussionID' => null))->resultArray(); foreach ($Categories as $Category) { $CategoryModel->SetRecentPost($Category['CategoryID']); } } elseif ($DeleteMethod == 'wipe') { // Erase the user's dicussions $SQL->update('Discussion')->set('Body', t('The user and all related content has been deleted.'))->set('Format', 'Deleted')->where('InsertUserID', $UserID)->put(); $SQL->update('Comment')->set('Body', t('The user and all related content has been deleted.'))->set('Format', 'Deleted')->where('InsertUserID', $UserID)->put(); } else { // Leave comments } // Remove the user's profile information related to this application $SQL->update('User')->set(array('CountDiscussions' => 0, 'CountUnreadDiscussions' => 0, 'CountComments' => 0, 'CountDrafts' => 0, 'CountBookmarks' => 0))->where('UserID', $UserID)->put(); }
protected function getBirthdays() { $birthdays = json_decode(Gdn::get('BirthdayModule.Birthdays')); $token = date('y-m-d/H'); if ($birthdays && $birthdays[0] == $token) { return $birthdays[1]; } $date = new DateTime(); if ($guestTimeZone = C('Garden.GuestTimeZone')) { try { $timeZone = new DateTimeZone($guestTimeZone); $offset = $timeZone->getOffset(new DateTime('now', new DateTimeZone('UTC'))); $offset = -floor($offset / 3600); $date->modify("{$offset} hours"); } catch (Exception $e) { } } $birthdays = Gdn::sql()->select('UserID')->from('User')->where("DATE_FORMAT(DateOfBirth, '%m-%d')", $date->format("'m-d'"), false, false)->get()->resultArray(); $birthdays = array_column($birthdays, 'UserID'); Gdn::set('BirthdayModule.Birthdays', json_encode([$token, $birthdays])); return $birthdays; }
/** * Takes a set of discussion identifiers and returns their comment counts in the same order. */ public function getCommentCounts() { $this->AllowJSONP(true); $vanilla_identifier = val('vanilla_identifier', $_GET); if (!is_array($vanilla_identifier)) { $vanilla_identifier = array($vanilla_identifier); } $vanilla_identifier = array_unique($vanilla_identifier); $FinalData = array_fill_keys($vanilla_identifier, 0); $Misses = array(); $CacheKey = 'embed.comments.count.%s'; $OriginalIDs = array(); foreach ($vanilla_identifier as $ForeignID) { $HashedForeignID = ForeignIDHash($ForeignID); // Keep record of non-hashed identifiers for the reply $OriginalIDs[$HashedForeignID] = $ForeignID; $RealCacheKey = sprintf($CacheKey, $HashedForeignID); $Comments = Gdn::cache()->get($RealCacheKey); if ($Comments !== Gdn_Cache::CACHEOP_FAILURE) { $FinalData[$ForeignID] = $Comments; } else { $Misses[] = $HashedForeignID; } } if (sizeof($Misses)) { $CountData = Gdn::sql()->select('ForeignID, CountComments')->from('Discussion')->where('Type', 'page')->whereIn('ForeignID', $Misses)->get()->resultArray(); foreach ($CountData as $Row) { // Get original identifier to send back $ForeignID = $OriginalIDs[$Row['ForeignID']]; $FinalData[$ForeignID] = $Row['CountComments']; // Cache using the hashed identifier $RealCacheKey = sprintf($CacheKey, $Row['ForeignID']); Gdn::cache()->store($RealCacheKey, $Row['CountComments'], array(Gdn_Cache::FEATURE_EXPIRY => 60)); } } $this->setData('CountData', $FinalData); $this->DeliveryMethod = DELIVERY_METHOD_JSON; $this->DeliveryType = DELIVERY_TYPE_DATA; $this->render(); }
public static function getViewsFallback($DiscussionID) { // Not found. Check main table. $Views = val('CountViews', Gdn::sql()->select('CountViews')->from('Discussion')->where('DiscussionID', $DiscussionID)->get()->firstRow(DATASET_TYPE_ARRAY), null); // Found. Insert into denormalized table and return. if (!is_null($Views)) { return $Views; } return null; }
/** * Delete cached data for user. * * @param int|null $UserID The user to clear the cache for. * @return bool Returns **true** if the cache was cleared or **false** otherwise. */ public function clearCache($UserID, $CacheTypesToClear = null) { if (is_null($UserID) || !$UserID) { return false; } if (is_null($CacheTypesToClear)) { $CacheTypesToClear = ['user', 'roles', 'permissions']; } if (in_array('user', $CacheTypesToClear)) { $UserKey = formatString(self::USERID_KEY, ['UserID' => $UserID]); Gdn::cache()->remove($UserKey); } if (in_array('roles', $CacheTypesToClear)) { $UserRolesKey = formatString(self::USERROLES_KEY, ['UserID' => $UserID]); Gdn::cache()->remove($UserRolesKey); } if (in_array('permissions', $CacheTypesToClear)) { Gdn::sql()->put('User', ['Permissions' => ''], ['UserID' => $UserID]); $PermissionsIncrement = $this->getPermissionsIncrement(); $UserPermissionsKey = formatString(self::USERPERMISSIONS_KEY, ['UserID' => $UserID, 'PermissionsIncrement' => $PermissionsIncrement]); Gdn::cache()->remove($UserPermissionsKey); } return true; }
public function discussionModel_afterSaveDiscussion_handler($Sender) { if (c('Plugins.PostUrl.Disable', false)) { return; } if (!Gdn::session()->checkPermission('Plugins.PostUrl.Allow')) { return; } $FormPostValues = val('FormPostValues', $Sender->EventArguments, array()); $PostUrlValue = val('PostUrlValue', $FormPostValues, 0); $PostUrlValue = intval($PostUrlValue); if ($PostUrlValue == 0 || $PostUrlValue > 3) { return; } $DiscussionID = val('DiscussionID', $Sender->EventArguments, 0); $SQL = Gdn::sql(); $row = $SQL->select("*")->from("PostUrl")->where("DiscussionID", $DiscussionID)->get()->firstRow(); if (!$row) { $SQL->insert("PostUrl", array('DiscussionID' => $DiscussionID, 'PostUrlValue' => $PostUrlValue, 'DateInserted' => date('Y-m-d H:i:s'))); } else { $SQL->update("PostUrl", array("PostUrlValue" => $PostUrlValue), array("DiscussionID" => $DiscussionID))->put(); } }
/** * * * @throws Gdn_UserException */ public function setup() { // Make sure the user has curl. if (!function_exists('curl_exec')) { throw new Gdn_UserException('This plugin requires curl.'); } // Save the twitter provider type. Gdn::sql()->replace('UserAuthenticationProvider', array('AuthenticationSchemeAlias' => 'twitter', 'URL' => '...', 'AssociationSecret' => '...', 'AssociationHashMethod' => '...'), array('AuthenticationKey' => self::ProviderKey)); }
$Name = $Row['Name']; $CategoryID = $Row['CategoryID']; $TagID = $Row['TagID']; // Get the tags that need to be deleted. $DeleteTags = Gdn::sql()->getWhere('Tag', array('Name' => $Name, 'CategoryID' => $CategoryID, 'TagID <> ' => $TagID))->resultArray(); foreach ($DeleteTags as $DRow) { // Update all of the discussions to the new tag. Gdn::sql()->options('Ignore', true)->put('TagDiscussion', array('TagID' => $TagID), array('TagID' => $DRow['TagID'])); // Delete the tag. Gdn::sql()->delete('Tag', array('TagID' => $DRow['TagID'])); } } } $Construct->table('Tag')->primaryKey('TagID')->column('Name', 'varchar(100)', false, 'unique')->column('FullName', 'varchar(100)', !$FullNameColumnExists, 'index')->column('Type', 'varchar(20)', '', 'index')->column('ParentTagID', 'int', true, 'key')->column('InsertUserID', 'int', true, 'key')->column('DateInserted', 'datetime')->column('CategoryID', 'int', -1, 'unique')->Engine('InnoDB')->set($Explicit, $Drop); if (!$FullNameColumnExists) { Gdn::sql()->update('Tag')->set('FullName', 'Name', false, false)->put(); $Construct->table('Tag')->column('FullName', 'varchar(255)', false, 'index')->set(); } $Construct->table('Log')->primaryKey('LogID')->column('Operation', array('Delete', 'Edit', 'Spam', 'Moderate', 'Pending', 'Ban', 'Error'), false, 'index')->column('RecordType', array('Discussion', 'Comment', 'User', 'Registration', 'Activity', 'ActivityComment', 'Configuration', 'Group'), false, 'index')->column('TransactionLogID', 'int', null)->column('RecordID', 'int', null, 'index')->column('RecordUserID', 'int', null, 'index')->column('RecordDate', 'datetime')->column('RecordIPAddress', 'varchar(15)', null, 'index')->column('InsertUserID', 'int')->column('DateInserted', 'datetime', false, 'index')->column('InsertIPAddress', 'varchar(15)', null)->column('OtherUserIDs', 'varchar(255)', null)->column('DateUpdated', 'datetime', null)->column('ParentRecordID', 'int', null, 'index')->column('CategoryID', 'int', null, 'key')->column('Data', 'mediumtext', null)->column('CountGroup', 'int', null)->engine('InnoDB')->set($Explicit, $Drop); $Construct->table('Regarding')->primaryKey('RegardingID')->column('Type', 'varchar(100)', false, 'key')->column('InsertUserID', 'int', false)->column('DateInserted', 'datetime', false)->column('ForeignType', 'varchar(32)', false)->column('ForeignID', 'int(11)', false)->column('OriginalContent', 'text', true)->column('ParentType', 'varchar(32)', true)->column('ParentID', 'int(11)', true)->column('ForeignURL', 'varchar(255)', true)->column('Comment', 'text', false)->column('Reports', 'int(11)', true)->engine('InnoDB')->set($Explicit, $Drop); $Construct->table('Ban')->primaryKey('BanID')->column('BanType', array('IPAddress', 'Name', 'Email'), false, 'unique')->column('BanValue', 'varchar(50)', false, 'unique')->column('Notes', 'varchar(255)', null)->column('CountUsers', 'uint', 0)->column('CountBlockedRegistrations', 'uint', 0)->column('InsertUserID', 'int')->column('DateInserted', 'datetime')->column('InsertIPAddress', 'varchar(15)', true)->column('UpdateUserID', 'int', true)->column('DateUpdated', 'datetime', true)->column('UpdateIPAddress', 'varchar(15)', true)->engine('InnoDB')->set($Explicit, $Drop); $Construct->table('Spammer')->column('UserID', 'int', false, 'primary')->column('CountSpam', 'usmallint', 0)->column('CountDeletedSpam', 'usmallint', 0)->set($Explicit, $Drop); $Construct->table('Media')->primaryKey('MediaID')->column('Name', 'varchar(255)')->column('Path', 'varchar(255)')->column('Type', 'varchar(128)')->column('Size', 'int(11)')->column('InsertUserID', 'int(11)')->column('DateInserted', 'datetime')->column('ForeignID', 'int(11)', true, 'index.Foreign')->column('ForeignTable', 'varchar(24)', true, 'index.Foreign')->column('ImageWidth', 'usmallint', null)->column('ImageHeight', 'usmallint', null)->column('ThumbWidth', 'usmallint', null)->column('ThumbHeight', 'usmallint', null)->column('ThumbPath', 'varchar(255)', null)->set(false, false); // Merge backup. $Construct->table('UserMerge')->primaryKey('MergeID')->column('OldUserID', 'int', false, 'key')->column('NewUserID', 'int', false, 'key')->column('DateInserted', 'datetime')->column('InsertUserID', 'int')->column('DateUpdated', 'datetime', true)->column('UpdateUserID', 'int', true)->column('Attributes', 'text', true)->set(); $Construct->table('UserMergeItem')->column('MergeID', 'int', false, 'key')->column('Table', 'varchar(30)')->column('Column', 'varchar(30)')->column('RecordID', 'int')->column('OldUserID', 'int')->column('NewUserID', 'int')->set(); $Construct->table('Attachment')->primaryKey('AttachmentID')->column('Type', 'varchar(64)')->column('ForeignID', 'varchar(50)', false, 'index')->column('ForeignUserID', 'int', false, 'key')->column('Source', 'varchar(64)')->column('SourceID', 'varchar(32)')->column('SourceURL', 'varchar(255)')->column('Attributes', 'text', true)->column('DateInserted', 'datetime')->column('InsertUserID', 'int', false, 'key')->column('InsertIPAddress', 'varchar(64)')->column('DateUpdated', 'datetime', true)->column('UpdateUserID', 'int', true)->column('UpdateIPAddress', 'varchar(15)', true)->set($Explicit, $Drop); // Save the current input formatter to the user's config. // This will allow us to change the default later and grandfather existing forums in. saveToConfig('Garden.InputFormatter', c('Garden.InputFormatter')); // Make sure the default locale is in its canonical form.
/** * Get all messages or one message. * * @param int|bool $ID ID of message to get. * @return array|null */ public static function messages($ID = false) { if ($ID === null) { Gdn::cache()->remove('Messages'); return; } $Messages = Gdn::cache()->get('Messages'); if ($Messages === Gdn_Cache::CACHEOP_FAILURE) { $Messages = Gdn::sql()->get('Message', 'Sort')->resultArray(); $Messages = Gdn_DataSet::index($Messages, array('MessageID')); Gdn::cache()->store('Messages', $Messages); } if ($ID === false) { return $Messages; } else { return val($ID, $Messages); } }
/** * Determine if this discussion has risen from the dead. * * @param int $discussionID * @param string MySQL datetime. * @return bool */ protected function isRisen($discussionID, $revived) { $results = Gdn::sql()->select('CommentID', 'count', 'NumComments')->from('Comment')->where('DiscussionID', $discussionID)->where('DateInserted >', $revived)->get()->firstRow(); return val('NumComments', $results) >= c('Necro.CommentsToRevive', 10); }
/** * * * @param null $AddonCode * @param bool $Explicit * @param bool $Drop * @throws Exception */ public function runStructure($AddonCode = null, $Explicit = false, $Drop = false) { // Get the structure files for all of the enabled applications. $ApplicationManager = new Gdn_ApplicationManager(); $Apps = $ApplicationManager->EnabledApplications(); $AppNames = consolidateArrayValuesByKey($Apps, 'Folder'); $Paths = array(); foreach ($Apps as $Key => $AppInfo) { $Path = PATH_APPLICATIONS . "/{$AppInfo['Folder']}/settings/structure.php"; if (file_exists($Path)) { $Paths[] = $Path; } Gdn::ApplicationManager()->RegisterPermissions($Key, $this->Validation); } // Execute the structures. $Database = Gdn::database(); $SQL = Gdn::sql(); $Structure = Gdn::structure(); foreach ($Paths as $Path) { include $Path; } // Execute the structures for all of the plugins. $PluginManager = Gdn::pluginManager(); $Registered = $PluginManager->RegisteredPlugins(); foreach ($Registered as $ClassName => $Enabled) { if (!$Enabled) { continue; } try { $Plugin = $PluginManager->GetPluginInstance($ClassName, Gdn_PluginManager::ACCESS_CLASSNAME); if (method_exists($Plugin, 'Structure')) { trace("{$ClassName}->Structure()"); $Plugin->Structure(); } } catch (Exception $Ex) { // Do nothing, plugin wouldn't load/structure. if (Debug()) { throw $Ex; } } } $this->fireEvent('AfterStructure'); }
/** * Get the association for a user an a given authentication provider. * * @param string $UserKey * @param bool $ProviderKey * @param string $KeyType * @return array|bool|stdClass */ public function getAssociation($UserKey, $ProviderKey = false, $KeyType = Gdn_Authenticator::KEY_TYPE_TOKEN) { $Query = Gdn::sql()->select('ua.UserID, ua.ForeignUserKey, uat.Token')->from('UserAuthentication ua')->join('UserAuthenticationToken uat', 'ua.ForeignUserKey = uat.ForeignUserKey', 'left')->where('ua.ForeignUserKey', $UserKey)->where('UserID >', 0); if ($ProviderKey && $KeyType == Gdn_Authenticator::KEY_TYPE_TOKEN) { $Query->where('uat.Token', $ProviderKey); } if ($ProviderKey && $KeyType == Gdn_Authenticator::KEY_TYPE_PROVIDER) { $Query->where('ua.ProviderKey', $ProviderKey); } $UserAssociation = $Query->get()->firstRow(DATASET_TYPE_ARRAY); return $UserAssociation ? $UserAssociation : false; }
/** * * * @param bool $UserID * @throws Exception * @throws Gdn_UserException */ public function sso($UserID = false) { $this->permission('Garden.Users.Edit'); $ProviderModel = new Gdn_AuthenticationProviderModel(); $Form = new Gdn_Form(); if ($this->Request->isAuthenticatedPostBack()) { // Make sure everything has been posted. $Form->validateRule('ClientID', 'ValidateRequired'); $Form->validateRule('UniqueID', 'ValidateRequired'); if (!validateRequired($Form->getFormValue('Username')) && !validateRequired($Form->getFormValue('Email'))) { $Form->addError('Username or Email is required.'); } $Provider = $ProviderModel->getProviderByKey($Form->getFormValue('ClientID')); if (!$Provider) { $Form->addError(sprintf('%1$s "%2$s" not found.', t('Provider'), $Form->getFormValue('ClientID'))); } if ($Form->errorCount() > 0) { throw new Gdn_UserException($Form->errorString()); } // Grab the user. $User = false; if ($Email = $Form->getFormValue('Email')) { $User = Gdn::userModel()->GetByEmail($Email); } if (!$User && ($Username = $Form->getFormValue('Username'))) { $User = Gdn::userModel()->GetByUsername($Username); } if (!$User) { throw new Gdn_UserException(sprintf(t('User not found.'), strtolower(t(UserModel::SigninLabelCode()))), 404); } // Validate the user's password. $PasswordHash = new Gdn_PasswordHash(); $Password = $this->Form->getFormValue('Password', null); if ($Password !== null && !$PasswordHash->CheckPassword($Password, val('Password', $User), val('HashMethod', $User))) { throw new Gdn_UserException(t('Invalid password.'), 401); } // Okay. We've gotten this far. Let's save the authentication. $User = (array) $User; Gdn::userModel()->saveAuthentication(array('UserID' => $User['UserID'], 'Provider' => $Form->getFormValue('ClientID'), 'UniqueID' => $Form->getFormValue('UniqueID'))); $Row = Gdn::userModel()->getAuthentication($Form->getFormValue('UniqueID'), $Form->getFormValue('ClientID')); if ($Row) { $this->setData('Result', $Row); } else { throw new Gdn_UserException(t('There was an error saving the data.')); } } else { $User = Gdn::userModel()->getID($UserID); if (!$User) { throw notFoundException('User'); } $Result = Gdn::sql()->select('ua.ProviderKey', '', 'ClientID')->select('ua.ForeignUserKey', '', 'UniqueID')->select('ua.UserID')->select('p.Name')->select('p.AuthenticationSchemeAlias', '', 'Type')->from('UserAuthentication ua')->join('UserAuthenticationProvider p', 'ua.ProviderKey = p.AuthenticationKey')->where('UserID', $UserID)->get()->resultArray(); $this->setData('Result', $Result); } $this->render('Blank', 'Utility', 'Dashboard'); }
/** * Discussions filter: Unresolved. * * @return void */ public function discussionsController_unresolved_create($sender, $args) { $sender->permission('Plugins.Resolved.Manage'); $page = val(0, $args, 0); // Determine offset from $Page list($page, $limit) = offsetLimit($page, C('Vanilla.Discussions.PerPage', 30)); // Validate $Page if (!is_numeric($page) || $page < 0) { $page = 0; } $discussionModel = new DiscussionModel(); $wheres = array('d.Resolved' => '0'); // Hack in our wheregroup. Gdn::sql()->beginWhereGroup()->whereNotIn('d.Type', array('page', 'Report', 'poll', 'SimplePage'))->orWhere('d.Type is null')->endWhereGroup(); $sender->DiscussionData = $discussionModel->Get($page, $limit, $wheres); $sender->setData('Discussions', $sender->DiscussionData); $countDiscussions = $discussionModel->GetCount($wheres); $sender->setData('CountDiscussions', $countDiscussions); $sender->Category = false; $sender->setJson('Loading', $page . ' to ' . $limit); // Build a pager $pagerFactory = new Gdn_PagerFactory(); $sender->EventArguments['PagerType'] = 'Pager'; $sender->fireEvent('BeforeBuildBookmarkedPager'); $sender->Pager = $pagerFactory->getPager($sender->EventArguments['PagerType'], $sender); $sender->Pager->ClientID = 'Pager'; $sender->Pager->configure($page, $limit, $countDiscussions, 'discussions/unresolved/%1$s'); if (!$sender->data('_PagerUrl')) { $sender->setData('_PagerUrl', 'discussions/unresolved/{Page}'); } $sender->setData('_Page', $page); $sender->setData('_Limit', $limit); $sender->fireEvent('AfterBuildBookmarkedPager'); // Deliver JSON data if necessary if ($sender->deliveryType() != DELIVERY_TYPE_ALL) { $sender->setJson('LessRow', $sender->Pager->toString('less')); $sender->setJson('MoreRow', $sender->Pager->toString('more')); $sender->View = 'discussions'; } // Add modules $sender->addModule('DiscussionFilterModule'); $sender->addModule('NewDiscussionModule'); $sender->addModule('CategoriesModule'); // Render default view $sender->setData('Title', T('Unresolved')); $sender->setData('Breadcrumbs', array(array('Name' => T('Unresolved'), 'Url' => '/discussions/unresolved'))); $sender->render('index'); }
/** * */ public function structure() { // Save the facebook provider type. Gdn::sql()->replace('UserAuthenticationProvider', array('AuthenticationSchemeAlias' => 'facebook', 'URL' => '...', 'AssociationSecret' => '...', 'AssociationHashMethod' => '...'), array('AuthenticationKey' => self::ProviderKey), true); }
/** * * * @param $Sender * @throws Exception */ public function controller_delete($Sender) { list($Action, $MediaID) = $Sender->RequestArgs; $Sender->deliveryMethod(DELIVERY_METHOD_JSON); $Sender->deliveryType(DELIVERY_TYPE_VIEW); $Delete = array('MediaID' => $MediaID, 'Status' => 'failed'); $Media = $this->mediaModel()->getID($MediaID); $ForeignTable = val('ForeignTable', $Media); $Permission = false; // Get the category so we can figure out whether or not the user has permission to delete. if ($ForeignTable == 'discussion') { $PermissionCategoryID = Gdn::sql()->select('c.PermissionCategoryID')->from('Discussion d')->join('Category c', 'd.CategoryID = c.CategoryID')->where('d.DiscussionID', val('ForeignID', $Media))->get()->value('PermissionCategoryID'); $Permission = 'Vanilla.Discussions.Edit'; } elseif ($ForeignTable == 'comment') { $PermissionCategoryID = Gdn::sql()->select('c.PermissionCategoryID')->from('Comment cm')->join('Discussion d', 'd.DiscussionID = cm.DiscussionID')->join('Category c', 'd.CategoryID = c.CategoryID')->where('cm.CommentID', val('ForeignID', $Media))->get()->value('PermissionCategoryID'); $Permission = 'Vanilla.Comments.Edit'; } if ($Media) { $Delete['Media'] = $Media; $UserID = val('UserID', Gdn::session()); if (val('InsertUserID', $Media, null) == $UserID || Gdn::session()->checkPermission($Permission, true, 'Category', $PermissionCategoryID)) { $this->mediaModel()->delete($Media, true); $Delete['Status'] = 'success'; } else { throw PermissionException(); } } else { throw NotFoundException('Media'); } $Sender->setJSON('Delete', $Delete); $Sender->render($this->getView('blank.php')); }
/** * * * @param array $Data * @param array $Columns The columns/table information for the join. Depending on the argument's index it will be interpreted differently. * - <b>numeric</b>: This column will come be added to the resulting join. The value can be either a string or a two element array where the second element specifies an alias. * - <b>alias</b>: The alias of the child table in the query. * - <b>child</b>: The name of the child column. * - <b>column</b>: The name of the column to put the joined data into. Can't be used with <b>prefix</b>. * - <b>parent</b>: The name of the parent column. * - <b>table</b>: The name of the child table in the join. * - <b>prefix</b>: The name of the prefix to give the columns. Can't be used with <b>column</b>. * @param array $Options An array of extra options. * - <b>sql</b>: A Gdn_SQLDriver with the child query. * - <b>type</b>: The join type, either JOIN_INNER, JOIN_LEFT. This defaults to JOIN_LEFT. */ public static function join(&$Data, $Columns, $Options = array()) { $Options = array_change_key_case($Options); $Sql = Gdn::sql(); //GetValue('sql', $Options, Gdn::SQL()); $ResultColumns = array(); // Grab the columns. foreach ($Columns as $Index => $Name) { if (is_numeric($Index)) { // This is a column being selected. if (is_array($Name)) { $Column = $Name[0]; $ColumnAlias = $Name[1]; } else { $Column = $Name; $ColumnAlias = ''; } if (($Pos = strpos($Column, '.')) !== false) { $Sql->select($Column, '', $ColumnAlias); $Column = substr($Column, $Pos + 1); } else { $Sql->select(isset($TableAlias) ? $TableAlias . '.' . $Column : $Column, '', $ColumnAlias); } if ($ColumnAlias) { $ResultColumns[] = $ColumnAlias; } else { $ResultColumns[] = $Column; } } else { switch (strtolower($Index)) { case 'alias': $TableAlias = $Name; break; case 'child': $ChildColumn = $Name; break; case 'column': $JoinColumn = $Name; break; case 'parent': $ParentColumn = $Name; break; case 'prefix': $ColumnPrefix = $Name; break; case 'table': $Table = $Name; break; case 'type': // The type shouldn't be here, but handle it. $Options['Type'] = $Name; break; default: throw new Exception("Gdn_DataSet::Join(): Unknown column option '{$Index}'."); } } } if (!isset($TableAlias)) { if (isset($Table)) { $TableAlias = 'c'; } else { $TableAlias = 'c'; } } if (!isset($ParentColumn)) { if (isset($ChildColumn)) { $ParentColumn = $ChildColumn; } elseif (isset($Table)) { $ParentColumn = $Table . 'ID'; } else { throw Exception("Gdn_DataSet::Join(): Missing 'parent' argument'."); } } // Figure out some options if they weren't specified. if (!isset($ChildColumn)) { if (isset($ParentColumn)) { $ChildColumn = $ParentColumn; } elseif (isset($Table)) { $ChildColumn = $Table . 'ID'; } else { throw Exception("Gdn_DataSet::Join(): Missing 'child' argument'."); } } if (!isset($ColumnPrefix) && !isset($JoinColumn)) { $ColumnPrefix = stringEndsWith($ParentColumn, 'ID', true, true); } $JoinType = strtolower(val('Type', $Options, self::JOIN_LEFT)); // Start augmenting the sql for the join. if (isset($Table)) { $Sql->from("{$Table} {$TableAlias}"); } $Sql->select("{$TableAlias}.{$ChildColumn}"); // Get the IDs to generate an in clause with. $IDs = array(); foreach ($Data as $Row) { $Value = val($ParentColumn, $Row); if ($Value) { $IDs[$Value] = true; } } $IDs = array_keys($IDs); $Sql->whereIn($ChildColumn, $IDs); $ChildData = $Sql->get()->resultArray(); $ChildData = self::index($ChildData, $ChildColumn, array('unique' => GetValue('unique', $Options, isset($ColumnPrefix)))); $NotFound = array(); // Join the data in. foreach ($Data as $Index => &$Row) { $ParentID = val($ParentColumn, $Row); if (isset($ChildData[$ParentID])) { $ChildRow = $ChildData[$ParentID]; if (isset($ColumnPrefix)) { // Add the data to the columns. foreach ($ChildRow as $Name => $Value) { setValue($ColumnPrefix . $Name, $Row, $Value); } } else { // Add the result data. setValue($JoinColumn, $Row, $ChildRow); } } else { if ($JoinType == self::JOIN_LEFT) { if (isset($ColumnPrefix)) { foreach ($ResultColumns as $Name) { setValue($ColumnPrefix . $Name, $Row, null); } } else { setValue($JoinColumn, $Row, array()); } } else { $NotFound[] = $Index; } } } // Remove inner join rows. if ($JoinType == self::JOIN_INNER) { foreach ($NotFound as $Index) { unset($Data[$Index]); } } }
/** * * * @since 2.0.0 * @access public * @param array $Data * @param string $Permission * @param string $Column */ public static function joinModerators($Data, $Permission = 'Vanilla.Comments.Edit', $Column = 'Moderators') { $Moderators = Gdn::sql()->select('u.UserID, u.Name, u.Photo, u.Email')->select('p.JunctionID as CategoryID')->from('User u')->join('UserRole ur', 'ur.UserID = u.UserID')->join('Permission p', 'ur.RoleID = p.RoleID')->where('`' . $Permission . '`', 1)->get()->resultArray(); $Moderators = Gdn_DataSet::Index($Moderators, 'CategoryID', array('Unique' => false)); foreach ($Data as &$Category) { $ID = val('PermissionCategoryID', $Category); $Mods = val($ID, $Moderators, array()); $ModIDs = array(); $UniqueMods = array(); foreach ($Mods as $Mod) { if (!in_array($Mod['UserID'], $ModIDs)) { $ModIDs[] = $Mod['UserID']; $UniqueMods[] = $Mod; } } setValue($Column, $Category, $UniqueMods); } }
/** * Hark, a model kludged into a controller! * * @param string $mDay * @return array */ private function _getStats($mDay = '') { $AssumeToday = $mDay == ''; if ($AssumeToday) { $mDay = date("Y-m-d 00:00:00"); } // Get Vanilla Download Count Gdn::sql()->select('AddonID', 'count', 'Count')->from('Download')->where('AddonID', 465); // <---- Vanilla 1's AddonID if (!$AssumeToday) { Gdn::sql()->where('DateInserted <=', $mDay); } $OrgData = Gdn::sql()->get(); $VanillaDownloads = $OrgData->numRows() > 0 ? $OrgData->firstRow()->Count : 0; $VanillaDownloads += 311528; // There were 311,528 Vanilla downloads before moving to this new database // There were 1,171,794 plugin downloads when we started recording plugin downloads in LUM_Download Gdn::sql()->select('d.DownloadID', 'count', 'Count')->from('Download d')->join('Addon a', 'a.AddonID = d.AddonID')->join('AddonType t', 'a.AddonTypeID = t.AddonTypeID')->where('a.AddonID <>', 465); // Don't include Vanilla downloads in addon downloads. // ->Where('t.Label <>', 'Application'); if (!$AssumeToday) { Gdn::sql()->where('d.DateInserted <=', $mDay); } $OrgData = Gdn::sql()->get(); $AddonDownloads = $OrgData->numRows() > 0 ? $OrgData->firstRow()->Count : 0; $AddonDownloads += 1232885; // This was the count when we migrated to garden $mDay = substr($mDay, 0, 10) . ' 00:00:00'; return array('DateInserted' => $mDay, 'VanillaDownloads' => $VanillaDownloads, 'AddonDownloads' => $AddonDownloads); }
/** * * * @return bool */ public function updateCounts() { // This option could take a while so set the timeout. set_time_limit(60 * 5); // Define the necessary SQL. $Sqls = array(); if (!$this->importExists('Discussion', 'LastCommentID')) { $Sqls['Discussion.LastCommentID'] = $this->GetCountSQL('max', 'Discussion', 'Comment'); } if (!$this->importExists('Discussion', 'DateLastComment')) { $Sqls['Discussion.DateLastComment'] = "update :_Discussion d\n left join :_Comment c\n on d.LastCommentID = c.CommentID\n set d.DateLastComment = coalesce(c.DateInserted, d.DateInserted)"; } if (!$this->importExists('Discussion', 'LastCommentUserID')) { $Sqls['Discussion.LastCommentUseID'] = "update :_Discussion d\n join :_Comment c\n on d.LastCommentID = c.CommentID\n set d.LastCommentUserID = c.InsertUserID"; } if (!$this->importExists('Discussion', 'Body')) { // Update the body of the discussion if it isn't there. if (!$this->importExists('Discussion', 'FirstCommentID')) { $Sqls['Discussion.FirstCommentID'] = $this->GetCountSQL('min', 'Discussion', 'Comment', 'FirstCommentID', 'CommentID'); } $Sqls['Discussion.Body'] = "update :_Discussion d\n join :_Comment c\n on d.FirstCommentID = c.CommentID\n set d.Body = c.Body, d.Format = c.Format"; if ($this->importExists('Media') && Gdn::structure()->TableExists('Media')) { // Comment Media has to go onto the discussion. $Sqls['Media.Foreign'] = "update :_Media m\n join :_Discussion d\n on d.FirstCommentID = m.ForeignID and m.ForeignTable = 'comment'\n set m.ForeignID = d.DiscussionID, m.ForeignTable = 'discussion'"; } $Sqls['Comment.FirstComment.Delete'] = "delete c.*\n from :_Comment c\n inner join :_Discussion d\n on d.FirstCommentID = c.CommentID"; } if (!$this->importExists('Discussion', 'CountComments')) { $Sqls['Discussion.CountComments'] = $this->GetCountSQL('count', 'Discussion', 'Comment'); } if ($this->importExists('UserDiscussion') && !$this->importExists('UserDiscussion', 'CountComments') && $this->importExists('UserDiscussion', 'DateLastViewed')) { $Sqls['UserDiscussuion.CountComments'] = "update :_UserDiscussion ud\n set CountComments = (\n select count(c.CommentID)\n from :_Comment c\n where c.DiscussionID = ud.DiscussionID\n and c.DateInserted <= ud.DateLastViewed)"; } if ($this->importExists('Tag') && $this->importExists('TagDiscussion')) { $Sqls['Tag.CoundDiscussions'] = $this->GetCountSQL('count', 'Tag', 'TagDiscussion', 'CountDiscussions', 'TagID'); } if ($this->importExists('Poll') && Gdn::structure()->TableExists('Poll')) { $Sqls['PollOption.CountVotes'] = $this->GetCountSQL('count', 'PollOption', 'PollVote', 'CountVotes', 'PollOptionID'); $Sqls['Poll.CountOptions'] = $this->GetCountSQL('count', 'Poll', 'PollOption', 'CountOptions', 'PollID'); $Sqls['Poll.CountVotes'] = $this->GetCountSQL('sum', 'Poll', 'PollOption', 'CountVotes', 'CountVotes', 'PollID'); } if ($this->importExists('Activity', 'ActivityType')) { $Sqls['Activity.ActivityTypeID'] = "\n update :_Activity a\n join :_ActivityType t\n on a.ActivityType = t.Name\n set a.ActivityTypeID = t.ActivityTypeID"; } if ($this->importExists('Tag') && $this->importExists('TagDiscussion')) { $Sqls['Tag.CoundDiscussions'] = $this->GetCountSQL('count', 'Tag', 'TagDiscussion', 'CountDiscussions', 'TagID'); } $Sqls['Category.CountDiscussions'] = $this->GetCountSQL('count', 'Category', 'Discussion'); $Sqls['Category.CountComments'] = $this->GetCountSQL('sum', 'Category', 'Discussion', 'CountComments', 'CountComments'); if (!$this->importExists('Category', 'PermissionCategoryID')) { $Sqls['Category.PermissionCategoryID'] = "update :_Category set PermissionCategoryID = -1"; } if ($this->importExists('Conversation') && $this->importExists('ConversationMessage')) { $Sqls['Conversation.FirstMessageID'] = $this->GetCountSQL('min', 'Conversation', 'ConversationMessage', 'FirstMessageID', 'MessageID'); if (!$this->importExists('Conversation', 'CountMessages')) { $Sqls['Conversation.CountMessages'] = $this->GetCountSQL('count', 'Conversation', 'ConversationMessage', 'CountMessages', 'MessageID'); } if (!$this->importExists('Conversation', 'LastMessageID')) { $Sqls['Conversation.LastMessageID'] = $this->GetCountSQL('max', 'Conversation', 'ConversationMessage', 'LastMessageID', 'MessageID'); } if (!$this->importExists('Conversation', 'DateUpdated')) { $Sqls['Converstation.DateUpdated'] = "update :_Conversation c join :_ConversationMessage m on c.LastMessageID = m.MessageID set c.DateUpdated = m.DateInserted"; } if ($this->importExists('UserConversation')) { if (!$this->importExists('UserConversation', 'LastMessageID')) { if ($this->importExists('UserConversation', 'DateLastViewed')) { // Get the value from the DateLastViewed. $Sqls['UserConversation.LastMessageID'] = "update :_UserConversation uc\n set LastMessageID = (\n select max(MessageID)\n from :_ConversationMessage m\n where m.ConversationID = uc.ConversationID\n and m.DateInserted >= uc.DateLastViewed)"; } else { // Get the value from the conversation. // In this case just mark all of the messages read. $Sqls['UserConversation.LastMessageID'] = "update :_UserConversation uc\n join :_Conversation c\n on c.ConversationID = uc.ConversationID\n set uc.CountReadMessages = c.CountMessages,\n uc.LastMessageID = c.LastMessageID"; } } elseif (!$this->importExists('UserConversation', 'DateLastViewed')) { // We have the last message so grab the date from that. $Sqls['UserConversation.DateLastViewed'] = "update :_UserConversation uc\n join :_ConversationMessage m\n on m.ConversationID = uc.ConversationID\n and m.MessageID = uc.LastMessageID\n set uc.DateLastViewed = m.DateInserted"; } } } // User counts. if (!$this->importExists('User', 'DateFirstVisit')) { $Sqls['User.DateFirstVisit'] = 'update :_User set DateFirstVisit = DateInserted'; } if (!$this->importExists('User', 'CountDiscussions')) { $Sqls['User.CountDiscussions'] = $this->GetCountSQL('count', 'User', 'Discussion', 'CountDiscussions', 'DiscussionID', 'UserID', 'InsertUserID'); } if (!$this->importExists('User', 'CountComments')) { $Sqls['User.CountComments'] = $this->GetCountSQL('count', 'User', 'Comment', 'CountComments', 'CommentID', 'UserID', 'InsertUserID'); } if (!$this->importExists('User', 'CountBookmarks')) { $Sqls['User.CountBookmarks'] = "update :_User u\n set CountBookmarks = (\n select count(ud.DiscussionID)\n from :_UserDiscussion ud\n where ud.Bookmarked = 1\n and ud.UserID = u.UserID\n )"; } // if (!$this->importExists('User', 'CountUnreadConversations')) { // $Sqls['User.CountUnreadConversations'] = // 'update :_User u // set u.CountUnreadConversations = ( // select count(c.ConversationID) // from :_Conversation c // inner join :_UserConversation uc // on c.ConversationID = uc.ConversationID // where uc.UserID = u.UserID // and uc.CountReadMessages < c.CountMessages // )'; // } // The updates start here. $CurrentSubstep = val('CurrentSubstep', $this->Data, 0); // $Sqls2 = array(); // $i = 1; // foreach ($Sqls as $Name => $Sql) { // $Sqls2[] = "/* $i. $Name */\n" // .str_replace(':_', $this->Database->DatabasePrefix, $Sql) // .";\n"; // $i++; // } // throw new Exception(implode("\n", $Sqls2)); // Execute the SQL. $Keys = array_keys($Sqls); for ($i = $CurrentSubstep; $i < count($Keys); $i++) { $this->Data['CurrentStepMessage'] = sprintf(t('%s of %s'), $CurrentSubstep + 1, count($Keys)); $Sql = $Sqls[$Keys[$i]]; $this->query($Sql); if ($this->Timer->ElapsedTime() > $this->MaxStepTime) { $this->Data['CurrentSubstep'] = $i + 1; return false; } } if (isset($this->Data['CurrentSubstep'])) { unset($this->Data['CurrentSubstep']); } $this->Data['CurrentStepMessage'] = ''; // Update the url codes of categories. if (!$this->importExists('Category', 'UrlCode')) { $Categories = CategoryModel::categories(); $TakenCodes = array(); foreach ($Categories as $Category) { $UrlCode = urldecode(Gdn_Format::url($Category['Name'])); if (strlen($UrlCode) > 50) { $UrlCode = 'c' . $Category['CategoryID']; } elseif (is_numeric($UrlCode)) { $UrlCode = 'c' . $UrlCode; } if (in_array($UrlCode, $TakenCodes)) { $ParentCategory = CategoryModel::categories($Category['ParentCategoryID']); if ($ParentCategory && $ParentCategory['CategoryID'] != -1) { $UrlCode = Gdn_Format::url($ParentCategory['Name']) . '-' . $UrlCode; } if (in_array($UrlCode, $TakenCodes)) { $UrlCode = $Category['CategoryID']; } } $TakenCodes[] = $UrlCode; Gdn::sql()->put('Category', array('UrlCode' => $UrlCode), array('CategoryID' => $Category['CategoryID'])); } } // Rebuild the category tree. $CategoryModel = new CategoryModel(); $CategoryModel->RebuildTree(); $this->SetCategoryPermissionIDs(); return true; }