Пример #1
0
 /**
  * Generic save procedure.
  *
  * $Settings controls certain save functionality
  *
  *  SaveRoles - Save 'RoleID' field as user's roles. Default false.
  *  HashPassword - Hash the provided password on update. Default true.
  *  FixUnique - Try to resolve conflicts with unique constraints on Name and Email. Default false.
  *  ValidateEmail - Make sure the provided email addresses is formattted properly. Default true.
  *  NoConfirmEmail - Disable email confirmation. Default false.
  *
  */
 public function save($FormPostValues, $Settings = false)
 {
     // See if the user's related roles should be saved or not.
     $SaveRoles = val('SaveRoles', $Settings);
     // Define the primary key in this model's table.
     $this->defineSchema();
     // Custom Rule: This will make sure that at least one role was selected if saving roles for this user.
     if ($SaveRoles) {
         $this->Validation->addRule('OneOrMoreArrayItemRequired', 'function:ValidateOneOrMoreArrayItemRequired');
         // $this->Validation->AddValidationField('RoleID', $FormPostValues);
         $this->Validation->applyRule('RoleID', 'OneOrMoreArrayItemRequired');
     } else {
         $this->Validation->unapplyRule('RoleID', 'OneOrMoreArrayItemRequired');
     }
     // Make sure that checkbox vals are saved as the appropriate value
     if (array_key_exists('ShowEmail', $FormPostValues)) {
         $FormPostValues['ShowEmail'] = forceBool($FormPostValues['ShowEmail'], '0', '1', '0');
     }
     if (array_key_exists('Banned', $FormPostValues)) {
         $FormPostValues['Banned'] = forceBool($FormPostValues['Banned'], '0', '1', '0');
     }
     if (array_key_exists('Confirmed', $FormPostValues)) {
         $FormPostValues['Confirmed'] = forceBool($FormPostValues['Confirmed'], '0', '1', '0');
     }
     if (array_key_exists('Verified', $FormPostValues)) {
         $FormPostValues['Verified'] = forceBool($FormPostValues['Verified'], '0', '1', '0');
     }
     unset($FormPostValues['Admin']);
     // Validate the form posted values
     if (array_key_exists('Gender', $FormPostValues)) {
         $FormPostValues['Gender'] = self::fixGender($FormPostValues['Gender']);
     }
     if (array_key_exists('DateOfBirth', $FormPostValues) && $FormPostValues['DateOfBirth'] == '0-00-00') {
         $FormPostValues['DateOfBirth'] = null;
     }
     $UserID = val('UserID', $FormPostValues);
     $User = array();
     $Insert = $UserID > 0 ? false : true;
     if ($Insert) {
         $this->addInsertFields($FormPostValues);
     } else {
         $this->addUpdateFields($FormPostValues);
         $User = $this->getID($UserID, DATASET_TYPE_ARRAY);
         if (!$User) {
             $User = array();
         }
         // Block banning the superadmin or System accounts
         if (val('Admin', $User) == 2 && val('Banned', $FormPostValues)) {
             $this->Validation->addValidationResult('Banned', 'You may not ban a System user.');
         } elseif (val('Admin', $User) && val('Banned', $FormPostValues)) {
             $this->Validation->addValidationResult('Banned', 'You may not ban a user with the Admin flag set.');
         }
     }
     $this->EventArguments['FormPostValues'] = $FormPostValues;
     $this->fireEvent('BeforeSaveValidation');
     $RecordRoleChange = true;
     if ($UserID && val('FixUnique', $Settings)) {
         $UniqueValid = $this->validateUniqueFields(val('Name', $FormPostValues), val('Email', $FormPostValues), $UserID, true);
         if (!$UniqueValid['Name']) {
             unset($FormPostValues['Name']);
         }
         if (!$UniqueValid['Email']) {
             unset($FormPostValues['Email']);
         }
         $UniqueValid = true;
     } else {
         $UniqueValid = $this->validateUniqueFields(val('Name', $FormPostValues), val('Email', $FormPostValues), $UserID);
     }
     // Add & apply any extra validation rules:
     if (array_key_exists('Email', $FormPostValues) && val('ValidateEmail', $Settings, true)) {
         $this->Validation->applyRule('Email', 'Email');
     }
     // AllIPAdresses is stored as a CSV, so handle the case where an array is submitted.
     if (array_key_exists('AllIPAddresses', $FormPostValues) && is_array($FormPostValues['AllIPAddresses'])) {
         $FormPostValues['AllIPAddresses'] = implode(',', $FormPostValues['AllIPAddresses']);
     }
     if ($this->validate($FormPostValues, $Insert) && $UniqueValid) {
         // All fields on the form that need to be validated (including non-schema field rules defined above)
         $Fields = $this->Validation->validationFields();
         $RoleIDs = val('RoleID', $Fields, 0);
         $Username = val('Name', $Fields);
         $Email = val('Email', $Fields);
         // Only fields that are present in the schema
         $Fields = $this->Validation->schemaValidationFields();
         // Remove the primary key from the fields collection before saving
         $Fields = removeKeyFromArray($Fields, $this->PrimaryKey);
         if (!$Insert && array_key_exists('Password', $Fields) && val('HashPassword', $Settings, true)) {
             // Encrypt the password for saving only if it won't be hashed in _Insert()
             $PasswordHash = new Gdn_PasswordHash();
             $Fields['Password'] = $PasswordHash->hashPassword($Fields['Password']);
             $Fields['HashMethod'] = 'Vanilla';
         }
         // Check for email confirmation.
         if (self::requireConfirmEmail() && !val('NoConfirmEmail', $Settings)) {
             // Email address has changed
             if (isset($Fields['Email']) && (array_key_exists('Confirmed', $Fields) && $Fields['Confirmed'] == 0 || $UserID == Gdn::session()->UserID && $Fields['Email'] != Gdn::session()->User->Email && !Gdn::session()->checkPermission('Garden.Users.Edit'))) {
                 $Attributes = val('Attributes', Gdn::session()->User);
                 if (is_string($Attributes)) {
                     $Attributes = @unserialize($Attributes);
                 }
                 $ConfirmEmailRoleID = RoleModel::getDefaultRoles(RoleModel::TYPE_UNCONFIRMED);
                 if (!empty($ConfirmEmailRoleID)) {
                     // The confirm email role is set and it exists so go ahead with the email confirmation.
                     $NewKey = randomString(8);
                     $EmailKey = touchValue('EmailKey', $Attributes, $NewKey);
                     $Fields['Attributes'] = serialize($Attributes);
                     $Fields['Confirmed'] = 0;
                 }
             }
         }
         $this->EventArguments['SaveRoles'] =& $SaveRoles;
         $this->EventArguments['RoleIDs'] =& $RoleIDs;
         $this->EventArguments['Fields'] =& $Fields;
         $this->fireEvent('BeforeSave');
         $User = array_merge($User, $Fields);
         // Check the validation results again in case something was added during the BeforeSave event.
         if (count($this->Validation->results()) == 0) {
             // If the primary key exists in the validated fields and it is a
             // numeric value greater than zero, update the related database row.
             if ($UserID > 0) {
                 // If they are changing the username & email, make sure they aren't
                 // already being used (by someone other than this user)
                 if (val('Name', $Fields, '') != '' || val('Email', $Fields, '') != '') {
                     if (!$this->validateUniqueFields($Username, $Email, $UserID)) {
                         return false;
                     }
                 }
                 if (array_key_exists('Attributes', $Fields) && !is_string($Fields['Attributes'])) {
                     $Fields['Attributes'] = serialize($Fields['Attributes']);
                 }
                 // Perform save DB operation
                 $this->SQL->put($this->Name, $Fields, array($this->PrimaryKey => $UserID));
                 // Record activity if the person changed his/her photo.
                 $Photo = val('Photo', $FormPostValues);
                 if ($Photo !== false) {
                     if (val('CheckExisting', $Settings)) {
                         $User = $this->getID($UserID);
                         $OldPhoto = val('Photo', $User);
                     }
                     if (isset($OldPhoto) && $OldPhoto != $Photo) {
                         if (IsUrl($Photo)) {
                             $PhotoUrl = $Photo;
                         } else {
                             $PhotoUrl = Gdn_Upload::url(changeBasename($Photo, 'n%s'));
                         }
                         $ActivityModel = new ActivityModel();
                         if ($UserID == Gdn::session()->UserID) {
                             $HeadlineFormat = t('HeadlineFormat.PictureChange', '{RegardingUserID,You} changed {ActivityUserID,your} profile picture.');
                         } else {
                             $HeadlineFormat = t('HeadlineFormat.PictureChange.ForUser', '{RegardingUserID,You} changed the profile picture for {ActivityUserID,user}.');
                         }
                         $ActivityModel->save(array('ActivityUserID' => $UserID, 'RegardingUserID' => Gdn::session()->UserID, 'ActivityType' => 'PictureChange', 'HeadlineFormat' => $HeadlineFormat, 'Story' => img($PhotoUrl, array('alt' => t('Thumbnail')))));
                     }
                 }
             } else {
                 $RecordRoleChange = false;
                 if (!$this->validateUniqueFields($Username, $Email)) {
                     return false;
                 }
                 // Define the other required fields:
                 $Fields['Email'] = $Email;
                 $Fields['Roles'] = $RoleIDs;
                 // Make sure that the user is assigned to one or more roles:
                 $SaveRoles = false;
                 // And insert the new user.
                 $UserID = $this->_insert($Fields, $Settings);
                 if ($UserID) {
                     // Report that the user was created.
                     $ActivityModel = new ActivityModel();
                     $ActivityModel->save(array('ActivityType' => 'Registration', 'ActivityUserID' => $UserID, 'HeadlineFormat' => t('HeadlineFormat.Registration', '{ActivityUserID,You} joined.'), 'Story' => t('Welcome Aboard!')), false, array('GroupBy' => 'ActivityTypeID'));
                     // Report the creation for mods.
                     $ActivityModel->save(array('ActivityType' => 'Registration', 'ActivityUserID' => Gdn::session()->UserID, 'RegardingUserID' => $UserID, 'NotifyUserID' => ActivityModel::NOTIFY_MODS, 'HeadlineFormat' => t('HeadlineFormat.AddUser', '{ActivityUserID,user} added an account for {RegardingUserID,user}.')));
                 }
             }
             // Now update the role settings if necessary.
             if ($SaveRoles) {
                 // If no RoleIDs were provided, use the system defaults
                 if (!is_array($RoleIDs)) {
                     $RoleIDs = RoleModel::getDefaultRoles(RoleModel::TYPE_MEMBER);
                 }
                 $this->saveRoles($UserID, $RoleIDs, $RecordRoleChange);
             }
             // Send the confirmation email.
             if (isset($EmailKey)) {
                 if (!is_array($User)) {
                     $User = $this->getID($UserID, DATASET_TYPE_ARRAY);
                 }
                 $this->sendEmailConfirmationEmail($User, true);
             }
             $this->EventArguments['UserID'] = $UserID;
             $this->fireEvent('AfterSave');
         } else {
             $UserID = false;
         }
     } else {
         $UserID = false;
     }
     // Clear cached user data
     if (!$Insert && $UserID) {
         $this->clearCache($UserID, array('user'));
     }
     return $UserID;
 }
Пример #2
0
 /**
  * {@inheritDoc}
  * @param array $Data
  * @param bool $Settings
  * @return bool|mixed Primary Key Value
  */
 public function save($Data, $Settings = false)
 {
     $this->defineSchema();
     $SchemaFields = $this->Schema->fields();
     $SaveData = array();
     $Attributes = array();
     // Grab the current attachment.
     if (isset($Data['AttachmentID'])) {
         $PrimaryKeyVal = $Data['AttachmentID'];
         $CurrentAttachment = $this->SQL->getWhere('Attachment', array('AttachmentID' => $PrimaryKeyVal))->firstRow(DATASET_TYPE_ARRAY);
         if ($CurrentAttachment) {
             $Attributes = @unserialize($CurrentAttachment['Attributes']);
             if (!$Attributes) {
                 $Attributes = array();
             }
             $Insert = false;
         } else {
             $Insert = true;
         }
     } else {
         $PrimaryKeyVal = false;
         $Insert = true;
     }
     // Grab any values that aren't in the db schema and stick them in attributes.
     foreach ($Data as $Name => $Value) {
         if ($Name == 'Attributes') {
             continue;
         }
         if (isset($SchemaFields[$Name])) {
             $SaveData[$Name] = $Value;
         } elseif ($Value === null) {
             unset($Attributes[$Name]);
         } else {
             $Attributes[$Name] = $Value;
         }
     }
     if (sizeof($Attributes)) {
         $SaveData['Attributes'] = $Attributes;
     } else {
         $SaveData['Attributes'] = null;
     }
     if ($Insert) {
         $this->addInsertFields($SaveData);
     } else {
         $this->addUpdateFields($SaveData);
     }
     // Validate the form posted values.
     if ($this->validate($SaveData, $Insert) === true) {
         $Fields = $this->Validation->validationFields();
         if ($Insert === false) {
             $Fields = removeKeyFromArray($Fields, $this->PrimaryKey);
             // Don't try to update the primary key
             $this->update($Fields, array($this->PrimaryKey => $PrimaryKeyVal));
         } else {
             $PrimaryKeyVal = $this->insert($Fields);
         }
     } else {
         $PrimaryKeyVal = false;
     }
     return $PrimaryKeyVal;
 }
Пример #3
0
 /**
  * Returns the xhtml for a list of checkboxes; sorted into groups related to
  * the TextField value of the dataset.
  *
  * @param string $FieldName The name of the field that is being displayed/posted with this input. It
  * should related directly to a field name in a user junction table.
  * ie. LUM_UserRole.RoleID
  *
  * @param mixed $DataSet The data to fill the options in the select list. Either an associative
  * array or a database dataset. ie. RoleID, Name from LUM_Role.
  *
  * @param mixed $ValueDataSet The data that should be checked in $DataSet. Either an associative array
  * or a database dataset. ie. RoleID from LUM_UserRole for a single user.
  *
  * @param array $Attributes An associative array of attributes for the select. Here is a list of
  * "special" attributes and their default values:
  *
  * Attribute   Options                        Default
  * ------------------------------------------------------------------------
  * ValueField  The name of the field in       'value'
  *             $DataSet that contains the
  *             option values.
  * TextField   The name of the field in       'text'
  *             $DataSet that contains the
  *             option text.
  *
  * @return string
  */
 public function checkBoxGrid($FieldName, $DataSet, $ValueDataSet, $Attributes)
 {
     // Never display individual inline errors for these CheckBoxes
     $Attributes['InlineErrors'] = false;
     $Return = '';
     $CheckedValues = $ValueDataSet;
     if (is_object($ValueDataSet)) {
         $CheckedValues = array_column($ValueDataSet->resultArray(), $FieldName);
     }
     $i = 1;
     if (is_object($DataSet)) {
         $ValueField = arrayValueI('ValueField', $Attributes, 'value');
         $TextField = arrayValueI('TextField', $Attributes, 'text');
         $LastGroup = '';
         $Group = array();
         $Rows = array();
         $Cols = array();
         $CheckBox = '';
         foreach ($DataSet->result() as $Data) {
             // Define the checkbox
             $Instance = $Attributes;
             $Instance = removeKeyFromArray($Instance, array('TextField', 'ValueField'));
             $Instance['value'] = $Data->{$ValueField};
             $Instance['id'] = $FieldName . $i;
             if (is_array($CheckedValues) && in_array($Data->{$ValueField}, $CheckedValues)) {
                 $Instance['checked'] = 'checked';
             }
             $CheckBox = $this->checkBox($FieldName . '[]', '', $Instance);
             // Organize the checkbox into an array for this group
             $CurrentTextField = $Data->{$TextField};
             $aCurrentTextField = explode('.', $CurrentTextField);
             $aCurrentTextFieldCount = count($aCurrentTextField);
             $GroupName = array_shift($aCurrentTextField);
             $ColName = array_pop($aCurrentTextField);
             if ($aCurrentTextFieldCount >= 3) {
                 $RowName = implode('.', $aCurrentTextField);
                 if ($GroupName != $LastGroup && $LastGroup != '') {
                     // Render the last group
                     $Return .= $this->getCheckBoxGridGroup($LastGroup, $Group, $Rows, $Cols);
                     // Clean out the $Group array & Rowcount
                     $Group = array();
                     $Rows = array();
                     $Cols = array();
                 }
                 if (array_key_exists($ColName, $Group) === false || is_array($Group[$ColName]) === false) {
                     $Group[$ColName] = array();
                     if (!in_array($ColName, $Cols)) {
                         $Cols[] = $ColName;
                     }
                 }
                 if (!in_array($RowName, $Rows)) {
                     $Rows[] = $RowName;
                 }
                 $Group[$ColName][$RowName] = $CheckBox;
                 $LastGroup = $GroupName;
             }
             ++$i;
         }
     }
     return $Return . $this->getCheckBoxGridGroup($LastGroup, $Group, $Rows, $Cols);
 }
Пример #4
0
 /**
  *  Takes a set of form data ($Form->_PostValues), validates them, and
  * inserts or updates them to the datatabase.
  *
  * @param array $FormPostValues An associative array of $Field => $Value pairs that represent data posted
  * from the form in the $_POST or $_GET collection.
  * @param array $Settings If a custom model needs special settings in order to perform a save, they
  * would be passed in using this variable as an associative array.
  * @return unknown
  */
 public function save($FormPostValues, $Settings = false)
 {
     // Define the primary key in this model's table.
     $this->defineSchema();
     // See if a primary key value was posted and decide how to save
     $PrimaryKeyVal = val($this->PrimaryKey, $FormPostValues, false);
     $Insert = $PrimaryKeyVal == false ? true : false;
     if ($Insert) {
         $this->addInsertFields($FormPostValues);
     } else {
         $this->addUpdateFields($FormPostValues);
     }
     // Validate the form posted values
     if ($this->validate($FormPostValues, $Insert) === true) {
         $Fields = $this->Validation->validationFields();
         $Fields = removeKeyFromArray($Fields, $this->PrimaryKey);
         // Don't try to insert or update the primary key
         if ($Insert === false) {
             $this->update($Fields, array($this->PrimaryKey => $PrimaryKeyVal));
         } else {
             $PrimaryKeyVal = $this->insert($Fields);
         }
     } else {
         $PrimaryKeyVal = false;
     }
     return $PrimaryKeyVal;
 }