/** * Save profile data * * @param array $profile * @param array $access * @return boolean */ public function saveProfile($profile, $access = array()) { $profile = (array) $profile; $access = (array) $access; $keep = array(); foreach ($this->profiles as $field) { // Remove any entries not in the incoming data if (!isset($profile[$field->get('profile_key')])) { if (!$field->destroy()) { $this->addError($field->getError()); return false; } continue; } // Push to the list of fields we want to keep if (!isset($keep[$field->get('profile_key')])) { $keep[$field->get('profile_key')] = $field; } else { // Multi-value field $values = $keep[$field->get('profile_key')]; $values = is_array($values) ? $values : array($values->get('profile_value') => $values); $values[$field->get('profile_value')] = $field; $keep[$field->get('profile_key')] = $values; } } $i = 1; foreach ($profile as $key => $data) { if ($key == 'tag' || $key == 'tags') { $this->tag($data); continue; } // Is it a multi-value field? if (is_array($data)) { if (empty($data)) { continue; } foreach ($data as $val) { if (is_array($val) || is_object($val)) { $val = json_encode($val); } $val = trim($val); // Skip empty values if (!$val) { continue; } $field = null; // Try to find an existing entry if (isset($keep[$key])) { if (is_array($keep[$key])) { if (isset($keep[$key][$val])) { $field = $keep[$key][$val]; unset($keep[$key][$val]); } } else { $field = $keep[$key]; unset($keep[$key]); } } if (!$field instanceof Profile) { $field = Profile::blank(); } $field->set(array('user_id' => $this->get('id'), 'profile_key' => $key, 'profile_value' => $val, 'ordering' => $i, 'access' => isset($access[$key]) ? $access[$key] : $field->get('access', 5))); if (!$field->save()) { $this->addError($field->getError()); return false; } } // Remove any values not already found if (isset($keep[$key]) && is_array($keep[$key])) { foreach ($keep[$key] as $f) { if (!$f->destroy()) { $this->addError($f->getError()); return false; } } } } else { $val = trim($data); $field = null; if (isset($keep[$key])) { $field = $keep[$key]; } if (!$field instanceof Profile) { $field = Profile::blank(); } // If value is empty if (!$val) { // If an existing field, remove it if ($field->get('id')) { if (!$field->destroy()) { $this->addError($field->getError()); return false; } } // Move along. Nothing to see here. continue; } $field->set(array('user_id' => $this->get('id'), 'profile_key' => $key, 'profile_value' => $val, 'ordering' => $i, 'access' => isset($access[$key]) ? $access[$key] : $field->get('access', 5))); if (!$field->save()) { $this->addError($field->getError()); return false; } } $i++; } return true; }
/** * Save changes to a profile * Outputs JSON when called via AJAX, redirects to profile otherwise * * @return string JSON */ public function saveTask() { // Check if they are logged in if (User::isGuest()) { return false; } Request::checkToken(array('get', 'post')); $no_html = Request::getVar('no_html', 0); // Incoming user ID $id = Request::getInt('id', 0, 'post'); // Do we have an ID? if (!$id) { App::abort(404, Lang::txt('COM_MEMBERS_NO_ID')); } // Load the profile $member = Member::oneOrFail($id); // Name changed? $name = Request::getVar('name', array(), 'post'); if ($name && !empty($name)) { $member->set('givenName', trim($name['first'])); $member->set('middleName', trim($name['middle'])); $member->set('surname', trim($name['last'])); $name = implode(' ', $name); $name = preg_replace('/\\s+/', ' ', $name); $member->set('name', $name); } // Set profile access $visibility = Request::getVar('profileaccess', null, 'post'); if (!is_null($visibility)) { $member->set('access', $visibility); } // Check email $oldemail = $member->get('email'); $email = Request::getVar('email', null, 'post'); if (!is_null($email)) { $member->set('email', (string) $email); // Unconfirm if the email address changed if ($oldemail != $email) { // Get a new confirmation code $confirm = \Components\Members\Helpers\Utility::genemailconfirm(); $member->set('activation', $confirm); } } // Receieve email updates? $sendEmail = Request::getVar('sendEmail', null, 'post'); if (!is_null($sendEmail)) { $member->set('sendEmail', $sendEmail); } // Usage agreement $usageAgreement = Request::getVar('usageAgreement', null, 'post'); if (!is_null($usageAgreement)) { $member->set('usageAgreement', (int) $usageAgreement); } // Are we declining the terms of use? // If yes we want to set the usage agreement to 0 and profile to private $declineTOU = Request::getVar('declinetou', 0); if ($declineTOU) { $member->set('access', 0); $member->set('usageAgreement', 0); } // Save the changes if (!$member->save()) { $this->setError($member->getError()); if ($no_html) { echo json_encode($this->getErrors()); exit; } return $this->editTask($member); } // Incoming profile edits $profile = Request::getVar('profile', array(), 'post', 'none', 2); $access = Request::getVar('access', array(), 'post'); $field_to_check = Request::getVar('field_to_check', array()); $old = Profile::collect($member->profiles); $profile = array_merge($old, $profile); // Compile profile data foreach ($profile as $key => $data) { if (isset($profile[$key]) && is_array($profile[$key])) { $profile[$key] = array_filter($profile[$key]); } if (isset($profile[$key . '_other']) && trim($profile[$key . '_other'])) { if (is_array($profile[$key])) { $profile[$key][] = $profile[$key . '_other']; } else { $profile[$key] = $profile[$key . '_other']; } unset($profile[$key . '_other']); } } // Validate profile data $fields = Field::all()->including(['options', function ($option) { $option->select('*'); }])->where('action_edit', '!=', Field::STATE_HIDDEN)->ordered()->rows(); $form = new \Hubzero\Form\Form('profile', array('control' => 'profile')); $form->load(Field::toXml($fields, 'edit', $profile)); $form->bind(new \Hubzero\Config\Registry($profile)); $errors = array('_missing' => array(), '_invalid' => array()); if (!$form->validate($profile)) { foreach ($form->getErrors() as $key => $error) { // Filter out fields if (!empty($field_to_check) && !in_array($key, $field_to_check)) { continue; } if ($error instanceof \Hubzero\Form\Exception\MissingData) { $errors['_missing'][$key] = (string) $error; } $errors['_invalid'][$key] = (string) $error; $this->setError((string) $error); } } if ($this->getError()) { if ($no_html) { echo json_encode($errors); exit; } return $this->editTask($member); } // Save profile data if (!$member->saveProfile($profile, $access)) { $this->setError($member->getError()); if ($no_html) { echo json_encode($this->getErrors()); exit; } return $this->editTask($member); } $email = $member->get('email'); // Make sure certain changes make it back to the user table if ($member->get('id') == User::get('id')) { $user = App::get('session')->get('user'); if ($member->get('name') != $user->get('name')) { $user->set('name', $member->get('name')); } // Update session if email is changing if ($member->get('email') != $user->get('email')) { $user->set('email', $member->get('email')); // Add item to session to mark that the user changed emails // this way we can serve profile images for these users but not all // unconfirmed users App::get('session')->set('userchangedemail', 1); } App::get('session')->set('user', $user); } // Send a new confirmation code AFTER we've successfully saved the changes to the e-mail address if ($email != $oldemail) { $this->_sendConfirmationCode($member->get('username'), $email, $confirm); } // If were declinging the terms we want to logout user and tell the javascript if ($declineTOU) { App::get('auth')->logout(); echo json_encode(array('loggedout' => true)); return; } if ($no_html) { // Output JSON echo json_encode(array('success' => true)); exit; } // Redirect App::redirect(Route::url('index.php?option=' . $this->_option . ($id ? '&id=' . $id . '&active=profile' : ''))); }