Example #1
0
/**
 * Return a formatted string
 * @link http://www.php.net/manual/en/function.sprintf.php
 * @param format string <p>
 * The format string is composed of zero or more directives:
 * ordinary characters (excluding %) that are
 * copied directly to the result, and conversion
 * specifications, each of which results in fetching its
 * own parameter. This applies to both sprintf
 * and printf.
 * </p>
 * <p>
 * Each conversion specification consists of a percent sign
 * (%), followed by one or more of these
 * elements, in order:
 * An optional sign specifier that forces a sign
 * (- or +) to be used on a number. By default, only the - sign is used
 * on a number if it's negative. This specifier forces positive numbers
 * to have the + sign attached as well, and was added in PHP 4.3.0.
 * @param args mixed[optional] <p>
 * </p>
 * @param _ mixed[optional]
 * @return string a string produced according to the formatting string
 * format.
 */
function dbsprintf($format, $args = null, $_ = null)
{
    $varArray = func_get_args();
    $count = count($varArray);
    if ($count > 1) {
        $v = $varArray[$count - 1];
        if ($v === true) {
            $varArray = array_slice($varArray, 0, $count - 1);
            return call_user_func_array('sprintf', $varArray);
        } else {
            if ($v === false) {
                $varArray = array_slice($varArray, 0, $count - 1);
                $count--;
            }
        }
        for ($index = 1; $index < $count; $index++) {
            $patterns = array('/\\r/', '/\\n/', '/\\x00/', '/\\x1a/');
            $var = preg_replace($patterns, '', $varArray[$index]);
            if ($var === false) {
                $var = 0;
            }
            $varArray[$index] = dbencode($var);
        }
        return call_user_func_array('sprintf', $varArray);
    } else {
        return $format;
    }
}
Example #2
0
 /**
  * Set a property on a category.
  *
  * @param int $ID
  * @param array|string $Property
  * @param bool|false $Value
  * @return array|string
  */
 public function setField($ID, $Property, $Value = false)
 {
     if (!is_array($Property)) {
         $Property = array($Property => $Value);
     }
     if (isset($Property['AllowedDiscussionTypes']) && is_array($Property['AllowedDiscussionTypes'])) {
         $Property['AllowedDiscussionTypes'] = dbencode($Property['AllowedDiscussionTypes']);
     }
     $this->SQL->put($this->Name, $Property, array('CategoryID' => $ID));
     // Set the cache.
     self::setCache($ID, $Property);
     return $Property;
 }
 /**
  *
  *
  * @param array $Data
  * @param bool $Settings
  * @return bool
  */
 public function save($Data, $Settings = false)
 {
     // Grab the current record.
     $Row = false;
     if ($id = val('ID', $Settings)) {
         $Row = $this->getWhere(array($this->PrimaryKey => $id))->firstRow(DATASET_TYPE_ARRAY);
     } elseif (isset($Data[$this->PrimaryKey])) {
         $Row = $this->getWhere(array($this->PrimaryKey => $Data[$this->PrimaryKey]))->firstRow(DATASET_TYPE_ARRAY);
     } elseif ($PK = val('PK', $Settings)) {
         $Row = $this->getWhere(array($PK => $Data[$PK]))->firstRow(DATASET_TYPE_ARRAY);
     }
     // Get the columns and put the extended data in the attributes.
     $this->defineSchema();
     $Columns = $this->Schema->fields();
     $Remove = array('TransientKey' => 1, 'hpt' => 1, 'Save' => 1, 'Checkboxes' => 1);
     $Data = array_diff_key($Data, $Remove);
     $Attributes = array_diff_key($Data, $Columns);
     if (!empty($Attributes)) {
         $Data = array_diff_key($Data, $Attributes);
         $Data['Attributes'] = dbencode($Attributes);
     }
     $Insert = !$Row;
     if ($Insert) {
         $this->addInsertFields($Data);
     } else {
         $this->addUpdateFields($Data);
     }
     // Validate the form posted values
     if ($this->validate($Data, $Insert) === true) {
         // Clear the default from other authentication providers.
         $Default = val('IsDefault', $Data);
         if ($Default) {
             $this->SQL->put($this->Name, array('IsDefault' => 0), array('AuthenticationKey <>' => val('AuthenticationKey', $Data)));
         }
         $Fields = $this->Validation->validationFields();
         if ($Insert === false) {
             $PrimaryKeyVal = $Row[$this->PrimaryKey];
             $this->update($Fields, array($this->PrimaryKey => $PrimaryKeyVal));
         } else {
             $PrimaryKeyVal = $this->insert($Fields);
         }
     } else {
         $PrimaryKeyVal = false;
     }
     return $PrimaryKeyVal;
 }
Example #4
0
 /**
  * Check an addon's file to extract the addon information out of it.
  *
  * @param string $Path The path to the file.
  * @param bool $ThrowError Whether or not to throw an exception if there is a problem analyzing the addon.
  * @return array An array of addon information.
  */
 public static function analyzeAddon($Path, $ThrowError = true)
 {
     if (!file_exists($Path)) {
         if ($ThrowError) {
             throw new Exception("{$Path} not found.", 404);
         }
         return false;
     }
     $Addon = [];
     $Result = [];
     $InfoPaths = array('/settings/about.php', '/default.php', '/class.*.plugin.php', '/about.php', '/definitions.php', '/index.php', 'vanilla2export.php');
     // Get the list of potential files to analyze.
     if (is_dir($Path)) {
         $Entries = self::getInfoFiles($Path, $InfoPaths);
         $DeleteEntries = false;
     } else {
         $Entries = self::getInfoZip($Path, $InfoPaths, false, $ThrowError);
         $DeleteEntries = true;
     }
     foreach ($Entries as $Entry) {
         if ($Entry['Name'] == '/index.php') {
             // This could be the core vanilla package.
             $Version = self::parseCoreVersion($Entry['Path']);
             if (!$Version) {
                 continue;
             }
             // The application was confirmed.
             $Addon = array('AddonKey' => 'vanilla', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla', 'Description' => 'Vanilla is an open-source, standards-compliant, multi-lingual, fully extensible discussion forum for the web. Anyone who has web-space that meets the requirements can download and use Vanilla for free!', 'Version' => $Version, 'License' => 'GPLv2', 'Path' => $Entry['Path']);
             break;
         } elseif ($Entry['Name'] == 'vanilla2export.php') {
             // This could be the vanilla porter.
             $Version = self::parseCoreVersion($Entry['Path']);
             if (!$Version) {
                 continue;
             }
             $Addon = array('AddonKey' => 'porter', 'AddonTypeID' => ADDON_TYPE_CORE, 'Name' => 'Vanilla Porter', 'Description' => 'Drop this script in your existing site and navigate to it in your web browser to export your existing forum data to the Vanilla 2 import format.', 'Version' => $Version, 'License' => 'GPLv2', 'Path' => $Entry['Path']);
             break;
         } else {
             // This could be an addon.
             $Info = self::parseInfoArray($Entry['Path']);
             if (!is_array($Info) && count($Info)) {
                 continue;
             }
             $Key = key($Info);
             $Variable = $Info['Variable'];
             $Info = $Info[$Key];
             // Validate the addon.
             $Name = $Entry['Name'];
             $Valid = true;
             if (!val('Name', $Info)) {
                 $Info['Name'] = $Key;
             }
             // Validate basic fields.
             $checkResult = self::checkRequiredFields($Info);
             if (count($checkResult)) {
                 $Result = array_merge($Result, $checkResult);
                 $Valid = false;
             }
             // Validate folder name matches key.
             if (isset($Entry['Base']) && strcasecmp($Entry['Base'], $Key) != 0 && $Variable != 'ThemeInfo') {
                 $Result[] = "{$Name}: The addon's key is not the same as its folder name.";
                 $Valid = false;
             }
             if (!$Valid) {
                 continue;
             }
             // The addon is valid.
             $Addon = array_merge(array('AddonKey' => $Key, 'AddonTypeID' => ''), $Info);
             switch ($Variable) {
                 case 'ApplicationInfo':
                     $Addon['AddonTypeID'] = ADDON_TYPE_APPLICATION;
                     break;
                 case 'LocaleInfo':
                     $Addon['AddonTypeID'] = ADDON_TYPE_LOCALE;
                     break;
                 case 'PluginInfo':
                     $Addon['AddonTypeID'] = ADDON_TYPE_PLUGIN;
                     break;
                 case 'ThemeInfo':
                     $Addon['AddonTypeID'] = ADDON_TYPE_THEME;
                     break;
             }
         }
     }
     if ($DeleteEntries) {
         $FolderPath = substr($Path, 0, -4);
         Gdn_FileSystem::removeFolder($FolderPath);
     }
     // Add the addon requirements.
     if (!empty($Addon)) {
         $Requirements = arrayTranslate($Addon, ['RequiredApplications' => 'Applications', 'RequiredPlugins' => 'Plugins', 'RequiredThemes' => 'Themes']);
         foreach ($Requirements as $Type => $Items) {
             if (!is_array($Items)) {
                 unset($Requirements[$Type]);
             }
         }
         $Addon['Requirements'] = dbencode($Requirements);
         $Addon['Checked'] = true;
         $Addon['Path'] = $Path;
         $UploadsPath = PATH_UPLOADS . '/';
         if (stringBeginsWith($Addon['Path'], $UploadsPath)) {
             $Addon['File'] = substr($Addon['Path'], strlen($UploadsPath));
         }
         if (is_file($Path)) {
             $Addon['MD5'] = md5_file($Path);
             $Addon['FileSize'] = filesize($Path);
         }
     } elseif ($ThrowError) {
         $Msg = implode("\n", $Result);
         throw new Gdn_UserException($Msg, 400);
     } else {
         return false;
     }
     return $Addon;
 }
Example #5
0
 /**
  *
  *
  * @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();
 }
Example #6
0
 /**
  * @param PostController $Sender
  * @param array $Args
  * @return mixed
  */
 public function PostController_Comment_Create($Sender, $Args = array())
 {
     if ($Sender->Form->AuthenticatedPostBack()) {
         $Sender->Form->SetModel($Sender->CommentModel);
         // Grab the discussion for use later.
         $DiscussionID = $Sender->Form->GetFormValue('DiscussionID');
         $DiscussionModel = new DiscussionModel();
         $Discussion = $DiscussionModel->GetID($DiscussionID);
         // Check to see if the discussion is supposed to be in private...
         $WhisperConversationID = GetValueR('Attributes.WhisperConversationID', $Discussion);
         if ($WhisperConversationID === TRUE) {
             // There isn't a conversation so we want to create one.
             $Sender->Form->SetFormValue('Whisper', TRUE);
             $WhisperUserIDs = GetValueR('Attributes.WhisperUserIDs', $Discussion);
             $Sender->Form->SetFormValue('RecipientUserID', $WhisperUserIDs);
         } elseif ($WhisperConversationID) {
             // There is already a conversation.
             $Sender->Form->SetFormValue('Whisper', TRUE);
             $Sender->Form->SetFormValue('ConversationID', $WhisperConversationID);
         }
         $Whisper = $Sender->Form->GetFormValue('Whisper') && GetIncomingValue('Type') != 'Draft';
         $WhisperTo = trim($Sender->Form->GetFormValue('To'));
         $ConversationID = $Sender->Form->GetFormValue('ConversationID');
         // If this isn't a whisper then post as normal.
         if (!$Whisper) {
             return call_user_func_array(array($Sender, 'Comment'), $Args);
         }
         $ConversationModel = new ConversationModel();
         $ConversationMessageModel = new ConversationMessageModel();
         if ($ConversationID > 0) {
             $Sender->Form->SetModel($ConversationMessageModel);
         } else {
             // We have to remove the blank conversation ID or else the model won't validate.
             $FormValues = $Sender->Form->FormValues();
             unset($FormValues['ConversationID']);
             $FormValues['Subject'] = GetValue('Name', $Discussion);
             $Sender->Form->FormValues($FormValues);
             $Sender->Form->SetModel($ConversationModel);
             $ConversationModel->Validation->ApplyRule('DiscussionID', 'Required');
         }
         $ID = $Sender->Form->Save($ConversationMessageModel);
         if ($Sender->Form->ErrorCount() > 0) {
             $Sender->ErrorMessage($Sender->Form->Errors());
         } else {
             if ($WhisperConversationID === TRUE) {
                 $Discussion->Attributes['WhisperConversationID'] = $ID;
                 $DiscussionModel->SetProperty($DiscussionID, 'Attributes', dbencode($Discussion->Attributes));
             }
             $LastCommentID = GetValue('LastCommentID', $Discussion);
             $MessageID = GetValue('LastMessageID', $ConversationMessageModel, FALSE);
             // Randomize the querystring to force the browser to refresh.
             $Rand = mt_rand(10000, 99999);
             if ($LastCommentID) {
                 // Link to the last comment.
                 $HashID = $MessageID ? 'w' . $MessageID : $LastCommentID;
                 $Sender->RedirectUrl = Url("discussion/comment/{$LastCommentID}?rand={$Rand}#Comment_{$HashID}", TRUE);
             } else {
                 // Link to the discussion.
                 $Hash = $MessageID ? "Comment_w{$MessageID}" : 'Item_1';
                 $Name = rawurlencode(GetValue('Name', $Discussion, 'x'));
                 $Sender->RedirectUrl = Url("discussion/{$DiscussionID}/{$Name}?rand={$Rand}#{$Hash}", TRUE);
             }
         }
         $Sender->Render();
     } else {
         return call_user_func_array(array($Sender, 'Comment'), $Args);
     }
 }
 /**
  * Create secure handshake with remote authenticator.
  *
  * @access public
  * @since 2.0.?
  * @author Tim Gunter
  *
  * @param string $AuthenticationSchemeAlias (default: 'default')
  */
 public function handshake($AuthenticationSchemeAlias = 'default')
 {
     try {
         // Don't show anything if handshaking not turned on by an authenticator
         if (!Gdn::authenticator()->canHandshake()) {
             throw new Exception();
         }
         // Try to load the authenticator
         $Authenticator = Gdn::authenticator()->authenticateWith($AuthenticationSchemeAlias);
         // Try to grab the authenticator data
         $Payload = $Authenticator->getHandshake();
         if ($Payload === false) {
             Gdn::request()->withURI('dashboard/entry/auth/password');
             return Gdn::dispatcher()->dispatch();
         }
     } catch (Exception $e) {
         Gdn::request()->WithURI('/entry/signin');
         return Gdn::dispatcher()->dispatch();
     }
     $UserInfo = array('UserKey' => $Authenticator->GetUserKeyFromHandshake($Payload), 'ConsumerKey' => $Authenticator->GetProviderKeyFromHandshake($Payload), 'TokenKey' => $Authenticator->GetTokenKeyFromHandshake($Payload), 'UserName' => $Authenticator->GetUserNameFromHandshake($Payload), 'UserEmail' => $Authenticator->GetUserEmailFromHandshake($Payload));
     if (method_exists($Authenticator, 'GetRolesFromHandshake')) {
         $RemoteRoles = $Authenticator->GetRolesFromHandshake($Payload);
         if (!empty($RemoteRoles)) {
             $UserInfo['Roles'] = $RemoteRoles;
         }
     }
     // Manual user sync is disabled. No hand holding will occur for users.
     $SyncScreen = c('Garden.Authenticator.SyncScreen', 'on');
     switch ($SyncScreen) {
         case 'on':
             // Authenticator events fired inside
             $this->syncScreen($Authenticator, $UserInfo, $Payload);
             break;
         case 'off':
         case 'smart':
             $UserID = $this->UserModel->synchronize($UserInfo['UserKey'], array('Name' => $UserInfo['UserName'], 'Email' => $UserInfo['UserEmail'], 'Roles' => val('Roles', $UserInfo)));
             if ($UserID > 0) {
                 // Account created successfully.
                 // Finalize the link between the forum user and the foreign userkey
                 $Authenticator->finalize($UserInfo['UserKey'], $UserID, $UserInfo['ConsumerKey'], $UserInfo['TokenKey'], $Payload);
                 $UserEventData = array_merge(array('UserID' => $UserID, 'Payload' => $Payload), $UserInfo);
                 Gdn::authenticator()->trigger(Gdn_Authenticator::AUTH_CREATED, $UserEventData);
                 /// ... and redirect them appropriately
                 $Route = $this->redirectTo();
                 if ($Route !== false) {
                     redirect($Route);
                 } else {
                     redirect('/');
                 }
             } else {
                 // Account not created.
                 if ($SyncScreen == 'smart') {
                     $this->informMessage(t('There is already an account in this forum using your email address. Please create a new account, or enter the credentials for the existing account.'));
                     $this->syncScreen($Authenticator, $UserInfo, $Payload);
                 } else {
                     // Set the memory cookie to allow signinloopback to shortcircuit remote query.
                     $CookiePayload = array('Sync' => 'Failed');
                     $encodedCookiePayload = dbencode($CookiePayload);
                     $Authenticator->remember($UserInfo['ConsumerKey'], $encodedCookiePayload);
                     // This resets vanilla's internal "where am I" to the homepage. Needed.
                     Gdn::request()->withRoute('DefaultController');
                     $this->SelfUrl = url('');
                     //Gdn::request()->Path();
                     $this->View = 'syncfailed';
                     $this->ProviderSite = $Authenticator->getProviderUrl();
                     $this->render();
                 }
             }
             break;
     }
 }
 /**
  * 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
 }
Example #9
0
 /**
  *
  *
  * @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;
 }
Example #10
0
File: stub.php Project: R-J/vanilla
<?php

if (!defined('APPLICATION')) {
    exit;
}
/**
 * Conversations stub content for a new site.
 *
 * Called by ConversationsHooks::Setup() to insert stub content upon enabling app.
 *
 * @copyright 2009-2016 Vanilla Forums Inc.
 * @license http://www.opensource.org/licenses/gpl-2.0.php GNU GPL v2
 * @package Conversations
 * @since 2.2
 */
// Only do this once, ever.
if (!$Drop) {
    return;
}
$SQL = Gdn::database()->sql();
// Prep default content
$ConversationBody = "Pssst. Hey. A conversation is a private chat between two or more members. No one can see it except the members added. You can delete this one since I&rsquo;m just a bot and know better than to talk back.";
$SystemUserID = Gdn::userModel()->getSystemUserID();
$TargetUserID = Gdn::session()->UserID;
$Now = Gdn_Format::toDateTime();
$Contributors = dbencode(array($SystemUserID, $TargetUserID));
// Insert stub conversation
$ConversationID = $SQL->insert('Conversation', array('InsertUserID' => $SystemUserID, 'DateInserted' => $Now, 'Contributors' => $Contributors, 'CountMessages' => 1));
$MessageID = $SQL->insert('ConversationMessage', array('ConversationID' => $ConversationID, 'Body' => t('StubConversationBody', $ConversationBody), 'Format' => 'Html', 'InsertUserID' => $SystemUserID, 'DateInserted' => $Now));
$SQL->update('Conversation')->set('LastMessageID', $MessageID)->where('ConversationID', $ConversationID)->put();
$SQL->insert('UserConversation', array('ConversationID' => $ConversationID, 'UserID' => $TargetUserID, 'CountReadMessages' => 0, 'LastMessageID' => $MessageID, 'DateConversationUpdated' => $Now));
Example #11
0
 /**
  * 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']]);
     }
 }
Example #12
0
 /**
  * Saves a name/value to the user's specified $Column.
  *
  * This method throws exceptions when errors are encountered. Use try catch blocks to capture these exceptions.
  *
  * @param string $Column The name of the serialized column to save to. At the time of this writing there are three serialized columns on the user table: Permissions, Preferences, and Attributes.
  * @param int $UserID The UserID to save.
  * @param mixed $Name The name of the value being saved, or an associative array of name => value pairs to be saved. If this is an associative array, the $Value argument will be ignored.
  * @param mixed $Value The value being saved.
  */
 public function saveToSerializedColumn($Column, $UserID, $Name, $Value = '')
 {
     // Load the existing values
     $UserData = $this->getID($UserID, DATASET_TYPE_OBJECT);
     if (!$UserData) {
         throw new Exception(sprintf('User %s not found.', $UserID));
     }
     $Values = val($Column, $UserData);
     if (!is_array($Values) && !is_object($Values)) {
         $Values = dbdecode($UserData->{$Column});
     }
     // Throw an exception if the field was not empty but is also not an object or array
     if (is_string($Values) && $Values != '') {
         throw new Exception(sprintf(t('Serialized column "%s" failed to be unserialized.'), $Column));
     }
     if (!is_array($Values)) {
         $Values = [];
     }
     // Hook for plugins
     $this->EventArguments['CurrentValues'] =& $Values;
     $this->EventArguments['Column'] =& $Column;
     $this->EventArguments['UserID'] =& $UserID;
     $this->EventArguments['Name'] =& $Name;
     $this->EventArguments['Value'] =& $Value;
     $this->fireEvent('BeforeSaveSerialized');
     // Assign the new value(s)
     if (!is_array($Name)) {
         $Name = [$Name => $Value];
     }
     $RawValues = array_merge($Values, $Name);
     $Values = [];
     foreach ($RawValues as $Key => $RawValue) {
         if (!is_null($RawValue)) {
             $Values[$Key] = $RawValue;
         }
     }
     $Values = dbencode($Values);
     // Save the values back to the db
     $SaveResult = $this->SQL->put('User', [$Column => $Values], ['UserID' => $UserID]);
     $this->clearCache($UserID, ['user']);
     return $SaveResult;
 }
Example #13
0
 /**
  * Place a name/value pair into the user's session stash.
  *
  * @param string $name            The key of the stash value.
  * @param mixed  $value           The value of the stash to set. Pass null to retrieve the key.
  * @param bool   $unsetOnRetrieve Whether or not to unset the key from stash.
  *
  * @return mixed Returns the value of the stash or null on failure.
  */
 public function stash($name = '', $value = '', $unsetOnRetrieve = true)
 {
     if ($name == '') {
         return;
     }
     // Create a fresh copy of the Sql object to avoid pollution.
     $sql = clone Gdn::sql();
     $sql->reset();
     // Grab the user's session.
     $session = $this->getStashSession($sql, $value);
     if (!$session) {
         return;
     }
     // Stash or unstash the value depending on inputs.
     if ($value != '') {
         $session->Attributes[$name] = $value;
     } else {
         $value = val($name, $session->Attributes);
         if ($unsetOnRetrieve) {
             unset($session->Attributes[$name]);
         }
     }
     // Update the attributes.
     $sql->put('Session', ['DateUpdated' => Gdn_Format::toDateTime(), 'Attributes' => dbencode($session->Attributes)], ['SessionID' => $session->SessionID]);
     return $value;
 }
Example #14
0
 /**
  * Create or update a comment.
  *
  * @since 2.0.0
  * @access public
  *
  * @param int $DiscussionID Unique ID to add the comment to. If blank, this method will throw an error.
  */
 public function comment($DiscussionID = '')
 {
     // Get $DiscussionID from RequestArgs if valid
     if ($DiscussionID == '' && count($this->RequestArgs)) {
         if (is_numeric($this->RequestArgs[0])) {
             $DiscussionID = $this->RequestArgs[0];
         }
     }
     // If invalid $DiscussionID, get from form.
     $this->Form->setModel($this->CommentModel);
     $DiscussionID = is_numeric($DiscussionID) ? $DiscussionID : $this->Form->getFormValue('DiscussionID', 0);
     // Set discussion data
     $this->DiscussionID = $DiscussionID;
     $this->Discussion = $Discussion = $this->DiscussionModel->getID($DiscussionID);
     // Is this an embedded comment being posted to a discussion that doesn't exist yet?
     $vanilla_type = $this->Form->getFormValue('vanilla_type', '');
     $vanilla_url = $this->Form->getFormValue('vanilla_url', '');
     $vanilla_category_id = $this->Form->getFormValue('vanilla_category_id', '');
     $Attributes = array('ForeignUrl' => $vanilla_url);
     $vanilla_identifier = $this->Form->getFormValue('vanilla_identifier', '');
     $isEmbeddedComments = $vanilla_url != '' && $vanilla_identifier != '';
     // Only allow vanilla identifiers of 32 chars or less - md5 if larger
     if (strlen($vanilla_identifier) > 32) {
         $Attributes['vanilla_identifier'] = $vanilla_identifier;
         $vanilla_identifier = md5($vanilla_identifier);
     }
     if (!$Discussion && $isEmbeddedComments) {
         $Discussion = $Discussion = $this->DiscussionModel->getForeignID($vanilla_identifier, $vanilla_type);
         if ($Discussion) {
             $this->DiscussionID = $DiscussionID = $Discussion->DiscussionID;
             $this->Form->setValue('DiscussionID', $DiscussionID);
         }
     }
     // If so, create it!
     if (!$Discussion && $isEmbeddedComments) {
         // Add these values back to the form if they exist!
         $this->Form->addHidden('vanilla_identifier', $vanilla_identifier);
         $this->Form->addHidden('vanilla_type', $vanilla_type);
         $this->Form->addHidden('vanilla_url', $vanilla_url);
         $this->Form->addHidden('vanilla_category_id', $vanilla_category_id);
         $PageInfo = fetchPageInfo($vanilla_url);
         if (!($Title = $this->Form->getFormValue('Name'))) {
             $Title = val('Title', $PageInfo, '');
             if ($Title == '') {
                 $Title = t('Undefined discussion subject.');
                 if (!empty($PageInfo['Exception']) && $PageInfo['Exception'] === "Couldn't connect to host.") {
                     $Title .= ' ' . t('Page timed out.');
                 }
             }
         }
         $Description = val('Description', $PageInfo, '');
         $Images = val('Images', $PageInfo, array());
         $LinkText = t('EmbededDiscussionLinkText', 'Read the full story here');
         if (!$Description && count($Images) == 0) {
             $Body = formatString('<p><a href="{Url}">{LinkText}</a></p>', array('Url' => $vanilla_url, 'LinkText' => $LinkText));
         } else {
             $Body = formatString('
         <div class="EmbeddedContent">{Image}<strong>{Title}</strong>
            <p>{Excerpt}</p>
            <p><a href="{Url}">{LinkText}</a></p>
            <div class="ClearFix"></div>
         </div>', array('Title' => $Title, 'Excerpt' => $Description, 'Image' => count($Images) > 0 ? img(val(0, $Images), array('class' => 'LeftAlign')) : '', 'Url' => $vanilla_url, 'LinkText' => $LinkText));
         }
         if ($Body == '') {
             $Body = $vanilla_url;
         }
         if ($Body == '') {
             $Body = t('Undefined discussion body.');
         }
         // Validate the CategoryID for inserting.
         $Category = CategoryModel::categories($vanilla_category_id);
         if (!$Category) {
             $vanilla_category_id = c('Vanilla.Embed.DefaultCategoryID', 0);
             if ($vanilla_category_id <= 0) {
                 // No default category defined, so grab the first non-root category and use that.
                 $vanilla_category_id = $this->DiscussionModel->SQL->select('CategoryID')->from('Category')->where('CategoryID >', 0)->get()->firstRow()->CategoryID;
                 // No categories in the db? default to 0
                 if (!$vanilla_category_id) {
                     $vanilla_category_id = 0;
                 }
             }
         } else {
             $vanilla_category_id = $Category['CategoryID'];
         }
         $EmbedUserID = c('Garden.Embed.UserID');
         if ($EmbedUserID) {
             $EmbedUser = Gdn::userModel()->getID($EmbedUserID);
         }
         if (!$EmbedUserID || !$EmbedUser) {
             $EmbedUserID = Gdn::userModel()->getSystemUserID();
         }
         $EmbeddedDiscussionData = array('InsertUserID' => $EmbedUserID, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime(), 'CategoryID' => $vanilla_category_id, 'ForeignID' => $vanilla_identifier, 'Type' => $vanilla_type, 'Name' => $Title, 'Body' => $Body, 'Format' => 'Html', 'Attributes' => dbencode($Attributes));
         $this->EventArguments['Discussion'] =& $EmbeddedDiscussionData;
         $this->fireEvent('BeforeEmbedDiscussion');
         $DiscussionID = $this->DiscussionModel->SQL->insert('Discussion', $EmbeddedDiscussionData);
         $ValidationResults = $this->DiscussionModel->validationResults();
         if (count($ValidationResults) == 0 && $DiscussionID > 0) {
             $this->Form->addHidden('DiscussionID', $DiscussionID);
             // Put this in the form so reposts won't cause new discussions.
             $this->Form->setFormValue('DiscussionID', $DiscussionID);
             // Put this in the form values so it is used when saving comments.
             $this->setJson('DiscussionID', $DiscussionID);
             $this->Discussion = $Discussion = $this->DiscussionModel->getID($DiscussionID, DATASET_TYPE_OBJECT, array('Slave' => false));
             // Update the category discussion count
             if ($vanilla_category_id > 0) {
                 $this->DiscussionModel->updateDiscussionCount($vanilla_category_id, $DiscussionID);
             }
         }
     }
     // If no discussion was found, error out
     if (!$Discussion) {
         $this->Form->addError(t('Failed to find discussion for commenting.'));
     }
     /**
      * Special care is taken for embedded comments.  Since we don't currently use an advanced editor for these
      * comments, we may need to apply certain filters and fixes to the data to maintain its intended display
      * with the input format (e.g. maintaining newlines).
      */
     if ($isEmbeddedComments) {
         $inputFormatter = $this->Form->getFormValue('Format', c('Garden.InputFormatter'));
         switch ($inputFormatter) {
             case 'Wysiwyg':
                 $this->Form->setFormValue('Body', nl2br($this->Form->getFormValue('Body')));
                 break;
         }
     }
     $PermissionCategoryID = val('PermissionCategoryID', $Discussion);
     // Setup head
     $this->addJsFile('jquery.autosize.min.js');
     $this->addJsFile('autosave.js');
     $this->addJsFile('post.js');
     // Setup comment model, $CommentID, $DraftID
     $Session = Gdn::session();
     $CommentID = isset($this->Comment) && property_exists($this->Comment, 'CommentID') ? $this->Comment->CommentID : '';
     $DraftID = isset($this->Comment) && property_exists($this->Comment, 'DraftID') ? $this->Comment->DraftID : '';
     $this->EventArguments['CommentID'] = $CommentID;
     $this->EventArguments['DraftID'] = $DraftID;
     // Determine whether we are editing
     $Editing = $CommentID > 0 || $DraftID > 0;
     $this->EventArguments['Editing'] = $Editing;
     // If closed, cancel & go to discussion
     if ($Discussion && $Discussion->Closed == 1 && !$Editing && !$Session->checkPermission('Vanilla.Discussions.Close', true, 'Category', $PermissionCategoryID)) {
         redirect(DiscussionUrl($Discussion));
     }
     // Add hidden IDs to form
     $this->Form->addHidden('DiscussionID', $DiscussionID);
     $this->Form->addHidden('CommentID', $CommentID);
     $this->Form->addHidden('DraftID', $DraftID, true);
     // Check permissions
     if ($Discussion && $Editing) {
         // Permission to edit
         if ($this->Comment->InsertUserID != $Session->UserID) {
             $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID);
         }
         // Make sure that content can (still) be edited.
         $EditContentTimeout = c('Garden.EditContentTimeout', -1);
         $CanEdit = $EditContentTimeout == -1 || strtotime($this->Comment->DateInserted) + $EditContentTimeout > time();
         if (!$CanEdit) {
             $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID);
         }
         // Make sure only moderators can edit closed things
         if ($Discussion->Closed) {
             $this->permission('Vanilla.Comments.Edit', true, 'Category', $Discussion->PermissionCategoryID);
         }
         $this->Form->setFormValue('CommentID', $CommentID);
     } elseif ($Discussion) {
         // Permission to add
         $this->permission('Vanilla.Comments.Add', true, 'Category', $Discussion->PermissionCategoryID);
     }
     if ($this->Form->authenticatedPostBack()) {
         // Save as a draft?
         $FormValues = $this->Form->formValues();
         $FormValues = $this->CommentModel->filterForm($FormValues);
         if (!$Editing) {
             unset($FormValues['CommentID']);
         }
         if ($DraftID == 0) {
             $DraftID = $this->Form->getFormValue('DraftID', 0);
         }
         $Type = GetIncomingValue('Type');
         $Draft = $Type == 'Draft';
         $this->EventArguments['Draft'] = $Draft;
         $Preview = $Type == 'Preview';
         if ($Draft) {
             $DraftID = $this->DraftModel->save($FormValues);
             $this->Form->addHidden('DraftID', $DraftID, true);
             $this->Form->setValidationResults($this->DraftModel->validationResults());
         } elseif (!$Preview) {
             // Fix an undefined title if we can.
             if ($this->Form->getFormValue('Name') && val('Name', $Discussion) == t('Undefined discussion subject.')) {
                 $Set = array('Name' => $this->Form->getFormValue('Name'));
                 if (isset($vanilla_url) && $vanilla_url && strpos(val('Body', $Discussion), t('Undefined discussion subject.')) !== false) {
                     $LinkText = t('EmbededDiscussionLinkText', 'Read the full story here');
                     $Set['Body'] = formatString('<p><a href="{Url}">{LinkText}</a></p>', array('Url' => $vanilla_url, 'LinkText' => $LinkText));
                 }
                 $this->DiscussionModel->setField(val('DiscussionID', $Discussion), $Set);
             }
             $Inserted = !$CommentID;
             $CommentID = $this->CommentModel->save($FormValues);
             // The comment is now half-saved.
             if (is_numeric($CommentID) && $CommentID > 0) {
                 if (in_array($this->deliveryType(), array(DELIVERY_TYPE_ALL, DELIVERY_TYPE_DATA))) {
                     $this->CommentModel->save2($CommentID, $Inserted, true, true);
                 } else {
                     $this->jsonTarget('', url("/post/comment2.json?commentid={$CommentID}&inserted={$Inserted}"), 'Ajax');
                 }
                 // $Discussion = $this->DiscussionModel->getID($DiscussionID);
                 $Comment = $this->CommentModel->getID($CommentID, DATASET_TYPE_OBJECT, array('Slave' => false));
                 $this->EventArguments['Discussion'] = $Discussion;
                 $this->EventArguments['Comment'] = $Comment;
                 $this->fireEvent('AfterCommentSave');
             } elseif ($CommentID === SPAM || $CommentID === UNAPPROVED) {
                 $this->StatusMessage = t('CommentRequiresApprovalStatus', 'Your comment will appear after it is approved.');
             }
             $this->Form->setValidationResults($this->CommentModel->validationResults());
             if ($CommentID > 0 && $DraftID > 0) {
                 $this->DraftModel->delete($DraftID);
             }
         }
         // Handle non-ajax requests first:
         if ($this->_DeliveryType == DELIVERY_TYPE_ALL) {
             if ($this->Form->errorCount() == 0) {
                 // Make sure that this form knows what comment we are editing.
                 if ($CommentID > 0) {
                     $this->Form->addHidden('CommentID', $CommentID);
                 }
                 // If the comment was not a draft
                 if (!$Draft) {
                     // Redirect to the new comment.
                     if ($CommentID > 0) {
                         redirect("discussion/comment/{$CommentID}/#Comment_{$CommentID}");
                     } elseif ($CommentID == SPAM) {
                         $this->setData('DiscussionUrl', DiscussionUrl($Discussion));
                         $this->View = 'Spam';
                     }
                 } elseif ($Preview) {
                     // If this was a preview click, create a comment shell with the values for this comment
                     $this->Comment = new stdClass();
                     $this->Comment->InsertUserID = $Session->User->UserID;
                     $this->Comment->InsertName = $Session->User->Name;
                     $this->Comment->InsertPhoto = $Session->User->Photo;
                     $this->Comment->DateInserted = Gdn_Format::date();
                     $this->Comment->Body = val('Body', $FormValues, '');
                     $this->Comment->Format = val('Format', $FormValues, c('Garden.InputFormatter'));
                     $this->addAsset('Content', $this->fetchView('preview'));
                 } else {
                     // If this was a draft save, notify the user about the save
                     $this->informMessage(sprintf(t('Draft saved at %s'), Gdn_Format::date()));
                 }
             }
         } else {
             // Handle ajax-based requests
             if ($this->Form->errorCount() > 0) {
                 // Return the form errors
                 $this->errorMessage($this->Form->errors());
             } else {
                 // Make sure that the ajax request form knows about the newly created comment or draft id
                 $this->setJson('CommentID', $CommentID);
                 $this->setJson('DraftID', $DraftID);
                 if ($Preview) {
                     // If this was a preview click, create a comment shell with the values for this comment
                     $this->Comment = new stdClass();
                     $this->Comment->InsertUserID = $Session->User->UserID;
                     $this->Comment->InsertName = $Session->User->Name;
                     $this->Comment->InsertPhoto = $Session->User->Photo;
                     $this->Comment->DateInserted = Gdn_Format::date();
                     $this->Comment->Body = val('Body', $FormValues, '');
                     $this->Comment->Format = val('Format', $FormValues, c('Garden.InputFormatter'));
                     $this->View = 'preview';
                 } elseif (!$Draft) {
                     // If the comment was not a draft
                     // If Editing a comment
                     if ($Editing) {
                         // Just reload the comment in question
                         $this->Offset = 1;
                         $Comments = $this->CommentModel->getIDData($CommentID, array('Slave' => false));
                         $this->setData('Comments', $Comments);
                         $this->setData('Discussion', $Discussion);
                         // Load the discussion
                         $this->ControllerName = 'discussion';
                         $this->View = 'comments';
                         // Also define the discussion url in case this request came from the post screen and needs to be redirected to the discussion
                         $this->setJson('DiscussionUrl', DiscussionUrl($this->Discussion) . '#Comment_' . $CommentID);
                     } else {
                         // If the comment model isn't sorted by DateInserted or CommentID then we can't do any fancy loading of comments.
                         $OrderBy = valr('0.0', $this->CommentModel->orderBy());
                         //                     $Redirect = !in_array($OrderBy, array('c.DateInserted', 'c.CommentID'));
                         //							$DisplayNewCommentOnly = $this->Form->getFormValue('DisplayNewCommentOnly');
                         //                     if (!$Redirect) {
                         //                        // Otherwise load all new comments that the user hasn't seen yet
                         //                        $LastCommentID = $this->Form->getFormValue('LastCommentID');
                         //                        if (!is_numeric($LastCommentID))
                         //                           $LastCommentID = $CommentID - 1; // Failsafe back to this new comment if the lastcommentid was not defined properly
                         //
                         //                        // Don't reload the first comment if this new comment is the first one.
                         //                        $this->Offset = $LastCommentID == 0 ? 1 : $this->CommentModel->GetOffset($LastCommentID);
                         //                        // Do not load more than a single page of data...
                         //                        $Limit = c('Vanilla.Comments.PerPage', 30);
                         //
                         //                        // Redirect if the new new comment isn't on the same page.
                         //                        $Redirect |= !$DisplayNewCommentOnly && PageNumber($this->Offset, $Limit) != PageNumber($Discussion->CountComments - 1, $Limit);
                         //                     }
                         //                     if ($Redirect) {
                         //                        // The user posted a comment on a page other than the last one, so just redirect to the last page.
                         //                        $this->RedirectUrl = Gdn::request()->Url("discussion/comment/$CommentID/#Comment_$CommentID", true);
                         //                     } else {
                         //                        // Make sure to load all new comments since the page was last loaded by this user
                         //								if ($DisplayNewCommentOnly)
                         $this->Offset = $this->CommentModel->GetOffset($CommentID);
                         $Comments = $this->CommentModel->GetIDData($CommentID, array('Slave' => false));
                         $this->setData('Comments', $Comments);
                         $this->setData('NewComments', true);
                         $this->ClassName = 'DiscussionController';
                         $this->ControllerName = 'discussion';
                         $this->View = 'comments';
                         //                     }
                         // Make sure to set the user's discussion watch records
                         $CountComments = $this->CommentModel->getCount($DiscussionID);
                         $Limit = is_object($this->data('Comments')) ? $this->data('Comments')->numRows() : $Discussion->CountComments;
                         $Offset = $CountComments - $Limit;
                         $this->CommentModel->SetWatch($this->Discussion, $Limit, $Offset, $CountComments);
                     }
                 } else {
                     // If this was a draft save, notify the user about the save
                     $this->informMessage(sprintf(t('Draft saved at %s'), Gdn_Format::date()));
                 }
                 // And update the draft count
                 $UserModel = Gdn::userModel();
                 $CountDrafts = $UserModel->getAttribute($Session->UserID, 'CountDrafts', 0);
                 $this->setJson('MyDrafts', t('My Drafts'));
                 $this->setJson('CountDrafts', $CountDrafts);
             }
         }
     } elseif ($this->Request->isPostBack()) {
         throw new Gdn_UserException(t('Invalid CSRF token.', 'Invalid CSRF token. Please try again.'), 401);
     } else {
         // Load form
         if (isset($this->Comment)) {
             $this->Form->setData((array) $this->Comment);
         }
     }
     // Include data for FireEvent
     if (property_exists($this, 'Discussion')) {
         $this->EventArguments['Discussion'] = $this->Discussion;
     }
     if (property_exists($this, 'Comment')) {
         $this->EventArguments['Comment'] = $this->Comment;
     }
     $this->fireEvent('BeforeCommentRender');
     if ($this->deliveryType() == DELIVERY_TYPE_DATA) {
         if ($this->data('Comments') instanceof Gdn_DataSet) {
             $Comment = $this->data('Comments')->firstRow(DATASET_TYPE_ARRAY);
             if ($Comment) {
                 $Photo = $Comment['InsertPhoto'];
                 if (strpos($Photo, '//') === false) {
                     $Photo = Gdn_Upload::url(changeBasename($Photo, 'n%s'));
                 }
                 $Comment['InsertPhoto'] = $Photo;
             }
             $this->Data = array('Comment' => $Comment);
         }
         $this->RenderData($this->Data);
     } else {
         require_once $this->fetchViewLocation('helper_functions', 'Discussion');
         // Render default view.
         $this->render();
     }
 }
Example #15
0
 /**
  *
  *
  * @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;
 }
Example #16
0
 /**
  * Get a user's permissions.
  *
  * @param int $userID Unique ID of the user.
  * @return Vanilla\Permissions
  */
 public function getPermissions($userID)
 {
     $permissions = new Vanilla\Permissions();
     $permissionsKey = '';
     if (Gdn::cache()->activeEnabled()) {
         $permissionsIncrement = $this->getPermissionsIncrement();
         $permissionsKey = formatString(self::USERPERMISSIONS_KEY, ['UserID' => $userID, 'PermissionsIncrement' => $permissionsIncrement]);
         $cachedPermissions = Gdn::cache()->get($permissionsKey);
         if ($cachedPermissions !== Gdn_Cache::CACHEOP_FAILURE) {
             $permissions->setPermissions($cachedPermissions);
             return $permissions;
         }
     }
     $data = Gdn::permissionModel()->cachePermissions($userID);
     $permissions->compileAndLoad($data);
     $this->EventArguments['UserID'] = $userID;
     $this->EventArguments['Permissions'] = $permissions;
     $this->fireEvent('loadPermissions');
     if (Gdn::cache()->activeEnabled()) {
         Gdn::cache()->store($permissionsKey, $permissions->getPermissions());
     } else {
         // Save the permissions to the user table
         if ($userID > 0) {
             $this->SQL->put('User', ['Permissions' => dbencode($permissions->getPermissions())], ['UserID' => $userID]);
         }
     }
     return $permissions;
 }
Example #17
0
 /**
  * Place a name/value pair into the user's session stash.
  */
 public function stash($Name = '', $Value = '', $UnsetOnRetrieve = true)
 {
     if ($Name == '') {
         return;
     }
     // Grab the user's session
     $Session = $this->_getStashSession($Value);
     if (!$Session) {
         return;
     }
     // Stash or unstash the value depending on inputs
     if ($Name != '' && $Value != '') {
         $Session->Attributes[$Name] = $Value;
     } elseif ($Name != '') {
         $Value = val($Name, $Session->Attributes);
         if ($UnsetOnRetrieve) {
             unset($Session->Attributes[$Name]);
         }
     }
     // Update the attributes
     if ($Name != '') {
         Gdn::SQL()->put('Session', array('DateUpdated' => Gdn_Format::toDateTime(), 'Attributes' => dbencode($Session->Attributes)), array('SessionID' => $Session->SessionID));
     }
     return $Value;
 }