public function __construct($Sender = '')
 {
     if (!CheckPermission('Conversations.Conversations.Add')) {
         throw PermissionException();
     }
     $Session = Gdn::Session();
     if (property_exists($Sender, 'Conversation')) {
         $this->Conversation = $Sender->Conversation;
     }
     $this->Form = Gdn::Factory('Form', 'AddPeople');
     // $this->Form->Action = $Sender->SelfUrl;
     // If the form was posted back, check for people to add to the conversation
     if ($this->Form->AuthenticatedPostBack()) {
         $NewRecipientUserIDs = array();
         $NewRecipients = explode(',', $this->Form->GetFormValue('AddPeople', ''));
         $UserModel = Gdn::Factory("UserModel");
         foreach ($NewRecipients as $Name) {
             if (trim($Name) != '') {
                 $User = $UserModel->GetByUsername(trim($Name));
                 if (is_object($User)) {
                     $NewRecipientUserIDs[] = $User->UserID;
                 }
             }
         }
         $Sender->ConversationModel->AddUserToConversation($this->Conversation->ConversationID, $NewRecipientUserIDs);
         // if ($Sender->DeliveryType() == DELIVERY_TYPE_ALL)
         //    Redirect('/messages/'.$this->Conversation->ConversationID);
         $Sender->InformMessage(T('Your changes were saved.'));
         $Sender->RedirectUrl = Url('/messages/' . $this->Conversation->ConversationID);
     }
     $this->_ApplicationFolder = $Sender->Application;
     $this->_ThemeFolder = $Sender->Theme;
 }
 public function Permission()
 {
     if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) {
         $this->Render();
     } else {
         $this->RenderException(PermissionException());
     }
 }
 /**
  * This determines if the current user can react on this item with this action
  *
  * @param string $Type valid options are 'discussion', 'comment', and 'activity'
  * @param int $ID
  * @param int $ActionID
  * @throws Gdn_UserException
  */
 public function Index($Type, $ID, $ActionID)
 {
     $Type = strtolower($Type);
     $Action = $this->ActionModel->GetByID($ActionID);
     // Make sure the action exists and the user is allowed to react
     if (!$Action) {
         throw new Gdn_UserException(T('Yaga.Action.Invalid'));
     }
     if (!Gdn::Session()->CheckPermission($Action->Permission)) {
         throw PermissionException();
     }
     switch ($Type) {
         case 'discussion':
             $Model = new DiscussionModel();
             $AnchorID = '#Discussion_';
             break;
         case 'comment':
             $Model = new CommentModel();
             $AnchorID = '#Comment_';
             break;
         case 'activity':
             $Model = new ActivityModel();
             $AnchorID = '#Activity_';
             break;
         default:
             throw new Gdn_UserException(T('Yaga.Action.InvalidTargetType'));
             break;
     }
     $Item = $Model->GetID($ID);
     if ($Item) {
         $Anchor = $AnchorID . $ID . ' .ReactMenu';
     } else {
         throw new Gdn_UserException(T('Yaga.Action.InvalidTargetID'));
     }
     $UserID = Gdn::Session()->UserID;
     switch ($Type) {
         case 'comment':
         case 'discussion':
             $ItemOwnerID = $Item->InsertUserID;
             break;
         case 'activity':
             $ItemOwnerID = $Item['RegardingUserID'];
             break;
         default:
             throw new Gdn_UserException(T('Yaga.Action.InvalidTargetType'));
             break;
     }
     if ($ItemOwnerID == $UserID) {
         throw new Gdn_UserException(T('Yaga.Error.ReactToOwn'));
     }
     // It has passed through the gauntlet
     $this->ReactionModel->Set($ID, $Type, $ItemOwnerID, $UserID, $ActionID);
     $this->JsonTarget($Anchor, RenderReactionList($ID, $Type, FALSE), 'ReplaceWith');
     // Don't render anything
     $this->Render('Blank', 'Utility', 'Dashboard');
 }
 public function DiscussionController_AutoExpire_Create($Sender, $Args)
 {
     $DiscussionID = intval($Args[0]);
     $DiscussionModel = new DiscussionModel();
     $Discussion = $DiscussionModel->GetID($DiscussionID);
     if (!Gdn::Session()->CheckPermission('Vanilla.Discussions.Close', TRUE, 'Category', $Discussion->PermissionCategoryID)) {
         throw PermissionException('Vanilla.Discussions.Close');
     }
     if (strtolower($Args[1]) == 'reset') {
         Gdn::SQL()->Put('Discussion', array('AutoExpire' => 1, 'Closed' => 0, 'DateReOpened' => Gdn_Format::ToDateTime()), array('DiscussionID' => $DiscussionID));
     } else {
         $Expire = strtolower($Args[1]) == 'on' ? 1 : 0;
         Gdn::SQL()->Put('Discussion', array('AutoExpire' => $Expire), array('DiscussionID' => $DiscussionID));
     }
     Redirect('discussion/' . $DiscussionID . '/' . Gdn_Format::Url($Discussion->Name));
 }
 public function Archives($Category, $Month, $Page = FALSE)
 {
     $Category = CategoryModel::Categories($Category);
     if (!$Category) {
         throw NotFoundException($Category);
     }
     if (!$Category['PermsDiscussionsView']) {
         throw PermissionException();
     }
     $Timestamp = strtotime($Month);
     if (!$Timestamp) {
         throw new Gdn_UserException("{$Month} is not a valid date.");
     }
     $this->SetData('Category', $Category);
     // Round the month to the first day.
     $From = gmdate('Y-m-01', $Timestamp);
     $To = gmdate('Y-m-01', strtotime('+1 month', strtotime($From)));
     // Grab the discussions.
     list($Offset, $Limit) = OffsetLimit($Page, C('Vanilla.Discussions.PerPage', 30));
     $Where = array('CategoryID' => $Category['CategoryID'], 'Announce' => 'all', 'DateInserted >=' => $From, 'DateInserted <' => $To);
     SaveToConfig('Vanilla.Discussions.SortField', 'd.DateInserted', FALSE);
     $DiscussionModel = new DiscussionModel();
     $Discussions = $DiscussionModel->GetWhere($Where, $Offset, $Limit);
     $this->DiscussionData = $this->SetData('Discussions', $Discussions);
     $this->SetData('_CurrentRecords', count($Discussions));
     $this->SetData('_Limit', $Limit);
     $Canonical = '/categories/archives/' . rawurlencode($Category['UrlCode']) . '/' . gmdate('Y-m', $Timestamp);
     $Page = PageNumber($Offset, $Limit, TRUE, FALSE);
     $this->CanonicalUrl(Url($Canonical . ($Page ? '?page=' . $Page : ''), TRUE));
     PagerModule::Current()->Configure($Offset, $Limit, FALSE, $Canonical . '?page={Page}');
     //      PagerModule::Current()->Offset = $Offset;
     //      PagerModule::Current()->Url = '/categories/archives'.rawurlencode($Category['UrlCode']).'?page={Page}';
     Gdn_Theme::Section(GetValue('CssClass', $Category));
     Gdn_Theme::Section('DiscussionList');
     $this->Title(htmlspecialchars(GetValue('Name', $Category, '')));
     $this->Description(sprintf(T("Archives for %s"), gmdate('F Y', strtotime($From))), TRUE);
     $this->AddJsFile('discussions.js');
     $this->Head->AddTag('meta', array('name' => 'robots', 'content' => 'noindex'));
     $this->ControllerName = 'DiscussionsController';
     $this->CssClass = 'Discussions';
     $this->Render();
 }
 /**
  * Validates the current user's permissions & transientkey and then marks a user as a troll.
  *
  * @param UserController $sender
  */
 public function userController_markTroll_create($sender, $userID, $troll = true)
 {
     $sender->permission('Garden.Moderation.Manage');
     $trollUserID = $userID;
     // Validate the transient key && permissions
     // Make sure we are posting back.
     if (!$sender->Request->isAuthenticatedPostBack()) {
         throw PermissionException('Javascript');
     }
     $trolls = self::getTrolls();
     // Toggle troll value in DB
     if (in_array($trollUserID, $trolls)) {
         Gdn::sql()->update('User', ['Troll' => 0], ['UserID' => $trollUserID])->put();
         unset($trolls[array_search($trollUserID, $trolls)]);
     } else {
         Gdn::sql()->update('User', ['Troll' => 1], ['UserID' => $trollUserID])->put();
         $trolls[] = $trollUserID;
     }
     self::setTrolls($trolls);
     $sender->jsonTarget('', '', 'Refresh');
     $sender->render('Blank', 'Utility', 'Dashboard');
 }
 /**
  * Add a method to the ModerationController to handle merging discussions.
  * @param Gdn_Controller $Sender
  */
 public function ModerationController_MergeDiscussions_Create($Sender)
 {
     $Session = Gdn::Session();
     $Sender->Form = new Gdn_Form();
     $Sender->Title(T('Merge Discussions'));
     $DiscussionModel = new DiscussionModel();
     $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
     if (!is_array($CheckedDiscussions)) {
         $CheckedDiscussions = array();
     }
     $DiscussionIDs = $CheckedDiscussions;
     $Sender->SetData('DiscussionIDs', $DiscussionIDs);
     $CountCheckedDiscussions = count($DiscussionIDs);
     $Sender->SetData('CountCheckedDiscussions', $CountCheckedDiscussions);
     $Discussions = $DiscussionModel->SQL->WhereIn('DiscussionID', $DiscussionIDs)->Get('Discussion')->ResultArray();
     $Sender->SetData('Discussions', $Discussions);
     // Perform the merge
     if ($Sender->Form->AuthenticatedPostBack()) {
         // Create a new discussion record
         $MergeDiscussion = FALSE;
         $MergeDiscussionID = $Sender->Form->GetFormValue('MergeDiscussionID');
         foreach ($Discussions as $Discussion) {
             if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                 $MergeDiscussion = $Discussion;
                 break;
             }
         }
         $RedirectLink = $Sender->Form->GetFormValue('RedirectLink');
         if ($MergeDiscussion) {
             $ErrorCount = 0;
             // Verify that the user has permission to perform the merge.
             $Category = CategoryModel::Categories($MergeDiscussion['CategoryID']);
             if ($Category && !$Category['PermsDiscussionsEdit']) {
                 throw PermissionException('Vanilla.Discussions.Edit');
             }
             $DiscussionModel->DefineSchema();
             $MaxNameLength = GetValue('Length', $DiscussionModel->Schema->GetField('Name'));
             // Assign the comments to the new discussion record
             $DiscussionModel->SQL->Update('Comment')->Set('DiscussionID', $MergeDiscussionID)->WhereIn('DiscussionID', $DiscussionIDs)->Put();
             $CommentModel = new CommentModel();
             foreach ($Discussions as $Discussion) {
                 if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                     continue;
                 }
                 // Create a comment out of the discussion.
                 $Comment = ArrayTranslate($Discussion, array('Body', 'Format', 'DateInserted', 'InsertUserID', 'InsertIPAddress', 'DateUpdated', 'UpdateUserID', 'UpdateIPAddress', 'Attributes', 'Spam', 'Likes', 'Abuse'));
                 $Comment['DiscussionID'] = $MergeDiscussionID;
                 $CommentModel->Validation->Results(TRUE);
                 $CommentID = $CommentModel->Save($Comment);
                 if ($CommentID) {
                     // Move any attachments (FileUpload plugin awareness)
                     if (class_exists('MediaModel')) {
                         $MediaModel = new MediaModel();
                         $MediaModel->Reassign($Discussion['DiscussionID'], 'discussion', $CommentID, 'comment');
                     }
                     if ($RedirectLink) {
                         // The discussion needs to be changed to a moved link.
                         $RedirectDiscussion = array('Name' => SliceString(sprintf(T('Merged: %s'), $Discussion['Name']), $MaxNameLength), 'Type' => 'redirect', 'Body' => FormatString(T('This discussion has been <a href="{url,html}">merged</a>.'), array('url' => DiscussionUrl($MergeDiscussion))), 'Format' => 'Html');
                         $DiscussionModel->SetField($Discussion['DiscussionID'], $RedirectDiscussion);
                         $CommentModel->UpdateCommentCount($Discussion['DiscussionID']);
                         $CommentModel->RemovePageCache($Discussion['DiscussionID']);
                     } else {
                         // Delete discussion that was merged.
                         $DiscussionModel->Delete($Discussion['DiscussionID']);
                     }
                 } else {
                     $Sender->InformMessage($CommentModel->Validation->ResultsText());
                     $ErrorCount++;
                 }
             }
             // Update counts on all affected discussions.
             $CommentModel->UpdateCommentCount($MergeDiscussionID);
             $CommentModel->RemovePageCache($MergeDiscussionID);
             // Clear selections
             Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
             ModerationController::InformCheckedDiscussions($Sender);
             if ($ErrorCount == 0) {
                 $Sender->JsonTarget('', '', 'Refresh');
             }
         }
     }
     $Sender->Render('MergeDiscussions', '', 'plugins/SplitMerge');
 }
 public function SetHourOffset()
 {
     $Form = new Gdn_Form();
     if ($Form->AuthenticatedPostBack()) {
         if (!Gdn::Session()->IsValid()) {
             throw PermissionException('Garden.SignIn.Allow');
         }
         $HourOffset = $Form->GetFormValue('HourOffset');
         Gdn::UserModel()->SetField(Gdn::Session()->UserID, 'HourOffset', $HourOffset);
         $this->SetData('Result', TRUE);
         $this->SetData('HourOffset', $HourOffset);
         $time = time();
         $this->SetData('UTCDateTime', gmdate('r', $time));
         $this->SetData('UserDateTime', gmdate('r', $time + $HourOffset * 3600));
     } else {
         throw ForbiddenException('GET');
     }
     $this->Render('Blank');
 }
Esempio n. 9
0
 /**
  * Run a structure update on the database.
  *
  * @since 2.0.?
  * @access public
  */
 public function Update()
 {
     // Check for permission or flood control.
     // These settings are loaded/saved to the database because we don't want the config file storing non/config information.
     $Now = time();
     $LastTime = Gdn::Get('Garden.Update.LastTimestamp', 0);
     if ($LastTime + 60 * 60 * 24 > $Now) {
         // Check for flood control.
         $Count = Gdn::Get('Garden.Update.Count', 0) + 1;
         if ($Count > 5) {
             if (!Gdn::Session()->CheckPermission('Garden.Settings.Manage')) {
                 // We are only allowing an update of 5 times every 24 hours.
                 throw PermissionException();
             }
         }
     } else {
         $Count = 1;
     }
     Gdn::Set('Garden.Update.LastTimestamp', $Now);
     Gdn::Set('Garden.Update.Count', $Count);
     try {
         // Run the structure.
         $UpdateModel = new UpdateModel();
         $UpdateModel->RunStructure();
         $this->SetData('Success', TRUE);
     } catch (Exception $Ex) {
         $this->SetData('Success', FALSE);
     }
     if (Gdn::Session()->CheckPermission('Garden.Settings.Manage')) {
         SaveToConfig('Garden.Version', APPLICATION_VERSION);
     }
     if ($Target = $this->Request->Get('Target')) {
         Redirect($Target);
     }
     $this->MasterView = 'empty';
     $this->CssClass = 'Home';
     $this->Render();
 }
Esempio n. 10
0
 /**
  *
  *
  * @param DiscussionController $Sender
  */
 public function discussionController_download_create($Sender)
 {
     if (!$this->CanDownload) {
         throw PermissionException("File could not be streamed: Access is denied");
     }
     list($MediaID) = $Sender->RequestArgs;
     $Media = $this->mediaModel()->getID($MediaID);
     if (!$Media) {
         return;
     }
     $Filename = Gdn::request()->filename();
     if (!$Filename || $Filename == 'default') {
         $Filename = $Media->Name;
     }
     $DownloadPath = combinePaths(array(MediaModel::pathUploads(), val('Path', $Media)));
     if (in_array(strtolower(pathinfo($Filename, PATHINFO_EXTENSION)), array('bmp', 'gif', 'jpg', 'jpeg', 'png'))) {
         $ServeMode = 'inline';
     } else {
         $ServeMode = 'attachment';
     }
     $Served = false;
     $this->EventArguments['DownloadPath'] = $DownloadPath;
     $this->EventArguments['ServeMode'] = $ServeMode;
     $this->EventArguments['Media'] = $Media;
     $this->EventArguments['Served'] =& $Served;
     $this->fireEvent('BeforeDownload');
     if (!$Served) {
         return Gdn_FileSystem::serveFile($DownloadPath, $Filename, $Media->Type, $ServeMode);
         throw new Exception('File could not be streamed: missing file (' . $DownloadPath . ').');
     }
     exit;
 }
Esempio n. 11
0
 public function Verify($UserID, $Verified)
 {
     $this->Permission('Garden.Moderation.Manage');
     if (!$this->Request->IsAuthenticatedPostBack()) {
         throw PermissionException('Javascript');
     }
     // First, set the field value.
     Gdn::UserModel()->SetField($UserID, 'Verified', $Verified);
     $User = Gdn::UserModel()->GetID($UserID);
     if (!$User) {
         throw NotFoundException('User');
     }
     // Send back the verified button.
     require_once $this->FetchViewLocation('helper_functions', 'Profile', 'Dashboard');
     $this->JsonTarget('.User-Verified', UserVerified($User), 'ReplaceWith');
     $this->Render('Blank', 'Utility', 'Dashboard');
 }
Esempio n. 12
0
 /**
  * Redirect, but only to a safe domain.
  *
  * @param string $Destination Where to redirect.
  * @param int $StatusCode The status of the redirect. Defaults to 302.
  */
 function safeRedirect($Destination = false, $StatusCode = null)
 {
     if (!$Destination) {
         $Destination = Url('', true);
     } else {
         $Destination = Url($Destination, true);
     }
     $Domain = parse_url($Destination, PHP_URL_HOST);
     if (in_array($Domain, TrustedDomains())) {
         Redirect($Destination, $StatusCode);
     } else {
         throw PermissionException();
     }
 }
Esempio n. 13
0
 /**
  * Add a method to the ModerationController to handle merging discussions.
  * @param Gdn_Controller $Sender
  */
 public function ModerationController_MergeDiscussions_Create($Sender)
 {
     $Session = Gdn::Session();
     $Sender->Form = new Gdn_Form();
     $Sender->Title(T('Merge Discussions'));
     $DiscussionModel = new DiscussionModel();
     $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
     if (!is_array($CheckedDiscussions)) {
         $CheckedDiscussions = array();
     }
     $DiscussionIDs = $CheckedDiscussions;
     $Sender->SetData('DiscussionIDs', $DiscussionIDs);
     $CountCheckedDiscussions = count($DiscussionIDs);
     $Sender->SetData('CountCheckedDiscussions', $CountCheckedDiscussions);
     $Discussions = $DiscussionModel->SQL->WhereIn('DiscussionID', $DiscussionIDs)->Get('Discussion')->ResultArray();
     $Sender->SetData('Discussions', $Discussions);
     // Perform the merge
     if ($Sender->Form->AuthenticatedPostBack()) {
         // Create a new discussion record
         $MergeDiscussion = FALSE;
         $MergeDiscussionID = $Sender->Form->GetFormValue('MergeDiscussionID');
         foreach ($Discussions as $Discussion) {
             if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                 $MergeDiscussion = $Discussion;
                 break;
             }
         }
         if ($MergeDiscussion) {
             $ErrorCount = 0;
             // Verify that the user has permission to perform the merge.
             $Category = CategoryModel::Categories($MergeDiscussion['CategoryID']);
             if ($Category && !$Category['PermsDiscussionsEdit']) {
                 throw PermissionException('Vanilla.Discussions.Edit');
             }
             // Assign the comments to the new discussion record
             $DiscussionModel->SQL->Update('Comment')->Set('DiscussionID', $MergeDiscussionID)->WhereIn('DiscussionID', $DiscussionIDs)->Put();
             $CommentModel = new CommentModel();
             foreach ($Discussions as $Discussion) {
                 if ($Discussion['DiscussionID'] == $MergeDiscussionID) {
                     continue;
                 }
                 // Create a comment out of the discussion.
                 $Comment = ArrayTranslate($Discussion, array('Body', 'Format', 'DateInserted', 'InsertUserID', 'InsertIPAddress', 'DateUpdated', 'UpdateUserID', 'UpdateIPAddress', 'Attributes', 'Spam', 'Likes', 'Abuse'));
                 $Comment['DiscussionID'] = $MergeDiscussionID;
                 $CommentModel->Validation->Results(TRUE);
                 $CommentID = $CommentModel->Save($Comment);
                 if ($CommentID) {
                     // Move any attachments (FileUpload plugin awareness)
                     if (class_exists('MediaModel')) {
                         $MediaModel = new MediaModel();
                         $MediaModel->Reassign($Discussion['DiscussionID'], 'discussion', $CommentID, 'comment');
                     }
                     // Delete discussion that was merged
                     $DiscussionModel->Delete($Discussion['DiscussionID']);
                 } else {
                     $Sender->InformMessage($CommentModel->Validation->ResultsText());
                     $ErrorCount++;
                 }
             }
             // Update counts on all affected discussions.
             $CommentModel->UpdateCommentCount($MergeDiscussionID);
             $CommentModel->RemovePageCache($MergeDiscussionID);
             // Clear selections
             Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
             ModerationController::InformCheckedDiscussions($Sender);
             if ($ErrorCount == 0) {
                 $Sender->RedirectUrl = Url("/discussion/{$MergeDiscussionID}/" . Gdn_Format::Url($MergeDiscussion['Name']));
             }
         }
     }
     $Sender->Render('MergeDiscussions', '', 'plugins/SplitMerge');
 }
 /**
  * Retrieve the user to be manipulated. Defaults to current user.
  *
  * @since 2.0.0
  * @access public
  * @param mixed $User Unique identifier, possibly username or ID.
  * @param string $Username.
  * @param int $UserID Unique ID.
  * @param bool $CheckPermissions Whether or not to check user permissions.
  * @return bool Always true.
  */
 public function GetUserInfo($UserReference = '', $Username = '', $UserID = '', $CheckPermissions = FALSE)
 {
     if ($this->_UserInfoRetrieved) {
         return;
     }
     if (!C('Garden.Profile.Public') && !Gdn::Session()->IsValid()) {
         throw PermissionException();
     }
     // If a UserID was provided as a querystring parameter, use it over anything else:
     if ($UserID) {
         $UserReference = $UserID;
         $Username = '******';
         // Fill this with a value so the $UserReference is assumed to be an integer/userid.
     }
     $this->Roles = array();
     if ($UserReference == '') {
         if ($Username) {
             $this->User = $this->UserModel->GetByUsername($Username);
         } else {
             $this->User = $this->UserModel->GetID(Gdn::Session()->UserID);
         }
     } elseif (is_numeric($UserReference) && $Username != '') {
         $this->User = $this->UserModel->GetID($UserReference);
     } else {
         $this->User = $this->UserModel->GetByUsername($UserReference);
     }
     if ($this->User === FALSE) {
         throw NotFoundException('User');
     } else {
         if ($this->User->Deleted == 1) {
             Redirect('dashboard/home/deleted');
         } else {
             $this->RoleData = $this->UserModel->GetRoles($this->User->UserID);
             if ($this->RoleData !== FALSE && $this->RoleData->NumRows(DATASET_TYPE_ARRAY) > 0) {
                 $this->Roles = ConsolidateArrayValuesByKey($this->RoleData->Result(), 'Name');
             }
             if (Gdn::Session()->CheckPermission('Garden.Settings.Manage') || Gdn::Session()->UserID == $this->User->UserID) {
                 $this->User->Transient = GetValueR('Attributes.TransientKey', $this->User);
             }
             // Hide personal info roles
             if (!CheckPermission('Garden.PersonalInfo.View')) {
                 $this->Roles = array_filter($this->Roles, 'RoleModel::FilterPersonalInfo');
             }
             $this->SetData('Profile', $this->User);
             $this->SetData('UserRoles', $this->Roles);
             if ($CssClass = GetValue('_CssClass', $this->User)) {
                 $this->CssClass .= ' ' . $CssClass;
             }
         }
     }
     if ($CheckPermissions && Gdn::Session()->UserID != $this->User->UserID) {
         $this->Permission(array('Garden.Users.Edit', 'Moderation.Profiles.Edit'), FALSE);
     }
     $this->AddSideMenu();
     $this->_UserInfoRetrieved = TRUE;
     return TRUE;
 }
 /**
  * Allow user to set their preferred locale via link-click.
  */
 public function ProfileController_SetLocale_Create($Sender, $locale, $TK)
 {
     if (!Gdn::Session()->UserID) {
         throw PermissionException('Garden.SignIn.Allow');
     }
     // Check intent.
     if (!Gdn::Session()->ValidateTransientKey($TK)) {
         Redirect($_SERVER['HTTP_REFERER']);
     }
     // If we got a valid locale, save their preference
     if (isset($locale)) {
         $locale = $this->ValidateLocale($locale);
         if ($locale) {
             $this->SetUserMeta(Gdn::Session()->UserID, 'Locale', $locale);
         }
     }
     // Back from whence we came.
     Redirect($_SERVER['HTTP_REFERER']);
 }
 /**
  * Synchronizes the user based on a given UserKey.
  *
  * @param string $UserKey A string that uniquely identifies this user.
  * @param array $Data Information to put in the user table.
  * @return int The ID of the user.
  */
 public function Synchronize($UserKey, $Data)
 {
     $UserID = 0;
     $Attributes = ArrayValue('Attributes', $Data);
     if (is_string($Attributes)) {
         $Attributes = @unserialize($Attributes);
     }
     if (!is_array($Attributes)) {
         $Attributes = array();
     }
     // If the user didnt log in, they won't have a UserID yet. That means they want a new
     // account. So create one for them.
     if (!isset($Data['UserID']) || $Data['UserID'] <= 0) {
         // Prepare the user data.
         $UserData['Name'] = $Data['Name'];
         $UserData['Password'] = RandomString(16);
         $UserData['Email'] = ArrayValue('Email', $Data, '*****@*****.**');
         $UserData['Gender'] = strtolower(substr(ArrayValue('Gender', $Data, 'u'), 0, 1));
         $UserData['HourOffset'] = ArrayValue('HourOffset', $Data, 0);
         $UserData['DateOfBirth'] = ArrayValue('DateOfBirth', $Data, '');
         $UserData['CountNotifications'] = 0;
         $UserData['Attributes'] = $Attributes;
         $UserData['InsertIPAddress'] = Gdn::Request()->IpAddress();
         if ($UserData['DateOfBirth'] == '') {
             $UserData['DateOfBirth'] = '1975-09-16';
         }
         // Make sure there isn't another user with this username.
         if ($this->ValidateUniqueFields($UserData['Name'], $UserData['Email'])) {
             if (!BanModel::CheckUser($UserData, $this->Validation, TRUE)) {
                 throw PermissionException('Banned');
             }
             // Insert the new user.
             $this->AddInsertFields($UserData);
             $UserID = $this->_Insert($UserData);
         }
         if ($UserID) {
             $NewUserRoleIDs = $this->NewUserRoleIDs();
             // Save the roles.
             $Roles = GetValue('Roles', $Data, FALSE);
             if (empty($Roles)) {
                 $Roles = $NewUserRoleIDs;
             }
             $this->SaveRoles($UserID, $Roles, FALSE);
         }
     } else {
         $UserID = $Data['UserID'];
     }
     // Synchronize the transientkey from the external user data source if it is present (eg. WordPress' wpnonce).
     if (array_key_exists('TransientKey', $Attributes) && $Attributes['TransientKey'] != '' && $UserID > 0) {
         $this->SetTransientKey($UserID, $Attributes['TransientKey']);
     }
     return $UserID;
 }
 /**
  * Redirect, but only to a safe domain.
  *
  * @param string $Destination Where to redirect.
  * @param int $StatusCode
  */
 function SafeRedirect($Destination = FALSE, $StatusCode = NULL)
 {
     if (!$Destination) {
         $Destination = Url('', TRUE);
     } else {
         $Destination = Url($Destination, TRUE);
     }
     $Domain = parse_url($Destination, PHP_URL_HOST);
     if (in_array($Domain, TrustedDomains())) {
         Redirect($Destination, $StatusCode);
     } else {
         throw PermissionException();
     }
 }
Esempio n. 18
0
 /**
  * Display 'no permission' page.
  *
  * @since 2.0.0
  * @access public
  */
 public function Permission()
 {
     Gdn_Theme::Section('Error');
     if ($this->DeliveryMethod() == DELIVERY_METHOD_XHTML) {
         safeHeader("HTTP/1.0 401", TRUE, 401);
         $this->Render();
     } else {
         $this->RenderException(PermissionException());
     }
 }
 /**
  * Retrieve the user to be manipulated. Defaults to current user.
  *
  * @since 2.0.0
  * @access public
  * @param mixed $UserReference Unique identifier, possibly username or ID.
  * @param string $Username.
  * @param int $UserID Unique ID.
  * @param bool $CheckPermissions Whether or not to check user permissions.
  * @return bool Always true.
  */
 public function GetUserInfo($UserReference = '', $Username = '', $UserID = '', $CheckPermissions = FALSE)
 {
     if ($this->_UserInfoRetrieved) {
         return;
     }
     if (!C('Garden.Profile.Public') && !Gdn::Session()->IsValid()) {
         throw PermissionException();
     }
     // If a UserID was provided as a querystring parameter, use it over anything else:
     if ($UserID) {
         $UserReference = $UserID;
         $Username = '******';
         // Fill this with a value so the $UserReference is assumed to be an integer/userid.
     }
     $this->Roles = array();
     if ($UserReference == '') {
         $this->User = $this->UserModel->GetID(Gdn::Session()->UserID);
     } else {
         if (is_numeric($UserReference) && $Username != '') {
             $this->User = $this->UserModel->GetID($UserReference);
         } else {
             $this->User = $this->UserModel->GetByUsername($UserReference);
         }
     }
     if ($this->User === FALSE) {
         throw NotFoundException();
     } else {
         if ($this->User->Deleted == 1) {
             Redirect('dashboard/home/deleted');
         } else {
             $this->RoleData = $this->UserModel->GetRoles($this->User->UserID);
             if ($this->RoleData !== FALSE && $this->RoleData->NumRows(DATASET_TYPE_ARRAY) > 0) {
                 $this->Roles = ConsolidateArrayValuesByKey($this->RoleData->Result(), 'Name');
             }
             $this->SetData('Profile', $this->User);
             $this->SetData('UserRoles', $this->Roles);
         }
     }
     if ($CheckPermissions && Gdn::Session()->UserID != $this->User->UserID) {
         $this->Permission('Garden.Users.Edit');
     }
     // Make sure the userphoto module gets added to the page
     $UserPhotoModule = new UserPhotoModule($this);
     $UserPhotoModule->User = $this->User;
     $this->AddModule($UserPhotoModule);
     $this->AddSideMenu();
     $this->_UserInfoRetrieved = TRUE;
     return TRUE;
 }
 /**
  * Set user preference for sorting discussions.
  */
 public function Sort($Target = '')
 {
     if (!Gdn::Session()->IsValid()) {
         throw PermissionException();
     }
     if (!$this->Request->IsAuthenticatedPostBack()) {
         throw ForbiddenException('GET');
     }
     // Get param
     $SortField = Gdn::Request()->Post('DiscussionSort');
     $SortField = 'd.' . StringBeginsWith($SortField, 'd.', TRUE, TRUE);
     // Use whitelist here too to keep database clean
     if (!in_array($SortField, DiscussionModel::AllowedSortFields())) {
         throw new Gdn_UserException("Unknown sort {$SortField}.");
     }
     // Set user pref
     Gdn::UserModel()->SavePreference(Gdn::Session()->UserID, 'Discussions.SortField', $SortField);
     if ($Target) {
         Redirect($Target);
     }
     // Send sorted discussions.
     $this->DeliveryMethod(DELIVERY_METHOD_JSON);
     $this->Render();
 }
Esempio n. 21
0
 /**
  *
  * @param DiscussionController $Sender
  * @param array $Args
  */
 public function DiscussionController_QnA_Create($Sender, $Args = array())
 {
     $Comment = Gdn::SQL()->GetWhere('Comment', array('CommentID' => $Sender->Request->Get('commentid')))->FirstRow(DATASET_TYPE_ARRAY);
     if (!$Comment) {
         throw NotFoundException('Comment');
     }
     $Discussion = Gdn::SQL()->GetWhere('Discussion', array('DiscussionID' => $Comment['DiscussionID']))->FirstRow(DATASET_TYPE_ARRAY);
     // Check for permission.
     if (!(Gdn::Session()->UserID == GetValue('InsertUserID', $Discussion) || Gdn::Session()->CheckPermission('Garden.Moderation.Manage'))) {
         throw PermissionException('Garden.Moderation.Manage');
     }
     if (!Gdn::Session()->ValidateTransientKey($Sender->Request->Get('tkey'))) {
         throw PermissionException();
     }
     switch ($Args[0]) {
         case 'accept':
             $QnA = 'Accepted';
             break;
         case 'reject':
             $QnA = 'Rejected';
             break;
     }
     if (isset($QnA)) {
         $DiscussionSet = array('QnA' => $QnA);
         $CommentSet = array('QnA' => $QnA);
         if ($QnA == 'Accepted') {
             $CommentSet['DateAccepted'] = Gdn_Format::ToDateTime();
             $CommentSet['AcceptedUserID'] = Gdn::Session()->UserID;
             if (!$Discussion['DateAccepted']) {
                 $DiscussionSet['DateAccepted'] = Gdn_Format::ToDateTime();
                 $DiscussionSet['DateOfAnswer'] = $Comment['DateInserted'];
             }
         }
         // Update the comment.
         Gdn::SQL()->Put('Comment', $CommentSet, array('CommentID' => $Comment['CommentID']));
         // Update the discussion.
         if ($Discussion['QnA'] != $QnA && (!$Discussion['QnA'] || in_array($Discussion['QnA'], array('Unanswered', 'Answered', 'Rejected')))) {
             Gdn::SQL()->Put('Discussion', $DiscussionSet, array('DiscussionID' => $Comment['DiscussionID']));
         }
         // Determine QnA change
         if ($Comment['QnA'] != $QnA) {
             $Change = 0;
             switch ($QnA) {
                 case 'Rejected':
                     $Change = -1;
                     if ($Comment['QnA'] != 'Accepted') {
                         $Change = 0;
                     }
                     break;
                 case 'Accepted':
                     $Change = 1;
                     break;
                 default:
                     if ($Comment['QnA'] == 'Rejected') {
                         $Change = 0;
                     }
                     if ($Comment['QnA'] == 'Accepted') {
                         $Change = -1;
                     }
                     break;
             }
         }
         // Apply change effects
         if ($Change) {
             // Update the user
             $UserID = GetValue('InsertUserID', $Comment);
             $this->RecalculateUserQnA($UserID);
             // Update reactions
             if ($this->Reactions) {
                 include_once Gdn::Controller()->FetchViewLocation('reaction_functions', '', 'plugins/Reactions');
                 $Rm = new ReactionModel();
                 // If there's change, reactions will take care of it
                 $Rm->React('Comment', $Comment['CommentID'], 'AcceptAnswer');
             }
         }
         // Record the activity.
         if ($QnA == 'Accepted') {
             $Activity = array('ActivityType' => 'AnswerAccepted', 'NotifyUserID' => $Comment['InsertUserID'], 'HeadlineFormat' => '{ActivityUserID,You} accepted {NotifyUserID,your} answer.', 'RecordType' => 'Comment', 'RecordID' => $Comment['CommentID'], 'Route' => CommentUrl($Comment, '/'), 'Emailed' => ActivityModel::SENT_PENDING, 'Notified' => ActivityModel::SENT_PENDING);
             $ActivityModel = new ActivityModel();
             $ActivityModel->Save($Activity);
         }
     }
     Redirect("/discussion/comment/{$Comment['CommentID']}#Comment_{$Comment['CommentID']}");
 }
 /**
  * Delete an activity item.
  * 
  * @since 2.0.0
  * @access public
  * 
  * @param int $ActivityID Unique ID of item to delete.
  * @param string $TransientKey Verify intent.
  */
 public function Delete($ActivityID = '', $TransientKey = '')
 {
     $Session = Gdn::Session();
     if (!$Session->ValidateTransientKey($TransientKey)) {
         throw PermissionException();
     }
     if (!is_numeric($ActivityID)) {
         throw Gdn_UserException('Invalid activity ID');
     }
     $HasPermission = $Session->CheckPermission('Garden.Activity.Delete');
     if (!$HasPermission) {
         $Activity = $this->ActivityModel->GetID($ActivityID);
         if (!$Activity) {
             throw NotFoundException('Activity');
         }
         $HasPermission = $Activity['InsertUserID'] == $Session->UserID;
     }
     if (!$HasPermission) {
         throw PermissionException();
     }
     $this->ActivityModel->Delete($ActivityID);
     if ($this->_DeliveryType === DELIVERY_TYPE_ALL) {
         Redirect(GetIncomingValue('Target', $this->SelfUrl));
     }
     // Still here? Getting a 404.
     $this->ControllerName = 'Home';
     $this->View = 'FileNotFound';
     $this->Render();
 }
Esempio n. 23
0
 /**
  * 
  * @param PostController $Sender
  * @param type $RecordType
  * @param type $ID
  * @throws type
  */
 public function PostController_Twitter_Create($Sender, $RecordType, $ID)
 {
     if (!$this->SocialReactions()) {
         throw PermissionException();
     }
     //      if (!Gdn::Request()->IsPostBack())
     //         throw PermissionException('Javascript');
     $Row = GetRecord($RecordType, $ID);
     if ($Row) {
         // Grab the tweet message.
         switch (strtolower($RecordType)) {
             case 'discussion':
                 $Message = Gdn_Format::PlainText($Row['Name'], 'Text');
                 break;
             case 'comment':
             default:
                 $Message = Gdn_Format::PlainText($Row['Body'], $Row['Format']);
         }
         $Elips = '...';
         $Message = preg_replace('`\\s+`', ' ', $Message);
         //         if (function_exists('normalizer_is_normalized')) {
         //            // Slice the string to 119 characters (21 reservered for the url.
         //            if (!normalizer_is_normalized($Message))
         //               $Message = Normalizer::normalize($Message, Normalizer::FORM_D);
         //            $Elips = Normalizer::normalize($Elips, Normalizer::FORM_D);
         //         }
         $Max = 140;
         $LinkLen = 22;
         $Max -= $LinkLen;
         $Message = SliceParagraph($Message, $Max);
         if (strlen($Message) > $Max) {
             $Message = substr($Message, 0, $Max - strlen($Elips)) . $Elips;
         }
         //         echo $Message.strlen($Message);
         if ($this->AccessToken()) {
             Gdn::Controller()->SetData('Message', $Message);
             $Message .= ' ' . $Row['ShareUrl'];
             $R = $this->API('/statuses/update.json', array('status' => $Message), 'POST');
             $Sender->SetJson('R', $R);
             $Sender->InformMessage(T('Thanks for sharing!'));
         } else {
             $Get = array('text' => $Message, 'url' => $Row['ShareUrl']);
             $Url = "http://twitter.com/share?" . http_build_query($Get);
             Redirect($Url);
         }
     }
     $Sender->Render('Blank', 'Utility', 'Dashboard');
 }
Esempio n. 24
0
 public function PluginController_ReceiveUpload_Create($Sender)
 {
     $IncomingTransientKey = GetPostValue('TransientKey', Gdn::Session()->TransientKey());
     $IncomingUserID = GetPostValue('SessionUserID', Gdn::Session()->UserID);
     $Folder = GetPostValue('Folder');
     $User = Gdn::UserModel()->GetID($IncomingUserID);
     $UserTransientKey = GetValueR('Attributes.TransientKey', $User);
     if (!($IncomingTransientKey && $IncomingTransientKey == $UserTransientKey)) {
         throw PermissionException();
     }
     if (!self::HasPermission($User)) {
         throw PermissionException();
     }
     $Folder = trim($Folder, '/\\');
     if (substr($Folder, 0, 7) == 'uploads') {
         $Folder = trim(substr($Folder, 7), '/\\');
     }
     if (!$Folder || $Folder == 'false') {
         $Folder = 'i';
         $_POST['AddYear'] = True;
         $_POST['AddMonth'] = True;
     }
     if (GetPostValue('Debug')) {
         $DEBUG = array('$_POST' => $_POST, '$IncomingTransientKey' => $IncomingTransientKey, '$IncomingUserID' => $IncomingUserID, '$Sender->DeliveryType()' => $Sender->DeliveryType(), '$Sender->DeliveryMethod()' => $Sender->DeliveryMethod(), 'Uploadify' => GetPostValue('Uploadify'));
         file_put_contents(__DIR__ . '/post_' . rand(0, 99999) . '.txt', var_export($DEBUG, True));
     }
     //$TargetFolder = PATH_UPLOADS . DS . $Folder;
     $TargetFolder = 'uploads' . DS . $Folder;
     if (GetPostValue('AddYear')) {
         $TargetFolder .= DS . date('Y');
     }
     if (GetPostValue('AddMonth')) {
         $TargetFolder .= DS . date('m');
     }
     $Result = UploadFile($TargetFolder, 'File', array('WebTarget' => True));
     if (GetPostValue('Asset')) {
         $Result = Asset($Result);
     }
     if (GetPostValue('Uploadify')) {
         echo $Result;
         return;
     }
     $Sender->SetData('Result', $Result);
     $Sender->Render();
 }
   public function Update() {
      // Check for permission or flood control.
      // These settings are loaded/saved to the database because we don't want the config file storing non/config information.
      $Now = time();
      $LastTime = Gdn::Get('Garden.Update.LastTimestamp', 0);

      if ($LastTime + (60 * 60 * 24) > $Now) {
         // Check for flood control.
         $Count = Gdn::Get('Garden.Update.Count', 0) + 1;
         if ($Count > 5) {
            if (!Gdn::Session()->CheckPermission('Garden.Settings.Manage')) {
               // We are only allowing an update of 5 times every 24 hours.
               throw PermissionException();
            }
         }
      } else {
         $Count = 1;
      }
      Gdn::Set('Garden.Update.LastTimestamp', $Now);
      Gdn::Set('Garden.Update.Count', $Count);

      // Run the structure.
      $UpdateModel = new UpdateModel();
      
      $UpdateModel->RunStructure();
      $this->SetData('Success', TRUE);

      $this->MasterView = 'none';
      $this->Render();
   }
Esempio n. 26
0
 /**
  * Edit a discussion (wrapper for PostController::Discussion).
  *
  * Will throw an error if both params are blank.
  *
  * @since 2.0.0
  * @access public
  *
  * @param int $DiscussionID Unique ID of the discussion to edit.
  * @param int $DraftID Unique ID of draft discussion to edit.
  */
 public function EditDiscussion($DiscussionID = '', $DraftID = '')
 {
     if ($DraftID != '') {
         $this->Draft = $this->DraftModel->GetID($DraftID);
         $this->CategoryID = $this->Draft->CategoryID;
         // Verify this is their draft
         if (GetValue('InsertUserID', $this->Draft) != Gdn::Session()->UserID) {
             throw PermissionException();
         }
     } else {
         $this->SetData('Discussion', $this->DiscussionModel->GetID($DiscussionID), TRUE);
         $this->CategoryID = $this->Discussion->CategoryID;
     }
     if (C('Garden.ForceInputFormatter')) {
         $this->Form->RemoveFormValue('Format');
     }
     // Set view and render
     $this->View = 'Discussion';
     $this->Discussion($this->CategoryID);
 }
Esempio n. 27
0
 public function NotSpam($LogIDs)
 {
     $this->Permission('Garden.Moderation.Manage');
     if (!$this->Request->IsPostBack()) {
         throw PermissionException('Javascript');
     }
     $Logs = array();
     // Verify the appropriate users.
     $UserIDs = $this->Form->GetFormValue('UserID', array());
     if (!is_array($UserIDs)) {
         $UserIDs = array();
     }
     foreach ($UserIDs as $UserID) {
         Gdn::UserModel()->SetField($UserID, 'Verified', TRUE);
         $Logs = array_merge($Logs, $this->LogModel->GetWhere(array('Operation' => 'Spam', 'RecordUserID' => $UserID)));
     }
     // Grab the logs.
     $Logs = array_merge($Logs, $this->LogModel->GetIDs($LogIDs));
     //      try {
     foreach ($Logs as $Log) {
         $this->LogModel->Restore($Log);
     }
     //      } catch (Exception $Ex) {
     //         $this->Form->AddError($Ex->getMessage());
     //      }
     $this->LogModel->Recalculate();
     $this->SetData('Complete');
     $this->SetData('Count', count($Logs));
     $this->Render('Blank', 'Utility');
 }
 /**
  * Re-fetch a discussion's content based on its foreign url.
  * @param type $DiscussionID
  */
 public function RefetchPageInfo($DiscussionID)
 {
     // Make sure we are posting back.
     if (!$this->Request->IsPostBack()) {
         throw PermissionException('Javascript');
     }
     // Grab the discussion.
     $Discussion = $this->DiscussionModel->GetID($DiscussionID);
     if (!$Discussion) {
         throw NotFoundException('Discussion');
     }
     // Make sure the user has permission to edit this discussion.
     $this->Permission('Vanilla.Discussions.Edit', TRUE, 'Category', $Discussion->PermissionCategoryID);
     $ForeignUrl = GetValueR('Attributes.ForeignUrl', $Discussion);
     if (!$ForeignUrl) {
         throw new Gdn_UserException(T("This discussion isn't associated with a url."));
     }
     $Stub = $this->DiscussionModel->FetchPageInfo($ForeignUrl, TRUE);
     // Save the stub.
     $this->DiscussionModel->SetField($DiscussionID, (array) $Stub);
     // Send some of the stuff back.
     if (isset($Stub['Name'])) {
         $this->JsonTarget('.PageTitle h1', Gdn_Format::Text($Stub['Name']));
     }
     if (isset($Stub['Body'])) {
         $this->JsonTarget("#Discussion_{$DiscussionID} .Message", Gdn_Format::To($Stub['Body'], $Stub['Format']));
     }
     $this->InformMessage('The page was successfully fetched.');
     $this->Render('Blank', 'Utility', 'Dashboard');
 }
 public function Controller_Delete($Sender)
 {
     $Session = Gdn::Session();
     $DPModel = new DiscussionPollsModel();
     $DiscussionModel = new DiscussionModel();
     $Poll = $DPModel->Get($Sender->RequestArgs[1]);
     $Discussion = $DiscussionModel->GetID($Poll->DiscussionID);
     $PollOwnerID = $Discussion->InsertUserID;
     if ($Session->CheckPermission('Plugins.DiscussionPolls.Manage') || $PollOwnerID == $Session->UserID) {
         $DPModel = new DiscussionPollsModel();
         $DPModel->Delete($Sender->RequestArgs[1]);
         $Result = 'Removed poll with id ' . $Sender->RequestArgs[1];
         if ($Sender->DeliveryType() == DELIVERY_TYPE_VIEW) {
             $Data = array('html' => $Result);
             echo json_encode($Data);
         } else {
             $Sender->SetData('PollString', $Result);
             $Sender->Render($this->ThemView('poll'));
         }
     } else {
         // throw permission exception
         throw PermissionException();
     }
 }
Esempio n. 30
0
 /**
  * Handle discussion option menu Resolve action.
  *
  * @throws Exception Throws an exception when the discussion is not found, or the request is not a POST
  * @return void
  */
 public function discussionController_resolve_create($sender, $args)
 {
     $sender->permission('Plugins.Resolved.Manage');
     $discussionID = $sender->Request->get('discussionid');
     $resolve = $sender->Request->get('resolve');
     // Make sure we are posting back.
     if (!$sender->Request->isPostBack()) {
         throw PermissionException('Javascript');
     }
     $discussion = $sender->DiscussionModel->getID($discussionID);
     if (!$discussion) {
         throw NotFoundException('Discussion');
     }
     // Resolve the discussion.
     $this->resolve($discussion, $resolve);
     $sender->sendOptions($discussion);
     if (!$resolve) {
         require_once $sender->fetchViewLocation('helper_functions', 'Discussions');
         $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID} .Meta-Discussion", '<span class="Tag Tag-Unresolved" title="Unresolved">' . T('Unresolved') . '</span>', 'Prepend');
         $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID}", 'Unresolved', 'AddClass');
     } else {
         $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID} .Tag-Unresolved", null, 'Remove');
         $sender->jsonTarget(".Section-DiscussionList #Discussion_{$discussionID}", 'Unresolved', 'RemoveClass');
     }
     $sender->jsonTarget("#Discussion_{$discussionID}", null, 'Highlight');
     $sender->jsonTarget(".Discussion #Item_0", null, 'Highlight');
     $sender->render('Blank', 'Utility', 'Dashboard');
 }