save() public méthode

It uses the assigned model to save the sent form fields. If saving fails, it populates $this->_ValidationResults with validation errors & related fields.
public save ( ) : unknown
Résultat unknown
 /**
  * Upload new version of an existing addon.
  *
  * @param int $AddonID Addon ID specified.
  * @throws Exception Addon not Found.
  */
 public function newVersion($AddonID = '')
 {
     $Session = Gdn::session();
     $Addon = $this->AddonModel->getID($AddonID);
     if (!$Addon) {
         throw notFoundException('Addon');
     }
     if ($Addon['InsertUserID'] != $Session->UserID) {
         $this->permission('Addons.Addon.Manage');
     }
     $this->addModule('AddonHelpModule');
     $this->Form->setModel($this->AddonModel);
     $this->Form->addHidden('AddonID', $AddonID);
     if ($this->Form->authenticatedPostBack()) {
         $AnalyzedAddon = $this->handleAddonUpload();
         if ($Addon['Description2'] != $AnalyzedAddon['Description2'] && $Addon['Description2'] != '') {
             $this->Form->setFormValue('Description2', $Addon['Description2']);
         }
         $AnalyzedAddon['AddonID'] = $AddonID;
         $this->Form->setFormValue('AddonID', $AddonID);
         // If there were no errors, save the addon version.
         if ($this->Form->errorCount() == 0) {
             $NewVersionID = $this->Form->save(false);
             if ($NewVersionID) {
                 $this->setData('Addon', $AnalyzedAddon);
                 $Addon = $this->AddonModel->getID($AddonID);
                 $this->setData('Url', url('/addon/' . AddonModel::slug($Addon, true), true));
                 if ($this->deliveryType() == DELIVERY_TYPE_ALL) {
                     $this->RedirectUrl = $this->data('Url');
                 }
             }
         }
     }
     $this->render();
 }
 /**
  * Configuration of registration settings.
  *
  * Events: BeforeRegistrationUpdate
  *
  * @since 2.0.0
  * @access public
  * @param string $RedirectUrl Where to send user after registration.
  */
 public function registration($RedirectUrl = '')
 {
     $this->permission('Garden.Settings.Manage');
     $this->addSideMenu('dashboard/settings/registration');
     $this->addJsFile('registration.js');
     $this->title(t('Registration'));
     // Load roles with sign-in permission
     $RoleModel = new RoleModel();
     $this->RoleData = $RoleModel->getByPermission('Garden.SignIn.Allow');
     $this->setData('_Roles', array_column($this->RoleData->resultArray(), 'Name', 'RoleID'));
     // Get currently selected InvitationOptions
     $this->ExistingRoleInvitations = Gdn::config('Garden.Registration.InviteRoles');
     if (is_array($this->ExistingRoleInvitations) === false) {
         $this->ExistingRoleInvitations = array();
     }
     // Get the currently selected Expiration Length
     $this->InviteExpiration = Gdn::config('Garden.Registration.InviteExpiration', '');
     // Registration methods.
     $this->RegistrationMethods = array('Basic' => "New users fill out a simple form and are granted access immediately.", 'Approval' => "New users are reviewed and approved by an administrator (that's you!).", 'Invitation' => "Existing members send invitations to new members.", 'Connect' => "New users are only registered through SSO plugins.");
     // Options for how many invitations a role can send out per month.
     $this->InvitationOptions = array('0' => t('None'), '1' => '1', '2' => '2', '5' => '5', '-1' => t('Unlimited'));
     // Options for when invitations should expire.
     $this->InviteExpirationOptions = array('1 week' => t('1 week after being sent'), '2 weeks' => t('2 weeks after being sent'), '1 month' => t('1 month after being sent'), 'FALSE' => t('never'));
     // Replace 'Captcha' with 'Basic' if needed
     if (c('Garden.Registration.Method') == 'Captcha') {
         saveToConfig('Garden.Registration.Method', 'Basic');
     }
     // Create a model to save configuration settings
     $Validation = new Gdn_Validation();
     $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
     $registrationOptions = array('Garden.Registration.Method' => 'Basic', 'Garden.Registration.InviteExpiration', 'Garden.Registration.ConfirmEmail');
     $ConfigurationModel->setField($registrationOptions);
     $this->EventArguments['Validation'] =& $Validation;
     $this->EventArguments['Configuration'] =& $ConfigurationModel;
     $this->fireEvent('Registration');
     // Set the model on the forms.
     $this->Form->setModel($ConfigurationModel);
     if ($this->Form->authenticatedPostBack() === false) {
         $this->Form->setData($ConfigurationModel->Data);
     } else {
         // Define some validation rules for the fields being saved
         $ConfigurationModel->Validation->applyRule('Garden.Registration.Method', 'Required');
         // Define the Garden.Registration.RoleInvitations setting based on the postback values
         $InvitationRoleIDs = $this->Form->getValue('InvitationRoleID');
         $InvitationCounts = $this->Form->getValue('InvitationCount');
         $this->ExistingRoleInvitations = arrayCombine($InvitationRoleIDs, $InvitationCounts);
         $ConfigurationModel->forceSetting('Garden.Registration.InviteRoles', $this->ExistingRoleInvitations);
         // Event hook
         $this->EventArguments['ConfigurationModel'] =& $ConfigurationModel;
         $this->fireEvent('BeforeRegistrationUpdate');
         // Save!
         if ($this->Form->save() !== false) {
             $this->informMessage(t("Your settings have been saved."));
             if ($RedirectUrl != '') {
                 $this->RedirectUrl = $RedirectUrl;
             }
         }
     }
     $this->render();
 }
 /**
  * Move a category to a different parent.
  *
  * @param int $categoryID Unique ID for the category to move.
  * @throws Exception if category is not found.
  */
 public function moveCategory($categoryID)
 {
     // Check permission
     $this->permission(['Garden.Community.Manage', 'Garden.Settings.Manage'], false);
     $category = CategoryModel::categories($categoryID);
     if (!$category) {
         throw notFoundException();
     }
     $this->Form->setModel($this->CategoryModel);
     $this->Form->addHidden('CategoryID', $categoryID);
     $this->setData('Category', $category);
     $parentCategories = CategoryModel::getAncestors($categoryID);
     array_pop($parentCategories);
     if (!empty($parentCategories)) {
         $this->setData('ParentCategories', array_column($parentCategories, 'Name', 'CategoryID'));
     }
     if ($this->Form->authenticatedPostBack()) {
         // Verify we're only attempting to save specific values.
         $this->Form->formValues(['CategoryID' => $this->Form->getValue('CategoryID'), 'ParentCategoryID' => $this->Form->getValue('ParentCategoryID')]);
         $this->Form->save();
     } else {
         $this->Form->setData($category);
     }
     $this->render();
 }
 /**
  * Enabling and disabling categories from list.
  *
  * @since 2.0.0
  * @access public
  */
 public function manageCategories()
 {
     // Check permission
     $this->permission('Garden.Community.Manage');
     $this->addSideMenu('vanilla/settings/managecategories');
     $this->addJsFile('categories.js');
     $this->addJsFile('jquery.alphanumeric.js');
     // This now works on latest jQuery version 1.10.2
     //
     // Jan29, 2014, upgraded jQuery UI to 1.10.3 from 1.8.11
     $this->addJsFile('nestedSortable/jquery-ui.min.js');
     // Newer nestedSortable, but does not work.
     //$this->addJsFile('js/library/nestedSortable/jquery.mjs.nestedSortable.js');
     // old jquery-ui
     //$this->addJsFile('js/library/nestedSortable.1.3.4/jquery-ui-1.8.11.custom.min.js');
     $this->addJsFile('nestedSortable.1.3.4/jquery.ui.nestedSortable.js');
     $this->title(t('Categories'));
     // Get category data
     $CategoryData = $this->CategoryModel->getAll('TreeLeft');
     // Set CanDelete per-category so we can override later if we want.
     $canDelete = checkPermission('Garden.Settings.Manage');
     array_walk($CategoryData->result(), function (&$value) use($canDelete) {
         setvalr('CanDelete', $value, $canDelete);
     });
     $this->setData('CategoryData', $CategoryData, true);
     // Setup & save forms
     $Validation = new Gdn_Validation();
     $ConfigurationModel = new Gdn_ConfigurationModel($Validation);
     $ConfigurationModel->setField(array('Vanilla.Categories.MaxDisplayDepth', 'Vanilla.Categories.DoHeadings', 'Vanilla.Categories.HideModule'));
     // Set the model on the form.
     $this->Form->setModel($ConfigurationModel);
     // Define MaxDepthOptions
     $DepthData = array();
     $DepthData['2'] = sprintf(t('more than %s deep'), plural(1, '%s level', '%s levels'));
     $DepthData['3'] = sprintf(t('more than %s deep'), plural(2, '%s level', '%s levels'));
     $DepthData['4'] = sprintf(t('more than %s deep'), plural(3, '%s level', '%s levels'));
     $DepthData['0'] = t('never');
     $this->setData('MaxDepthData', $DepthData);
     // If seeing the form for the first time...
     if ($this->Form->authenticatedPostBack() === false) {
         // Apply the config settings to the form.
         $this->Form->setData($ConfigurationModel->Data);
     } else {
         if ($this->Form->save() !== false) {
             $this->informMessage(t("Your settings have been saved."));
         }
     }
     // Render default view
     $this->render();
 }
 /**
  * Add a message to a conversation.
  *
  * @since 2.0.0
  * @access public
  *
  * @param int $ConversationID Unique ID of the conversation.
  */
 public function addMessage($ConversationID = '')
 {
     $this->Form->setModel($this->ConversationMessageModel);
     if (is_numeric($ConversationID) && $ConversationID > 0) {
         $this->Form->addHidden('ConversationID', $ConversationID);
     }
     if ($this->Form->authenticatedPostBack()) {
         $ConversationID = $this->Form->getFormValue('ConversationID', '');
         // Make sure the user posting to the conversation is actually
         // a member of it, or is allowed, like an admin.
         if (!checkPermission('Garden.Moderation.Manage')) {
             $UserID = Gdn::session()->UserID;
             $ValidConversationMember = $this->ConversationModel->validConversationMember($ConversationID, $UserID);
             if (!$ValidConversationMember) {
                 throw permissionException();
             }
         }
         $Conversation = $this->ConversationModel->getID($ConversationID, Gdn::session()->UserID);
         $this->EventArguments['Conversation'] = $Conversation;
         $this->EventArguments['ConversationID'] = $ConversationID;
         $this->fireEvent('BeforeAddMessage');
         $NewMessageID = $this->Form->save();
         if ($NewMessageID) {
             if ($this->deliveryType() == DELIVERY_TYPE_ALL) {
                 redirect('messages/' . $ConversationID . '/#' . $NewMessageID, 302);
             }
             $this->setJson('MessageID', $NewMessageID);
             $this->EventArguments['MessageID'] = $NewMessageID;
             $this->fireEvent('AfterMessageSave');
             // If this was not a full-page delivery type, return the partial response
             // Load all new messages that the user hasn't seen yet (including theirs)
             $LastMessageID = $this->Form->getFormValue('LastMessageID');
             if (!is_numeric($LastMessageID)) {
                 $LastMessageID = $NewMessageID - 1;
             }
             $Session = Gdn::session();
             $MessageData = $this->ConversationMessageModel->getNew($ConversationID, $LastMessageID);
             $this->Conversation = $Conversation;
             $this->MessageData = $MessageData;
             $this->setData('Messages', $MessageData);
             $this->View = 'messages';
         } else {
             // Handle ajax based errors...
             if ($this->deliveryType() != DELIVERY_TYPE_ALL) {
                 $this->errorMessage($this->Form->errors());
             }
         }
     }
     $this->render();
 }
 /**
  * Set new password for current user.
  *
  * @since 2.0.0
  * @access public
  */
 public function password()
 {
     $this->permission('Garden.SignIn.Allow');
     // Don't allow password editing if using SSO Connect ONLY.
     // This is for security. We encountered the case where a customer charges
     // for membership using their external application and use SSO to let
     // their customers into Vanilla. If you allow those people to change their
     // password in Vanilla, they will then be able to log into Vanilla using
     // Vanilla's login form regardless of the state of their membership in the
     // external app.
     if (c('Garden.Registration.Method') == 'Connect') {
         Gdn::dispatcher()->dispatch('DefaultPermission');
         exit;
     }
     Gdn::userModel()->addPasswordStrength($this);
     // Get user data and set up form
     $this->getUserInfo();
     $this->Form->setModel($this->UserModel);
     $this->addDefinition('Username', $this->User->Name);
     if ($this->Form->authenticatedPostBack() === true) {
         $this->Form->setFormValue('UserID', $this->User->UserID);
         $this->UserModel->defineSchema();
         //         $this->UserModel->Validation->AddValidationField('OldPassword', $this->Form->formValues());
         // No password may have been set if they have only signed in with a connect plugin
         if (!$this->User->HashMethod || $this->User->HashMethod == "Vanilla") {
             $this->UserModel->Validation->applyRule('OldPassword', 'Required');
             $this->UserModel->Validation->applyRule('OldPassword', 'OldPassword', 'Your old password was incorrect.');
         }
         $this->UserModel->Validation->applyRule('Password', 'Required');
         $this->UserModel->Validation->applyRule('Password', 'Strength');
         $this->UserModel->Validation->applyRule('Password', 'Match');
         if ($this->Form->save()) {
             $this->informMessage(sprite('Check', 'InformSprite') . t('Your password has been changed.'), 'Dismissable AutoDismiss HasSprite');
             $this->Form->clearInputs();
             Logger::event('password_change', Logger::INFO, '{InsertName} changed password.');
         } else {
             Logger::event('password_change_failure', Logger::INFO, '{InsertName} failed to change password.', array('Error' => $this->Form->errorString()));
         }
     }
     $this->title(t('Change My Password'));
     $this->_setBreadcrumbs(t('Change My Password'), '/profile/password');
     $this->render();
 }
 /**
  * Edit a user account.
  *
  * @since 2.0.0
  * @access public
  * @param int $UserID Unique ID.
  */
 public function edit($UserID)
 {
     $this->permission('Garden.Users.Edit');
     // Page setup
     $this->addJsFile('user.js');
     $this->title(t('Edit User'));
     $this->addSideMenu('dashboard/user');
     // Only admins can reassign roles
     $RoleModel = new RoleModel();
     $AllRoles = $RoleModel->getArray();
     $RoleData = $RoleModel->getAssignable();
     $UserModel = new UserModel();
     $User = $UserModel->getID($UserID, DATASET_TYPE_ARRAY);
     // Determine if username can be edited
     $CanEditUsername = (bool) c("Garden.Profile.EditUsernames") || Gdn::session()->checkPermission('Garden.Users.Edit');
     $this->setData('_CanEditUsername', $CanEditUsername);
     // Determine if emails can be edited
     $CanEditEmail = Gdn::session()->checkPermission('Garden.Users.Edit');
     $this->setData('_CanEditEmail', $CanEditEmail);
     // Decide if they have ability to confirm users
     $Confirmed = (bool) valr('Confirmed', $User);
     $CanConfirmEmail = UserModel::RequireConfirmEmail() && Gdn::session()->checkPermission('Garden.Users.Edit');
     $this->setData('_CanConfirmEmail', $CanConfirmEmail);
     $this->setData('_EmailConfirmed', $Confirmed);
     $User['ConfirmEmail'] = (int) $Confirmed;
     // Determine whether user being edited is privileged (can escalate permissions)
     $UserModel = new UserModel();
     $EditingPrivilegedUser = $UserModel->checkPermission($User, 'Garden.Settings.Manage');
     // Determine our password reset options
     // Anyone with user editing my force reset over email
     $this->ResetOptions = array(0 => t('Keep current password.'), 'Auto' => t('Force user to reset their password and send email notification.'));
     // Only admins may manually reset passwords for other admins
     if (checkPermission('Garden.Settings.Manage') || !$EditingPrivilegedUser) {
         $this->ResetOptions['Manual'] = t('Manually set user password. No email notification.');
     }
     // Set the model on the form.
     $this->Form->setModel($UserModel);
     // Make sure the form knows which item we are editing.
     $this->Form->addHidden('UserID', $UserID);
     try {
         $AllowEditing = true;
         $this->EventArguments['AllowEditing'] =& $AllowEditing;
         $this->EventArguments['TargetUser'] =& $User;
         // These are all the 'effective' roles for this edit action. This list can
         // be trimmed down from the real list to allow subsets of roles to be
         // edited.
         $this->EventArguments['RoleData'] =& $RoleData;
         $UserRoleData = $UserModel->getRoles($UserID)->resultArray();
         $RoleIDs = array_column($UserRoleData, 'RoleID');
         $RoleNames = array_column($UserRoleData, 'Name');
         $UserRoleData = arrayCombine($RoleIDs, $RoleNames);
         $this->EventArguments['UserRoleData'] =& $UserRoleData;
         $this->fireEvent("BeforeUserEdit");
         $this->setData('AllowEditing', $AllowEditing);
         $this->Form->setData($User);
         if ($this->Form->authenticatedPostBack()) {
             if (!$CanEditUsername) {
                 $this->Form->setFormValue("Name", $User['Name']);
             }
             // Allow mods to confirm/unconfirm emails
             $this->Form->removeFormValue('Confirmed');
             $Confirmation = $this->Form->getFormValue('ConfirmEmail', null);
             $Confirmation = !is_null($Confirmation) ? (bool) $Confirmation : null;
             if ($CanConfirmEmail && is_bool($Confirmation)) {
                 $this->Form->setFormValue('Confirmed', (int) $Confirmation);
             }
             $ResetPassword = $this->Form->getValue('ResetPassword', false);
             // If we're an admin or this isn't a privileged user, allow manual setting of password
             $AllowManualReset = checkPermission('Garden.Settings.Manage') || !$EditingPrivilegedUser;
             if ($ResetPassword == 'Manual' && $AllowManualReset) {
                 // If a new password was specified, add it to the form's collection
                 $NewPassword = $this->Form->getValue('NewPassword', '');
                 $this->Form->setFormValue('Password', $NewPassword);
             }
             // Role changes
             // These are the new roles the editing user wishes to apply to the target
             // user, adjusted for his ability to affect those roles
             $RequestedRoles = $this->Form->getFormValue('RoleID');
             if (!is_array($RequestedRoles)) {
                 $RequestedRoles = array();
             }
             $RequestedRoles = array_flip($RequestedRoles);
             $UserNewRoles = array_intersect_key($RoleData, $RequestedRoles);
             // These roles will stay turned on regardless of the form submission contents
             // because the editing user does not have permission to modify them
             $ImmutableRoles = array_diff_key($AllRoles, $RoleData);
             $UserImmutableRoles = array_intersect_key($ImmutableRoles, $UserRoleData);
             // Apply immutable roles
             foreach ($UserImmutableRoles as $IMRoleID => $IMRoleName) {
                 $UserNewRoles[$IMRoleID] = $IMRoleName;
             }
             // Put the data back into the forum object as if the user had submitted
             // this themselves
             $this->Form->setFormValue('RoleID', array_keys($UserNewRoles));
             if ($this->Form->save(array('SaveRoles' => true)) !== false) {
                 if ($this->Form->getValue('ResetPassword', '') == 'Auto') {
                     $UserModel->PasswordRequest($User['Email']);
                     $UserModel->setField($UserID, 'HashMethod', 'Reset');
                 }
                 $this->informMessage(t('Your changes have been saved.'));
             }
             $UserRoleData = $UserNewRoles;
         }
     } catch (Exception $Ex) {
         $this->Form->addError($Ex);
     }
     $this->setData('User', $User);
     $this->setData('Roles', $RoleData);
     $this->setData('UserRoles', $UserRoleData);
     $this->render();
 }
Exemple #8
0
 /**
  * Create a controller to deal with plugin settings in dashboard.
  *
  * @param Gdn_Controller $sender.
  * @param Gdn_Controller $args.
  */
 public function settingsEndpoint($sender, $args)
 {
     $sender->permission('Garden.Settings.Manage');
     $model = new Gdn_AuthenticationProviderModel();
     /* @var Gdn_Form $form */
     $form = new Gdn_Form();
     $form->setModel($model);
     $sender->Form = $form;
     if (!$form->AuthenticatedPostBack()) {
         $provider = $this->provider();
         $form->setData($provider);
     } else {
         $form->setFormValue('AuthenticationKey', $this->getProviderKey());
         $sender->Form->validateRule('AssociationKey', 'ValidateRequired', 'You must provide a unique AccountID.');
         $sender->Form->validateRule('AssociationSecret', 'ValidateRequired', 'You must provide a Secret');
         $sender->Form->validateRule('AuthorizeUrl', 'isUrl', 'You must provide a complete URL in the Authorize Url field.');
         $sender->Form->validateRule('TokenUrl', 'isUrl', 'You must provide a complete URL in the Token Url field.');
         // To satisfy the AuthenticationProviderModel, create a BaseUrl.
         $baseUrlParts = parse_url($form->getValue('AuthorizeUrl'));
         $baseUrl = val('scheme', $baseUrlParts) && val('host', $baseUrlParts) ? val('scheme', $baseUrlParts) . '://' . val('host', $baseUrlParts) : null;
         if ($baseUrl) {
             $form->setFormValue('BaseUrl', $baseUrl);
             $form->setFormValue('SignInUrl', $baseUrl);
             // kludge for default provider
         }
         if ($form->save()) {
             $sender->informMessage(t('Saved'));
         }
     }
     // Set up the form.
     $formFields = ['AssociationKey' => ['LabelCode' => 'Client ID', 'Description' => 'Enter the unique ID of the authentication application.'], 'AssociationSecret' => ['LabelCode' => 'Secret', 'Description' => 'Enter the secret provided by the authentication provider.'], 'AuthorizeUrl' => ['LabelCode' => 'Authorize Url', 'Description' => 'Enter the endpoint to be appended to the base domain to retrieve the authorization token for a user.'], 'TokenUrl' => ['LabelCode' => 'Token Url', 'Description' => 'Enter the endpoint to be appended to the base domain to retrieve the authorization token for a user.'], 'ProfileUrl' => ['LabelCode' => 'Profile Url', 'Description' => 'Enter the endpoint to be appended to the base domain to retrieve a user\'s profile.']];
     $formFields = $formFields + $this->getSettingsFormFields();
     $formFields['IsDefault'] = ['LabelCode' => 'Make this connection your default signin method.', 'Control' => 'checkbox'];
     $sender->setData('_Form', $formFields);
     $sender->addSideMenu();
     if (!$sender->data('Title')) {
         $sender->setData('Title', sprintf(T('%s Settings'), 'Oauth2 SSO'));
     }
     $view = $this->settingsView ? $this->settingsView : 'plugins/oauth2';
     // Create send the possible redirect URLs that will be required by Oculus and display them in the dashboard.
     // Use Gdn::Request instead of convience function so that we can return http and https.
     $redirectUrls = Gdn::request()->url('/entry/' . $this->getProviderKey(), true, true);
     $sender->setData('redirectUrls', $redirectUrls);
     $sender->render('settings', '', 'plugins/' . $view);
 }
 /**
  * Set user's photo (avatar).
  *
  * @since 2.0.0
  * @access public
  *
  * @param mixed $userReference Unique identifier, possible username or ID.
  * @param string $username The username.
  * @param string $userID The user's ID.
  *
  * @throws Exception
  * @throws Gdn_UserException
  */
 public function picture($userReference = '', $username = '', $userID = '')
 {
     $this->addJsFile('profile.js');
     if (!$this->CanEditPhotos) {
         throw forbiddenException('@Editing user photos has been disabled.');
     }
     // Permission checks
     $this->permission(array('Garden.Profiles.Edit', 'Moderation.Profiles.Edit', 'Garden.ProfilePicture.Edit'), false);
     $session = Gdn::session();
     if (!$session->isValid()) {
         $this->Form->addError('You must be authenticated in order to use this form.');
     }
     // Check ability to manipulate image
     if (function_exists('gd_info')) {
         $gdInfo = gd_info();
         $gdVersion = preg_replace('/[a-z ()]+/i', '', $gdInfo['GD Version']);
         if ($gdVersion < 2) {
             throw new Exception(sprintf(t("This installation of GD is too old (v%s). Vanilla requires at least version 2 or compatible."), $gdVersion));
         }
     } else {
         throw new Exception(sprintf(t("Unable to detect PHP GD installed on this system. Vanilla requires GD version 2 or better.")));
     }
     // Get user data & prep form.
     if ($this->Form->authenticatedPostBack() && $this->Form->getFormValue('UserID')) {
         $userID = $this->Form->getFormValue('UserID');
     }
     $this->getUserInfo($userReference, $username, $userID, true);
     $validation = new Gdn_Validation();
     $configurationModel = new Gdn_ConfigurationModel($validation);
     $this->Form->setModel($configurationModel);
     $avatar = $this->User->Photo;
     if ($avatar === null) {
         $avatar = UserModel::getDefaultAvatarUrl();
     }
     $source = '';
     $crop = null;
     if ($this->isUploadedAvatar($avatar)) {
         // Get the image source so we can manipulate it in the crop module.
         $upload = new Gdn_UploadImage();
         $thumbnailSize = c('Garden.Thumbnail.Size', 40);
         $basename = changeBasename($avatar, "p%s");
         $source = $upload->copyLocal($basename);
         // Set up cropping.
         $crop = new CropImageModule($this, $this->Form, $thumbnailSize, $thumbnailSize, $source);
         $crop->setExistingCropUrl(Gdn_UploadImage::url(changeBasename($avatar, "n%s")));
         $crop->setSourceImageUrl(Gdn_UploadImage::url(changeBasename($avatar, "p%s")));
         $this->setData('crop', $crop);
     } else {
         $this->setData('avatar', $avatar);
     }
     if (!$this->Form->authenticatedPostBack()) {
         $this->Form->setData($configurationModel->Data);
     } else {
         if ($this->Form->save() !== false) {
             $upload = new Gdn_UploadImage();
             $newAvatar = false;
             if ($tmpAvatar = $upload->validateUpload('Avatar', false)) {
                 // New upload
                 $thumbOptions = array('Crop' => true, 'SaveGif' => c('Garden.Thumbnail.SaveGif'));
                 $newAvatar = $this->saveAvatars($tmpAvatar, $thumbOptions, $upload);
             } else {
                 if ($avatar && $crop && $crop->isCropped()) {
                     // New thumbnail
                     $tmpAvatar = $source;
                     $thumbOptions = array('Crop' => true, 'SourceX' => $crop->getCropXValue(), 'SourceY' => $crop->getCropYValue(), 'SourceWidth' => $crop->getCropWidth(), 'SourceHeight' => $crop->getCropHeight());
                     $newAvatar = $this->saveAvatars($tmpAvatar, $thumbOptions);
                 }
             }
             if ($this->Form->errorCount() == 0) {
                 if ($newAvatar !== false) {
                     $thumbnailSize = c('Garden.Thumbnail.Size', 40);
                     // Update crop properties.
                     $basename = changeBasename($newAvatar, "p%s");
                     $source = $upload->copyLocal($basename);
                     $crop = new CropImageModule($this, $this->Form, $thumbnailSize, $thumbnailSize, $source);
                     $crop->setSize($thumbnailSize, $thumbnailSize);
                     $crop->setExistingCropUrl(Gdn_UploadImage::url(changeBasename($newAvatar, "n%s")));
                     $crop->setSourceImageUrl(Gdn_UploadImage::url(changeBasename($newAvatar, "p%s")));
                     $this->setData('crop', $crop);
                 }
             }
             if ($this->deliveryType() === DELIVERY_TYPE_VIEW) {
                 $this->jsonTarget('', '', 'Refresh');
                 $this->RedirectUrl = userUrl($this->User);
             }
             $this->informMessage(t("Your settings have been saved."));
         }
     }
     if (val('SideMenuModule', val('Panel', val('Assets', $this)))) {
         /** @var SideMenuModule $sidemenu */
         $sidemenu = $this->Assets['Panel']['SideMenuModule'];
         $sidemenu->highlightRoute('/profile/picture');
     }
     $this->title(t('Change Picture'));
     $this->_setBreadcrumbs(t('Change My Picture'), userUrl($this->User, '', 'picture'));
     $this->render('picture', 'profile', 'dashboard');
 }
 /**
  *
  *
  * @param $Sender
  * @param bool|false $PocketID
  * @return mixed
  * @throws Gdn_UserException
  */
 protected function _addEdit($Sender, $PocketID = false)
 {
     $Form = new Gdn_Form();
     $PocketModel = new Gdn_Model('Pocket');
     $Form->setModel($PocketModel);
     $Sender->ConditionModule = new ConditionModule($Sender);
     $Sender->Form = $Form;
     if ($Form->authenticatedPostBack()) {
         // Save the pocket.
         if ($PocketID !== false) {
             $Form->setFormValue('PocketID', $PocketID);
         }
         // Convert the form data into a format digestable by the database.
         $Repeat = $Form->getFormValue('RepeatType');
         switch ($Repeat) {
             case Pocket::REPEAT_EVERY:
                 $PocketModel->Validation->applyRule('EveryFrequency', 'Integer');
                 $PocketModel->Validation->applyRule('EveryBegin', 'Integer');
                 $Frequency = $Form->getFormValue('EveryFrequency', 1);
                 if (!$Frequency || !validateInteger($Frequency) || $Frequency < 1) {
                     $Frequency = 1;
                 }
                 $Repeat .= ' ' . $Frequency;
                 if ($Form->getFormValue('EveryBegin', 1) > 1) {
                     $Repeat .= ',' . $Form->getFormValue('EveryBegin');
                 }
                 break;
             case Pocket::REPEAT_INDEX:
                 $PocketModel->Validation->addRule('IntegerArray', 'function:ValidateIntegerArray');
                 $PocketModel->Validation->applyRule('Indexes', 'IntegerArray');
                 $Indexes = explode(',', $Form->getFormValue('Indexes', ''));
                 $Indexes = array_map('trim', $Indexes);
                 $Repeat .= ' ' . implode(',', $Indexes);
                 break;
             default:
                 break;
         }
         $Form->setFormValue('Repeat', $Repeat);
         $Form->setFormValue('Sort', 0);
         $Form->setFormValue('Format', 'Raw');
         $Condition = Gdn_Condition::toString($Sender->ConditionModule->conditions(true));
         $Form->setFormValue('Condition', $Condition);
         if ($Form->getFormValue('Ad', 0)) {
             $Form->setFormValue('Type', Pocket::TYPE_AD);
         } else {
             $Form->setFormValue('Type', Pocket::TYPE_DEFAULT);
         }
         $Saved = $Form->save();
         if ($Saved) {
             $Sender->StatusMessage = t('Your changes have been saved.');
             $Sender->RedirectUrl = url('settings/pockets');
         }
     } else {
         if ($PocketID !== false) {
             // Load the pocket.
             $Pocket = $PocketModel->getWhere(array('PocketID' => $PocketID))->firstRow(DATASET_TYPE_ARRAY);
             if (!$Pocket) {
                 return Gdn::dispatcher()->dispatch('Default404');
             }
             // Convert some of the pocket data into a format digestable by the form.
             list($RepeatType, $RepeatFrequency) = Pocket::parseRepeat($Pocket['Repeat']);
             $Pocket['RepeatType'] = $RepeatType;
             $Pocket['EveryFrequency'] = GetValue(0, $RepeatFrequency, 1);
             $Pocket['EveryBegin'] = GetValue(1, $RepeatFrequency, 1);
             $Pocket['Indexes'] = implode(',', $RepeatFrequency);
             $Pocket['Ad'] = $Pocket['Type'] == Pocket::TYPE_AD;
             $Sender->ConditionModule->conditions(Gdn_Condition::fromString($Pocket['Condition']));
             $Form->setData($Pocket);
         } else {
             // Default the repeat.
             $Form->setFormValue('RepeatType', Pocket::REPEAT_ONCE);
         }
     }
     $Sender->Form = $Form;
     $Sender->setData('Locations', $this->Locations);
     $Sender->setData('LocationsArray', $this->getLocationsArray());
     $Sender->setData('Pages', array('' => '(' . T('All') . ')', 'activity' => 'activity', 'comments' => 'comments', 'dashboard' => 'dashboard', 'discussions' => 'discussions', 'inbox' => 'inbox', 'profile' => 'profile'));
     return $Sender->render('AddEdit', '', 'plugins/Pockets');
 }