public function member__forgot_password() { $globals = Statamic::loadAllConfigs(); $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING); $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING); $return = filter_input(INPUT_POST, 'return', FILTER_SANITIZE_STRING); $reset_return = filter_input(INPUT_POST, 'reset_return', FILTER_SANITIZE_STRING); $referrer = Request::getReferrer(); // validate form token if (!$this->tokens->validate($token)) { $this->flash->set('forgot_password_error', 'Invalid token.'); URL::redirect($referrer); } // bail if member doesn't exist if (!($member = Member::load($username))) { $this->flash->set('forgot_password_error', Localization::fetch('member_doesnt_exist')); URL::redirect($referrer); } // cache reset data $token = $this->tokens->create(); $reset_data = array('username' => $username); if (isset($reset_return)) { $reset_data['return'] = $reset_return; } $this->cache->putYAML($token, $reset_data); // generate reset url $reset_url = URL::makeFull($this->fetchConfig('reset_password_url', str_replace(Config::getSiteURL(), '', $referrer))); $reset_url .= '?H=' . $token; // send email $attributes = array('from' => $this->fetchConfig('email_sender', Config::get('email_sender'), null, false, false), 'to' => $member->get('email'), 'subject' => $this->fetchConfig('reset_password_subject', 'Password Reset', null, false, false)); if ($html_template = $this->fetchConfig('reset_password_html_email', false, null, false, false)) { $attributes['html'] = Theme::getTemplate($html_template); } if ($text_template = $this->fetchConfig('reset_password_text_email', false, null, false, false)) { $attributes['text'] = Theme::getTemplate($text_template); } foreach ($attributes as $key => $value) { $attributes[$key] = Parse::template($value, array('reset_url' => $reset_url), array('statamic_view', 'callback'), $globals); } Email::send($attributes); $this->flash->set('forgot_password_sent', true); // redirect URL::redirect($return); }
| | Pages go back to the tree, entries to their respective Entry Listing | Or, if a custom return was specified, we'll go there. | */ if ($form_data['type'] == 'none') { $app->flash('success', Localization::fetch('page_saved')); } else { $app->flash('success', Localization::fetch('entry_saved')); } $return = Request::post('return'); if (Request::post('continue')) { $path = Path::trimSlashes(str_replace(Config::getContentRoot(), '', Path::tidy($file))); $path = preg_replace('/\\.' . Config::getContentType() . '$/', '', $path); $redirect_url = $admin_app->urlFor('publish') . '?path=' . $path; if (strpos(Request::getReferrer(), 'return=')) { // maintain the 'return' in the URL $return_uri = substr($return, strlen($app->request()->getRootUri())); $redirect_url .= '&return=' . $return_uri; } $app->redirect($redirect_url); } else { $app->redirect($return); } }); // GET: DELETE ENTRY $admin_app->map('/delete/entry', function () use($admin_app) { authenticateForRole('admin'); doStatamicVersionCheck($admin_app); $content_root = Config::getContentRoot(); $content_type = Config::getContentType();
/** * Process a form submission * * @return void */ private function process() { /* |-------------------------------------------------------------------------- | Prep form and handler variables |-------------------------------------------------------------------------- | | We're going to assume success = true here to simplify code readability. | Checks already exist for require and validation so we simply flip the | switch there. | */ $success = true; $errors = array(); /* |-------------------------------------------------------------------------- | Hidden fields and $_POST hand off |-------------------------------------------------------------------------- | | We slide the hidden key out of the POST data and assign the rest to a | cleaner $submission variable. | */ $hidden = $_POST['hidden']; unset($_POST['hidden']); $submission = $_POST; /* |-------------------------------------------------------------------------- | Grab formset and collapse settings |-------------------------------------------------------------------------- | | Formset settings are merged on top of the default raven.yaml config file | to allow per-form overrides. | */ $formset_name = array_get($hidden, 'formset'); $formset = $formset_name . '.yaml'; if (File::exists('_config/add-ons/raven/formsets/' . $formset)) { $formset = Yaml::parse('_config/add-ons/raven/formsets/' . $formset); } elseif (File::exists('_config/formsets/' . $formset)) { $formset = Yaml::parse('_config/formsets/' . $formset); } else { $formset = array(); } if (!is_array($this->config)) { $this->log->warn('Could not find the config file.'); $this->config = array(); } $config = array_merge($this->config, $formset, array('formset' => $hidden['formset'])); /* |-------------------------------------------------------------------------- | Prep filters |-------------------------------------------------------------------------- | | We jump through some PHP hoops here to filter, sanitize and validate | our form inputs. | */ $allowed_fields = array_flip(array_get($formset, 'allowed', array())); $required_fields = array_flip(array_get($formset, 'required', array())); $validation_rules = isset($formset['validate']) ? $formset['validate'] : array(); $messages = isset($formset['messages']) ? $formset['messages'] : array(); $referrer = Request::getReferrer(); $return = array_get($hidden, 'return', $referrer); $error_return = array_get($hidden, 'error_return', $referrer); /* |-------------------------------------------------------------------------- | Allowed fields |-------------------------------------------------------------------------- | | It's best to only allow a set of predetermined fields to cut down on | spam and misuse. | */ if (count($allowed_fields) > 0) { $submission = array_intersect_key($submission, $allowed_fields); } /* |-------------------------------------------------------------------------- | Required fields |-------------------------------------------------------------------------- | | Requiring fields isn't required (ironic-five!), but if any are specified | and missing from the POST, we'll be squashing this submission right here | and sending back an array of missing fields. | */ if (count($required_fields) > 0) { $missing = array_flip(array_diff_key($required_fields, array_filter($submission))); if (count($missing) > 0) { foreach ($missing as $key => $field) { $errors['missing'][] = array('field' => $field); } $success = false; } } /* |-------------------------------------------------------------------------- | Validation |-------------------------------------------------------------------------- | | Run optional per-field validation. Any data failing the specified | validation rule will squash the submission and send back error messages | as specified in the formset. | */ $invalid = $this->validate($submission, $validation_rules); // Prepare a data array of fields and error messages use for template display if (count($invalid) > 0) { $errors['invalid'] = array(); foreach ($invalid as $field) { $errors['invalid'][] = array('field' => $field, 'message' => isset($messages[$field]) ? $messages[$field] : null); } $success = false; } /* |-------------------------------------------------------------------------- | Upload Files |-------------------------------------------------------------------------- | | Upload any files to their specified destination. | */ if (count($_FILES) > 0) { $files = array_intersect_key($_FILES, $allowed_fields); $upload_destination = array_get($config, 'upload_destination'); foreach ($files as $name => $file) { $submission[$name] = File::upload($file, $upload_destination); } } /* |-------------------------------------------------------------------------- | Hook: Pre Process |-------------------------------------------------------------------------- | | Allow pre-processing by other add-ons with the ability to kill the | success of the submission. Has access to the submission and config. | */ $success = Hook::run('raven', 'pre_process', 'replace', $success, compact('submission', 'config', 'success')); /* |-------------------------------------------------------------------------- | Form Identifier |-------------------------------------------------------------------------- | | In the event of multiple forms on a page, we'll be able to determine | which one was the one that had been triggered. | */ $this->flash->set('form_id', $hidden['raven']); /* |-------------------------------------------------------------------------- | Finalize & determine action |-------------------------------------------------------------------------- | | Send back the errors if validation or require fields are missing. | If successful, save to file (if enabled) and send notification | emails (if enabled). | */ if ($success) { // Akismet? $is_spam = false; if ($akismet = array_get($config, 'akismet') && array_get($config, 'akismet_api_key')) { $is_spam = $this->tasks->akismetCheck(array('permalink' => URL::makeFull(URL::getCurrent()), 'comment_type' => $formset_name, 'comment_author' => array_get($submission, array_get($akismet, 'author')), 'comment_author_email' => array_get($submission, array_get($akismet, 'email')), 'comment_author_url' => array_get($submission, array_get($akismet, 'url')), 'comment_content' => array_get($submission, array_get($akismet, 'content')))); } // Shall we save? if (array_get($config, 'submission_save_to_file', false) === true) { $file_prefix = Parse::template(array_get($config, 'file_prefix', ''), $submission); $file_suffix = Parse::template(array_get($config, 'file_suffix', ''), $submission); $file_prefix = $is_spam ? '_' . $file_prefix : $file_prefix; $this->save($submission, $config, $config['submission_save_path'], $is_spam); } // Shall we send? if (!$is_spam && array_get($config, 'send_notification_email', false) === true) { $this->send($submission, $config); } /* |-------------------------------------------------------------------------- | Hook: On Success |-------------------------------------------------------------------------- | | Allow events after the form as been processed. Has access to the | submission and config. | */ Hook::run('raven', 'on_success', null, null, array('submission' => $submission, 'config' => $config)); $this->flash->set('success', true); URL::redirect(URL::format($return)); } else { $this->flash->set('success', false); $this->flash->set('errors', $errors); $this->flash->set('old_values', $_POST); URL::redirect(URL::format($error_return)); } }
/** * Target for the member:profile_form form * * @return void */ public function member__update_profile() { $site_root = Config::getSiteRoot(); $referrer = Request::getReferrer(); $return = filter_input(INPUT_POST, 'return', FILTER_SANITIZE_URL); // is user logged in? if (!Auth::isLoggedIn()) { URL::redirect($this->fetchConfig('login_url', $site_root, null, false, false)); } // get current user $member = Auth::getCurrentMember(); // get configurations $allowed_fields = array_get($this->loadConfigFile('fields'), 'fields', array()); $role_definitions = $this->fetchConfig('role_definitions'); // who are we editing? $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING); $username = !$username ? $member->get('username') : $username; // if the user isn't the current user, ensure that's allowed if ($username !== $member->get('username')) { // username is different from current user if (!array_get($role_definitions, 'edit_other_users', null) || !$member->hasRole($role_definitions['edit_other_users'])) { // this user does not have permission to do this $this->flash->set('update_profile_error', 'You are not allowed to edit another member’s profile.'); URL::redirect($referrer); } else { // all set, update member $member = Member::load($username); } } // get old values $old_values = $member->export(); // set up iterators and flags $submission = array(); // loop through allowed fields, validating and updating foreach ($allowed_fields as $field => $options) { if (!isset($_POST[$field])) { // was this username? that can be included separately if ($field === 'username') { $value = $username; } else { // field wasn't set, skip it continue; } } else { // set value $value = filter_input(INPUT_POST, $field, FILTER_SANITIZE_STRING); } // set value $old_values[$field] = $value; // don't store this value if `save_value` is set to `false` if (array_get($options, 'save_value', true)) { $member->set($field, $value); } // add to submissions, including non-save_value fields because this // is the list that will be validated $submission[$field] = $value; } // validate $errors = $this->tasks->validate($submission); if (count($errors)) { // errors were found, set a flash message and redirect $this->flash->set('update_profile_error', 'Member profile not updated.'); $this->flash->set('update_profile_field_errors', $errors); $this->flash->set('update_profile_old_values', $old_values); URL::redirect($referrer); } else { // save member $member->save(); // trigger a hook $this->runHook('profile_update', 'call', null, $member); // user saved $this->flash->set('update_profile_success', 'Member profile updated.'); if ($return) { URL::redirect($return); } else { URL::redirect($referrer); } } }