/** * Execute the action */ public function execute() { parent::execute(); // get parameters $charset = $this->getContainer()->getParameter('kernel.charset'); $searchTerm = \SpoonFilter::getPostValue('term', null, ''); $term = $charset == 'utf-8' ? \SpoonFilter::htmlspecialchars($searchTerm) : \SpoonFilter::htmlentities($searchTerm); // validate search term if ($term == '') { $this->output(self::BAD_REQUEST, null, 'term-parameter is missing.'); } else { // previous search result $previousTerm = \SpoonSession::exists('searchTerm') ? \SpoonSession::get('searchTerm') : ''; \SpoonSession::set('searchTerm', ''); // save this term? if ($previousTerm != $term) { // format data $this->statistics = array(); $this->statistics['term'] = $term; $this->statistics['language'] = LANGUAGE; $this->statistics['time'] = FrontendModel::getUTCDate(); $this->statistics['data'] = serialize(array('server' => $_SERVER)); $this->statistics['num_results'] = FrontendSearchModel::getTotal($term); // save data FrontendSearchModel::save($this->statistics); } // save current search term in cookie \SpoonSession::set('searchTerm', $term); // output $this->output(self::OK); } }
/** * Validate the form */ protected function validateForm() { if ($this->frm->isSubmitted()) { $this->frm->cleanupFields(); // validation $fields = $this->frm->getFields(); $fields['title']->isFilled(Language::err('TitleIsRequired')); $fields['description']->isFilled(Language::err('FieldIsRequired')); $fields['author_name']->isFilled(Language::err('FieldIsRequired')); $fields['author_url']->isFilled(Language::err('FieldIsRequired')); $fields['author_email']->isFilled(Language::err('FieldIsRequired')); // cleanup the modulename $title = preg_replace('/[^A-Za-z ]/', '', $fields['title']->getValue()); // check if there is already a module with this name if (BackendExtensionsModel::existsModule($title)) { $fields['title']->addError(Language::err('DuplicateModuleName')); } if ($this->frm->isCorrect()) { $this->record['title'] = $title; $this->record['description'] = trim($fields['description']->getValue()); $this->record['author_name'] = $fields['author_name']->getValue(); $this->record['author_url'] = $fields['author_url']->getValue(); $this->record['author_email'] = $fields['author_email']->getValue(); $this->record['camel_case_name'] = BackendModuleMakerHelper::buildCamelCasedName($title); $this->record['underscored_name'] = BackendModuleMakerHelper::buildUnderscoredName($title); \SpoonSession::set('module', $this->record); $this->redirect(Model::createURLForAction('AddStep2')); } } }
/** * Validate the form */ protected function validateForm() { if ($this->frm->isSubmitted()) { $this->frm->cleanupFields(); $frmFields = $this->frm->getFields(); // validate form if ($frmFields['twitter']->isChecked()) { // we need fields when search is ticked $frmFields['twitter_name']->isFilled(Language::err('FieldIsRequired')); } if ($this->frm->isCorrect()) { // if this field is checked, let's add a boolean searchable true to the chosen fields if ($frmFields['twitter']->isChecked()) { $this->record['twitter'] = $frmFields['twitter_name']->getValue(); } else { if (array_key_exists('twitter', $this->record)) { unset($this->record['twitter']); } } // save the object in our session \SpoonSession::set('module', $this->record); $this->redirect(Model::createURLForAction('Generate')); } } }
/** * Execute the action * * @return void */ public function execute() { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // get parameters $term = SpoonFilter::getGetValue('term', null, ''); // validate if ($term == '') { $this->output(self::BAD_REQUEST, null, 'term-parameter is missing.'); } // previous search result $previousTerm = SpoonSession::exists('searchTerm') ? SpoonSession::get('searchTerm') : ''; SpoonSession::set('searchTerm', ''); // save this term? if ($previousTerm != $term) { // format data $this->statistics = array(); $this->statistics['term'] = $term; $this->statistics['language'] = FRONTEND_LANGUAGE; $this->statistics['time'] = FrontendModel::getUTCDate(); $this->statistics['data'] = serialize(array('server' => $_SERVER)); $this->statistics['num_results'] = FrontendSearchModel::getTotal($term); // save data FrontendSearchModel::save($this->statistics); } // save current search term in cookie SpoonSession::set('searchTerm', $term); // output $this->output(self::OK); }
/** * Check if the token is ok */ public function checkToken() { $fromSession = \SpoonSession::exists('csrf_token') ? \SpoonSession::get('csrf_token') : ''; $fromGet = \SpoonFilter::getGetValue('token', null, ''); if ($fromSession != '' && $fromGet != '' && $fromSession == $fromGet) { return; } // clear the token \SpoonSession::set('csrf_token', ''); $this->redirect(BackendModel::createURLForAction('Index', null, null, array('error' => 'csrf'))); }
/** * Validate the form based on the variables in $_POST * * @return void */ private function validateForm() { // form submitted if ($this->frm->isSubmitted()) { // required fields $this->frm->getField('email')->isEmail('Please provide a valid e-mailaddress.'); $this->frm->getField('password')->isFilled('This field is required.'); $this->frm->getField('confirm')->isFilled('This field is required.'); if ($this->frm->getField('password')->getValue() != $this->frm->getField('confirm')->getValue()) { $this->frm->getField('confirm')->addError('The passwords do not match.'); } // all valid if ($this->frm->isCorrect()) { // update session SpoonSession::set('email', $this->frm->getField('email')->getValue()); SpoonSession::set('password', $this->frm->getField('password')->getValue()); SpoonSession::set('confirm', $this->frm->getField('confirm')->getValue()); // redirect SpoonHTTP::redirect('index.php?step=7'); } } }
/** * Execute the action */ public function execute() { // If step 1 isn't entered, redirect back to the first step of the wizard $this->record = \SpoonSession::get('module'); if (!$this->record || !array_key_exists('title', $this->record)) { $this->redirect(Model::createURLForAction('Add')); } // If there are no fields added, redirect back to the second step of the wizard if (!array_key_exists('fields', $this->record) || empty($this->record['fields'])) { $this->redirect(Model::createURLForAction('AddStep2') . '&error=non-existing'); } // get parameters $this->id = $this->getParameter('id', 'int'); // does the item exist if ($this->id !== null && array_key_exists($this->id, $this->record['fields'])) { unset($this->record['fields'][$this->id]); \SpoonSession::set('module', $this->record); $this->redirect(Model::createURLForAction('AddStep2') . '&report=deleted'); } else { $this->redirect(Model::createURLForAction('AddStep2') . '&error=non-existing'); } }
/** * Validate the form */ private function validateForm() { // get settings $subscriptionsAllowed = isset($this->settings['allow_subscriptions']) && $this->settings['allow_subscriptions']; // subscriptions aren't allowed so we don't have to validate if (!$subscriptionsAllowed) { return false; } // is the form submitted if ($this->frm->isSubmitted()) { // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); // does the key exists? if (\SpoonSession::exists('agenda_subscription_' . $this->record['id'])) { // calculate difference $diff = time() - (int) \SpoonSession::get('agenda_subscription_' . $this->record['id']); // calculate difference, it it isn't 10 seconds the we tell the user to slow down if ($diff < 10 && $diff != 0) { $this->frm->getField('message')->addError(FL::err('CommentTimeout')); } } // validate required fields $this->frm->getField('name')->isFilled(FL::err('NameIsRequired')); $this->frm->getField('email')->isEmail(FL::err('EmailIsRequired')); // no errors? if ($this->frm->isCorrect()) { // get module setting $moderationEnabled = isset($this->settings['moderation']) && $this->settings['moderation']; // reformat data $name = $this->frm->getField('name')->getValue(); $email = $this->frm->getField('email')->getValue(); // build array $subscription['agenda_id'] = $this->record['id']; $subscription['language'] = FRONTEND_LANGUAGE; $subscription['created_on'] = FrontendModel::getUTCDate(); $subscription['name'] = $name; $subscription['email'] = $email; $subscription['status'] = 'subscribed'; // get URL for article $permaLink = $this->record['full_url']; $redirectLink = $permaLink; // is moderation enabled if ($moderationEnabled) { // if the commenter isn't moderated before alter the subscription status so it will appear in the moderation queue if (!FrontendAgendaModel::isModerated($name, $email)) { $subscription['status'] = 'moderation'; } } // insert comment $subscription['id'] = FrontendAgendaModel::insertSubscription($subscription); // trigger event FrontendModel::triggerEvent('agenda', 'after_add_subscription', array('subscription' => $subscription)); // append a parameter to the URL so we can show moderation if (strpos($redirectLink, '?') === false) { if ($subscription['status'] == 'moderation') { $redirectLink .= '?subscription=moderation#' . FL::act('Subscribe'); } if ($subscription['status'] == 'subscribed') { $redirectLink .= '?subscription=true#subscription-' . $subscription['id']; } } else { if ($subscription['status'] == 'moderation') { $redirectLink .= '&subscription=moderation#' . FL::act('Subscribe'); } if ($subscription['status'] == 'subscribed') { $redirectLink .= '&subscription=true#comment-' . $subscription['id']; } } // set title $subscription['agenda_title'] = $this->record['title']; $subscription['agenda_url'] = $this->record['url']; // notify the admin FrontendAgendaModel::notifyAdmin($subscription); // store timestamp in session so we can block excessive usage \SpoonSession::set('agenda_subscription_' . $this->record['id'], time()); // store author-data in cookies try { Cookie::set('subscription_author', $name); Cookie::set('subscription_email', $email); } catch (Exception $e) { // settings cookies isn't allowed, but because this isn't a real problem we ignore the exception } // redirect $this->redirect($redirectLink); } } }
/** * Process the querystring * * @return void */ private function processQueryString() { // store the querystring local, so we don't alter it. $queryString = $this->getQueryString(); // fix GET-parameters $getChunks = explode('?', $queryString); // are there GET-parameters if (isset($getChunks[1])) { // get key-value pairs $get = explode('&', $getChunks[1]); // remove from querystring $queryString = str_replace('?' . $getChunks[1], '', $this->getQueryString()); // loop pairs foreach ($get as $getItem) { // get key and value $getChunks = explode('=', $getItem, 2); // key available? if (isset($getChunks[0])) { // reset in $_GET $_GET[$getChunks[0]] = isset($getChunks[1]) ? (string) $getChunks[1] : ''; // add into parameters if (isset($getChunks[1])) { $this->parameters[(string) $getChunks[0]] = (string) $getChunks[1]; } } } } // split into chunks $chunks = (array) explode('/', $queryString); // single language if (!SITE_MULTILANGUAGE) { // set language id $language = FrontendModel::getModuleSetting('core', 'default_language', SITE_DEFAULT_LANGUAGE); } else { // default value $mustRedirect = false; // get possible languages $possibleLanguages = (array) FrontendLanguage::getActiveLanguages(); $redirectLanguages = (array) FrontendLanguage::getRedirectLanguages(); // the language is present in the URL if (isset($chunks[0]) && in_array($chunks[0], $possibleLanguages)) { // define language $language = (string) $chunks[0]; // try to set a cookie with the language try { // set cookie SpoonCookie::set('frontend_language', $language, 7 * 24 * 60 * 60, '/', '.' . $this->getDomain()); } catch (SpoonCookieException $e) { // settings cookies isn't allowed, because this isn't a real problem we ignore the exception } // set sessions SpoonSession::set('frontend_language', $language); // remove the language part array_shift($chunks); } elseif (SpoonCookie::exists('frontend_language') && in_array(SpoonCookie::get('frontend_language'), $redirectLanguages)) { // set languageId $language = (string) SpoonCookie::get('frontend_language'); // redirect is needed $mustRedirect = true; } else { // set languageId & abbreviation $language = FrontendLanguage::getBrowserLanguage(); // try to set a cookie with the language try { // set cookie SpoonCookie::set('frontend_language', $language, 7 * 24 * 60 * 60, '/', '.' . $this->getDomain()); } catch (SpoonCookieException $e) { // settings cookies isn't allowed, because this isn't a real problem we ignore the exception } // redirect is needed $mustRedirect = true; } // redirect is required if ($mustRedirect) { // build URL $URL = rtrim('/' . $language . '/' . $this->getQueryString(), '/'); // set header & redirect SpoonHTTP::redirect($URL, 301); } } // define the language define('FRONTEND_LANGUAGE', $language); // sets the localefile FrontendLanguage::setLocale($language); // list of pageIds & their full URL $keys = FrontendNavigation::getKeys(); // full URL $URL = implode('/', $chunks); $startURL = $URL; // loop until we find the URL in the list of pages while (!in_array($URL, $keys)) { // remove the last chunk array_pop($chunks); // redefine the URL $URL = implode('/', $chunks); } // remove language from querystring if (SITE_MULTILANGUAGE) { $queryString = trim(substr($queryString, strlen($language)), '/'); } // if it's the homepage AND parameters were given (not allowed!) if ($URL == '' && $queryString != '') { // get 404 URL $URL = FrontendNavigation::getURL(404); // remove language if (SITE_MULTILANGUAGE) { $URL = str_replace('/' . $language, '', $URL); } } // set pages $URL = trim($URL, '/'); // currently not in the homepage if ($URL != '') { // explode in pages $pages = explode('/', $URL); // reset pages $this->setPages($pages); // reset parameters $this->setParameters(array()); } // set parameters $parameters = trim(substr($startURL, strlen($URL)), '/'); // has at least one parameter if ($parameters != '') { // parameters will be separated by / $parameters = explode('/', $parameters); // set parameters $this->setParameters($parameters); } // pageId, parentId & depth $pageId = FrontendNavigation::getPageId(implode('/', $this->getPages())); $pageInfo = FrontendNavigation::getPageInfo($pageId); // invalid page, or parameters but no extra if ($pageInfo === false || !empty($parameters) && !$pageInfo['has_extra']) { // get 404 URL $URL = FrontendNavigation::getURL(404); // remove language if (SITE_MULTILANGUAGE) { $URL = trim(str_replace('/' . $language, '', $URL), '/'); } // currently not in the homepage if ($URL != '') { // explode in pages $pages = explode('/', $URL); // reset pages $this->setPages($pages); // reset parameters $this->setParameters(array()); } } // is this an internal redirect? if (isset($pageInfo['redirect_page_id']) && $pageInfo['redirect_page_id'] != '') { // get url for item $newPageURL = FrontendNavigation::getURL((int) $pageInfo['redirect_page_id']); $errorURL = FrontendNavigation::getURL(404); // not an error? if ($newPageURL != $errorURL) { // redirect SpoonHTTP::redirect($newPageURL, $pageInfo['redirect_code']); } } // is this an external redirect? if (isset($pageInfo['redirect_url']) && $pageInfo['redirect_url'] != '') { // redirect SpoonHTTP::redirect($pageInfo['redirect_url'], $pageInfo['redirect_code']); } }
/** * Validate the form based on the variables in $_POST */ private function validateForm() { // form submitted if ($this->frm->isSubmitted()) { // all valid if ($this->frm->isCorrect()) { // get selected modules $modules = $this->frm->getField('modules')->getValue(); // add blog if example data was checked if ($this->frm->getField('example_data')->getChecked() && !in_array('blog', $modules)) { $modules[] = 'blog'; } // set modules SpoonSession::set('modules', $modules); // example data SpoonSession::set('example_data', $this->frm->getField('example_data')->getChecked()); // debug mode SpoonSession::set('debug_mode', $this->frm->getField('debug_mode')->getChecked()); // redirect SpoonHTTP::redirect('index.php?step=5'); } } }
/** * Logout a profile. * * @return void */ public static function logout() { // delete session records FrontendModel::getDB(true)->delete('profiles_sessions', 'session_id = ?', array(SpoonSession::getSessionId())); // set is_logged_in to false SpoonSession::set('frontend_profile_logged_in', false); // delete cookie SpoonCookie::delete('frontend_profile_secret_key'); }
/** * Validate the form */ protected function validateForm() { if ($this->frm->isSubmitted()) { $this->frm->cleanupFields(); // validation $fields = $this->frm->getFields(); $fields['label']->isFilled(Language::err('FieldIsRequired')); // get existing fields $this->record = \SpoonSession::get('module'); if (array_key_exists('fields', $this->record)) { foreach ($this->record['fields'] as $field) { // check if we already have a type with the same label if (strtolower($field['label']) == strtolower($fields['label']->getValue())) { $fields['label']->addError(Language::err('LabelAlreadyExist')); break; } } } // for certain types, the options field is required $type = $fields['type']->getValue(); if ($type == 'dropdown' || $type == 'multicheckbox' || $type == 'radiobutton') { $fields['tags']->isFilled(Language::err('FieldIsRequired')); // check if the default field is one of the options if ($fields['default']->isFilled()) { $options = explode(',', $fields['tags']->getValue()); if (!in_array($fields['default']->getValue(), $options)) { $fields['default']->addError(Language::err('DefaultShouldBeAnOption')); } } elseif ($type == 'radiobutton') { $fields['default']->addError(Language::err('FieldIsRequired')); } } // if the type is images, the options should be in the form 200x200 seperated by a comma if ($type == 'image') { $fields['tags']->isFilled(Language::err('FieldIsRequired')); $tags = explode(',', $fields['tags']->getValue()); // loop all tags and check on format, example (400x400) foreach ($tags as $tag) { if (!preg_match('\'([1-9][0-9]*x[1-9][0-9]*|x[1-9][0-9]*|[1-9][0-9]*x)\'', $tag)) { $fields['tags']->addError(Language::err('ImageSizeNotWellFormed')); break; } } } // check if the default value is valid if ($fields['default']->isFilled()) { // get default value $defaultValue = $fields['default']->getValue(); // check the default values if ($type == 'text' || $type == 'password' || $type == 'file' || $type == 'image') { if (strlen($defaultValue) > 255) { $fields['default']->addError(Language::err('Max255Characters')); } } elseif ($type == 'number') { if (!is_numeric($defaultValue)) { $fields['default']->addError(Language::err('FieldIsNotNumeric')); } } elseif ($type == 'datetime') { if (!BackendModuleMakerHelper::isValidDateTime($defaultValue)) { $fields['default']->addError(Language::err('FieldIsNotAValidDateTime')); } } elseif ($type == 'checkbox') { if (strtoupper($defaultValue) != 'Y' && strtoupper($defaultValue) != 'N') { $fields['default']->addError(Language::err('MustBeAYOrAN')); } } } if ($this->frm->isCorrect()) { // create the item $item['label'] = strtolower($fields['label']->getValue()); $item['type'] = $type; $item['options'] = $fields['tags']->getValue(); $item['required'] = $fields['required']->isChecked(); $item['default'] = $fields['default']->getValue(); $item['camel_cased_label'] = BackendModuleMakerHelper::buildCamelCasedName($item['label']); $item['underscored_label'] = BackendModuleMakerHelper::buildUnderscoredName($item['label']); $item['lower_ccased_label'] = BackendModuleMakerHelper::buildLowerCamelCasedName($item['label']); $item['meta'] = false; $item['searchable'] = false; if ($item['type'] == 'image' && $fields['caption']->isChecked()) { $item['type'] = 'image_caption'; } // generate the SQL for the field $item['sql'] = $this->generateSQL($item); // if the record has no fields key yet, add it if (!array_key_exists('fields', $this->record)) { $this->record['fields'] = array(); } // add the item to the fields array of the record $this->record['fields'][] = $item; // save \SpoonSession::set('module', $this->record); $this->redirect(Model::createURLForAction('AddStep2')); } } }
/** * Validate the form. */ private function validateForm() { // submitted if ($this->frm->isSubmitted()) { // does the key exists? if (\SpoonSession::exists('formbuilder_' . $this->item['id'])) { // calculate difference $diff = time() - (int) \SpoonSession::get('formbuilder_' . $this->item['id']); // calculate difference, it it isn't 10 seconds the we tell the user to slow down if ($diff < 10 && $diff != 0) { $this->frm->addError(FL::err('FormTimeout')); } } // validate fields foreach ($this->item['fields'] as $field) { // field name $fieldName = 'field' . $field['id']; // skip if ($field['type'] == 'submit' || $field['type'] == 'paragraph' || $field['type'] == 'heading') { continue; } // loop other validations foreach ($field['validations'] as $rule => $settings) { // already has an error so skip if ($this->frm->getField($fieldName)->getErrors() !== null) { continue; } // required if ($rule == 'required') { $this->frm->getField($fieldName)->isFilled($settings['error_message']); } elseif ($rule == 'email') { // only check this if the field is filled, if the field is required it will be validated before if ($this->frm->getField($fieldName)->isFilled()) { $this->frm->getField($fieldName)->isEmail($settings['error_message']); } } elseif ($rule == 'numeric') { // only check this if the field is filled, if the field is required it will be validated before if ($this->frm->getField($fieldName)->isFilled()) { $this->frm->getField($fieldName)->isNumeric($settings['error_message']); } } elseif ($rule == 'time') { $regexTime = '/^(([0-1][0-9]|2[0-3]|[0-9])|([0-1][0-9]|2[0-3]|[0-9])(:|h)[0-5]?[0-9]?)$/'; if (!\SpoonFilter::isValidAgainstRegexp($regexTime, $this->frm->getField($fieldName)->getValue())) { $this->frm->getField($fieldName)->setError($settings['error_message']); } } } } // valid form if ($this->frm->isCorrect()) { // item $data['form_id'] = $this->item['id']; $data['session_id'] = \SpoonSession::getSessionId(); $data['sent_on'] = FrontendModel::getUTCDate(); $data['data'] = serialize(array('server' => $_SERVER)); // insert data $dataId = FrontendFormBuilderModel::insertData($data); // init fields array $fields = array(); // loop all fields foreach ($this->item['fields'] as $field) { // skip if ($field['type'] == 'submit' || $field['type'] == 'paragraph' || $field['type'] == 'heading') { continue; } // field data $fieldData['data_id'] = $dataId; $fieldData['label'] = $field['settings']['label']; $fieldData['value'] = $this->frm->getField('field' . $field['id'])->getValue(); if ($field['type'] == 'radiobutton') { $values = array(); foreach ($field['settings']['values'] as $value) { $values[$value['value']] = $value['label']; } $fieldData['value'] = $values[$fieldData['value']]; } // clean up if (is_array($fieldData['value']) && empty($fieldData['value'])) { $fieldData['value'] = null; } // serialize if ($fieldData['value'] !== null) { $fieldData['value'] = serialize($fieldData['value']); } // save fields data $fields[$field['id']] = $fieldData; // insert FrontendFormBuilderModel::insertDataField($fieldData); } $this->get('event_dispatcher')->dispatch(FormBuilderEvents::FORM_SUBMITTED, new FormBuilderSubmittedEvent($this->item, $fields, $dataId)); // trigger event FrontendModel::triggerEvent('FormBuilder', 'after_submission', array('form_id' => $this->item['id'], 'data_id' => $dataId, 'data' => $data, 'fields' => $fields, 'visitorId' => FrontendModel::getVisitorId())); // store timestamp in session so we can block excessive usage \SpoonSession::set('formbuilder_' . $this->item['id'], time()); // redirect $redirect = SITE_URL . $this->URL->getQueryString(); $redirect .= stripos($redirect, '?') === false ? '?' : '&'; $redirect .= 'identifier=' . $this->item['identifier']; $redirect .= '#' . $this->formName; throw new RedirectException('Redirect', new RedirectResponse($redirect)); } else { // not correct, show errors // global form errors set if ($this->frm->getErrors() != '') { $this->tpl->assign('formBuilderError', $this->frm->getErrors()); } else { // general error $this->tpl->assign('formBuilderError', FL::err('FormError')); } } } }
/** * Validate the form. */ private function validateForm() { // submitted if ($this->frm->isSubmitted()) { // does the key exists? if (SpoonSession::exists('formbuilder_' . $this->item['id'])) { // calculate difference $diff = time() - (int) SpoonSession::get('formbuilder_' . $this->item['id']); // calculate difference, it it isn't 10 seconds the we tell the user to slow down if ($diff < 10 && $diff != 0) { $this->frm->addError(FL::err('FormTimeout')); } } // validate fields foreach ($this->item['fields'] as $field) { // fieldname $fieldName = 'field' . $field['id']; // skip if ($field['type'] == 'submit' || $field['type'] == 'paragraph' || $field['type'] == 'heading') { continue; } // loop other validations foreach ($field['validations'] as $rule => $settings) { // already has an error so skip if ($this->frm->getField($fieldName)->getErrors() !== null) { continue; } // required if ($rule == 'required') { $this->frm->getField($fieldName)->isFilled($settings['error_message']); } elseif ($rule == 'email') { // only check this if the field is filled, if the field is required it will be validated before if ($this->frm->getField($fieldName)->isFilled()) { $this->frm->getField($fieldName)->isEmail($settings['error_message']); } } elseif ($rule == 'numeric') { // only check this if the field is filled, if the field is required it will be validated before if ($this->frm->getField($fieldName)->isFilled()) { $this->frm->getField($fieldName)->isNumeric($settings['error_message']); } } } } // valid form if ($this->frm->isCorrect()) { // item $data['form_id'] = $this->item['id']; $data['session_id'] = SpoonSession::getSessionId(); $data['sent_on'] = FrontendModel::getUTCDate(); $data['data'] = serialize(array('server' => $_SERVER)); // insert data $dataId = FrontendFormBuilderModel::insertData($data); // init fields array $fields = array(); // loop all fields foreach ($this->item['fields'] as $field) { // skip if ($field['type'] == 'submit' || $field['type'] == 'paragraph' || $field['type'] == 'heading') { continue; } // field data $fieldData['data_id'] = $dataId; $fieldData['label'] = $field['settings']['label']; $fieldData['value'] = $this->frm->getField('field' . $field['id'])->getValue(); // prepare fields for email if ($this->item['method'] == 'database_email') { // add field for email $emailFields[] = array('label' => $field['settings']['label'], 'value' => is_array($fieldData['value']) ? implode(',', $fieldData['value']) : nl2br($fieldData['value'])); } // clean up if (is_array($fieldData['value']) && empty($fieldData['value'])) { $fieldData['value'] = null; } // serialize if ($fieldData['value'] !== null) { $fieldData['value'] = serialize($fieldData['value']); } // save fields data $fields[] = $fieldData; // insert FrontendFormBuilderModel::insertDataField($fieldData); } // need to send mail if ($this->item['method'] == 'database_email') { // build variables $variables['sentOn'] = time(); $variables['name'] = $this->item['name']; $variables['fields'] = $emailFields; // loop recipients foreach ($this->item['email'] as $address) { // add email FrontendMailer::addEmail(sprintf(FL::getMessage('FormBuilderSubject'), $this->item['name']), FRONTEND_MODULES_PATH . '/form_builder/layout/templates/mails/form.tpl', $variables, $address, $this->item['name']); } } // trigger event FrontendModel::triggerEvent('form_builder', 'after_submission', array('form_id' => $this->item['id'], 'data_id' => $dataId, 'data' => $data, 'fields' => $fields, 'visitorId' => FrontendModel::getVisitorId())); // store timestamp in session so we can block excesive usage SpoonSession::set('formbuilder_' . $this->item['id'], time()); // redirect $redirect = SITE_URL . '/' . $this->URL->getQueryString(); $redirect .= stripos($redirect, '?') === false ? '?' : '&'; $redirect .= 'identifier=' . $this->item['identifier']; // redirect with identifier SpoonHTTP::redirect($redirect); } else { // global form errors set if ($this->frm->getErrors() != '') { $this->tpl->assign('formBuilderError', $this->frm->getErrors()); } else { $this->tpl->assign('formBuilderError', FL::err('FormError')); } } } }
/** * Logsout the current user * * @return void */ public static function logout() { // remove all rows owned by the current user BackendModel::getDB(true)->delete('users_sessions', 'session_id = ?', SpoonSession::getSessionId()); // reset values. We can't destroy the session because session-data can be used on the site. SpoonSession::set('backend_logged_in', false); SpoonSession::set('backend_secret_key', ''); }
/** * Validate the form based on the variables in $_POST */ private function validateForm() { // form submitted if ($this->frm->isSubmitted()) { // multiple languages if ($this->frm->getField('language_type')->getValue() == 'multiple') { // list of languages $languages = $this->frm->getField('languages')->getValue(); // default language if (!in_array($this->frm->getField('default_language')->getValue(), $languages)) { $this->frm->getField('default_language')->setError('Your default language needs to be in the list of languages you chose.'); } } else { // list of languages $languages = (array) array($this->frm->getField('default_language')->getValue()); } // same cms interface language if ($this->frm->getField('same_interface_language')->getChecked()) { // list of languages $interfaceLanguages = $languages; } else { // list of languages $interfaceLanguages = $this->frm->getField('interface_languages')->getValue(); } // default language if (!in_array($this->frm->getField('default_interface_language')->getValue(), $interfaceLanguages)) { $this->frm->getField('default_interface_language')->setError('Your default language needs to be in the list of languages you chose.'); } // all valid if ($this->frm->isCorrect()) { // set languages SpoonSession::set('default_language', $this->frm->getField('default_language')->getValue()); SpoonSession::set('default_interface_language', $this->frm->getField('default_interface_language')->getValue()); SpoonSession::set('multiple_languages', $this->frm->getField('language_type')->getValue() == 'multiple' ? true : false); SpoonSession::set('languages', $languages); SpoonSession::set('interface_languages', $interfaceLanguages); // redirect SpoonHTTP::redirect('index.php?step=4'); } } }
/** * Validate the form based on the variables in $_POST */ private function validateForm() { // form submitted if ($this->frm->isSubmitted()) { // database settings $this->frm->getField('hostname')->isFilled('This field is required.'); $this->frm->getField('database')->isFilled('This field is required.'); $this->frm->getField('username')->isFilled('This field is required.'); $this->frm->getField('password')->isFilled('This field is required.'); // all filled out if ($this->frm->getField('hostname')->isFilled() && $this->frm->getField('database')->isFilled() && $this->frm->getField('username')->isFilled() && $this->frm->getField('password')->isFilled()) { // test the database connection details try { // get port $port = $this->frm->getField('port')->isFilled() ? $this->frm->getField('port')->getValue() : 3306; // create instance $db = new SpoonDatabase('mysql', $this->frm->getField('hostname')->getValue(), $this->frm->getField('username')->getValue(), $this->frm->getField('password')->getValue(), $this->frm->getField('database')->getValue(), $port); // test table $table = 'test' . time(); // attempt to create table $db->execute('DROP TABLE IF EXISTS ' . $table); $db->execute('CREATE TABLE ' . $table . ' (id int(11) NOT NULL) ENGINE=MyISAM'); // drop table $db->drop($table); } catch (Exception $e) { // add errors $this->frm->addError('Problem with database credentials'); // show error $this->tpl->assign('formError', $e->getMessage()); } // all valid if ($this->frm->isCorrect()) { // update session SpoonSession::set('db_hostname', $this->frm->getField('hostname')->getValue()); SpoonSession::set('db_database', $this->frm->getField('database')->getValue()); SpoonSession::set('db_username', $this->frm->getField('username')->getValue()); SpoonSession::set('db_password', $this->frm->getField('password')->getValue()); SpoonSession::set('db_port', $this->frm->getField('port')->getValue()); // redirect SpoonHTTP::redirect('index.php?step=6'); } } } }
/** * Save statistics */ private function saveStatistics() { // no search term = no search if (!$this->term) { return; } // previous search result $previousTerm = \SpoonSession::exists('searchTerm') ? \SpoonSession::get('searchTerm') : ''; \SpoonSession::set('searchTerm', ''); // save this term? if ($previousTerm != $this->term) { // format data $this->statistics = array(); $this->statistics['term'] = $this->term; $this->statistics['language'] = LANGUAGE; $this->statistics['time'] = FrontendModel::getUTCDate(); $this->statistics['data'] = serialize(array('server' => $_SERVER)); $this->statistics['num_results'] = $this->pagination['num_items']; // save data FrontendSearchModel::save($this->statistics); } // save current search term in cookie \SpoonSession::set('searchTerm', $this->term); }
/** * Set the dates based on GET and SESSION * GET has priority and overwrites SESSION * * @return void */ public static function setDates() { // init vars with session data $startTimestamp = SpoonSession::exists('analytics_start_timestamp') ? SpoonSession::get('analytics_start_timestamp') : null; $endTimestamp = SpoonSession::exists('analytics_end_timestamp') ? SpoonSession::get('analytics_end_timestamp') : null; // overwrite with get data if needed if (isset($_GET['start_timestamp']) && $_GET['start_timestamp'] != '' && isset($_GET['end_timestamp']) && $_GET['end_timestamp'] != '') { // get dates $startTimestamp = (int) $_GET['start_timestamp']; $endTimestamp = (int) $_GET['end_timestamp']; } // dates are set if ($startTimestamp > 0 && $endTimestamp > 0) { // init valid $valid = true; // check startTimestamp (valid year/month/day) if (!checkdate((int) date('n', $startTimestamp), (int) date('j', $startTimestamp), (int) date('Y', $startTimestamp))) { $valid = false; } elseif (!checkdate((int) date('n', $endTimestamp), (int) date('j', $endTimestamp), (int) date('Y', $endTimestamp))) { $valid = false; } else { // start needs to be before end if ($startTimestamp > $endTimestamp) { $valid = false; } elseif ($startTimestamp < mktime(0, 0, 0, 1, 1, 2005)) { $valid = false; } elseif ($endTimestamp > time()) { $valid = false; } } // valid dates if ($valid) { // set sessions SpoonSession::set('analytics_start_timestamp', $startTimestamp); SpoonSession::set('analytics_end_timestamp', $endTimestamp); } } else { // get interval $interval = BackendModel::getModuleSetting('analytics', 'interval', 'week'); if ($interval == 'week') { $interval .= ' -1 days'; } // set sessions SpoonSession::set('analytics_start_timestamp', strtotime('-1' . $interval, mktime(0, 0, 0))); SpoonSession::set('analytics_end_timestamp', mktime(0, 0, 0)); } }
/** * Install a module. * * @param string $module The name of the module to be installed. * @param array $information Warnings from the upload of the module. */ public static function installModule($module, array $warnings = array()) { // we need the installer require_once BACKEND_CORE_PATH . '/installer/installer.php'; require_once BACKEND_MODULES_PATH . '/' . $module . '/installer/installer.php'; // installer class name $class = SpoonFilter::toCamelCase($module) . 'Installer'; // possible variables available for the module installers $variables = array(); // run installer $installer = new $class(BackendModel::getDB(true), BL::getActiveLanguages(), array_keys(BL::getInterfaceLanguages()), false, $variables); // execute installation $installer->install(); // add the warnings foreach ($warnings as $warning) { $installer->addWarning($warning); } // save the warnings in session for later use if ($installer->getWarnings()) { $warnings = SpoonSession::exists('installer_warnings') ? SpoonSession::get('installer_warnings') : array(); $warnings = array_merge($warnings, array('module' => $module, 'warnings' => $installer->getWarnings())); SpoonSession::set('installer_warnings', $warnings); } // clear the cache so locale (and so much more) gets rebuilt self::clearCache(); }
/** * Redirect to the loading page after checking for infinite loops. * * @return void * @param string $action The action to check for infinite loops. * @param array[optional] $extraParameters The extra parameters to append to the redirect url. */ public static function redirectToLoadingPage($action, array $extraParameters = array()) { // get loop counter $counter = SpoonSession::exists($action . 'Loop') ? SpoonSession::get($action . 'Loop') : 0; // loop has run too long - throw exception if ($counter > 2) { throw new BackendException('An infinite loop has been detected while getting data from cache for the action "' . $action . '".'); } // set new counter SpoonSession::set($action . 'Loop', ++$counter); // put parameters into a string $extraParameters = empty($extraParameters) ? '' : '&' . http_build_query($extraParameters); // redirect to loading page which will get the needed data based on the current action SpoonHTTP::redirect(BackendModel::createURLForAction('loading') . '&redirect_action=' . $action . $extraParameters); }
/** * Set Param to Session * * @param string $adminname Admin's Name * @param string $adminpw Admin's Password * @param string $expired Admin's Session Length */ private static function setSession($adminname, $adminpw, $expired) { SpoonSession::set('adminname', $adminname); SpoonSession::set('adminpw', $adminpw); SpoonSession::set('expiredTime', time() + $expired); }
/** * Validate the form */ private function validateForm() { // get settings $commentsAllowed = isset($this->settings['allow_comments']) && $this->settings['allow_comments']; // comments aren't allowed so we don't have to validate if (!$commentsAllowed) { return false; } // is the form submitted if ($this->frm->isSubmitted()) { // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); // does the key exists? if (SpoonSession::exists('blog_comment_' . $this->record['id'])) { // calculate difference $diff = time() - (int) SpoonSession::get('blog_comment_' . $this->record['id']); // calculate difference, it it isn't 10 seconds the we tell the user to slow down if ($diff < 10 && $diff != 0) { $this->frm->getField('message')->addError(FL::err('CommentTimeout')); } } // validate required fields $this->frm->getField('author')->isFilled(FL::err('AuthorIsRequired')); $this->frm->getField('email')->isEmail(FL::err('EmailIsRequired')); $this->frm->getField('message')->isFilled(FL::err('MessageIsRequired')); // validate optional fields if ($this->frm->getField('website')->isFilled() && $this->frm->getField('website')->getValue() != 'http://') { $this->frm->getField('website')->isURL(FL::err('InvalidURL')); } // no errors? if ($this->frm->isCorrect()) { // get module setting $spamFilterEnabled = isset($this->settings['spamfilter']) && $this->settings['spamfilter']; $moderationEnabled = isset($this->settings['moderation']) && $this->settings['moderation']; // reformat data $author = $this->frm->getField('author')->getValue(); $email = $this->frm->getField('email')->getValue(); $website = $this->frm->getField('website')->getValue(); if (trim($website) == '' || $website == 'http://') { $website = null; } $text = $this->frm->getField('message')->getValue(); // build array $comment['post_id'] = $this->record['id']; $comment['language'] = FRONTEND_LANGUAGE; $comment['created_on'] = FrontendModel::getUTCDate(); $comment['author'] = $author; $comment['email'] = $email; $comment['website'] = $website; $comment['text'] = $text; $comment['status'] = 'published'; $comment['data'] = serialize(array('server' => $_SERVER)); // get URL for article $permaLink = FrontendNavigation::getURLForBlock('blog', 'detail') . '/' . $this->record['url']; $redirectLink = $permaLink; // is moderation enabled if ($moderationEnabled) { // if the commenter isn't moderated before alter the comment status so it will appear in the moderation queue if (!FrontendBlogModel::isModerated($author, $email)) { $comment['status'] = 'moderation'; } } // should we check if the item is spam if ($spamFilterEnabled) { // check for spam $result = FrontendModel::isSpam($text, SITE_URL . $permaLink, $author, $email, $website); // if the comment is spam alter the comment status so it will appear in the spam queue if ($result) { $comment['status'] = 'spam'; } elseif ($result == 'unknown') { $comment['status'] = 'moderation'; } } // insert comment $comment['id'] = FrontendBlogModel::insertComment($comment); // trigger event FrontendModel::triggerEvent('blog', 'after_add_comment', array('comment' => $comment)); // append a parameter to the URL so we can show moderation if (strpos($redirectLink, '?') === false) { if ($comment['status'] == 'moderation') { $redirectLink .= '?comment=moderation#' . FL::act('Comment'); } if ($comment['status'] == 'spam') { $redirectLink .= '?comment=spam#' . FL::act('Comment'); } if ($comment['status'] == 'published') { $redirectLink .= '?comment=true#comment-' . $comment['id']; } } else { if ($comment['status'] == 'moderation') { $redirectLink .= '&comment=moderation#' . FL::act('Comment'); } if ($comment['status'] == 'spam') { $redirectLink .= '&comment=spam#' . FL::act('Comment'); } if ($comment['status'] == 'published') { $redirectLink .= '&comment=true#comment-' . $comment['id']; } } // set title $comment['post_title'] = $this->record['title']; $comment['post_url'] = $this->record['url']; // notify the admin FrontendBlogModel::notifyAdmin($comment); // store timestamp in session so we can block excesive usage SpoonSession::set('blog_comment_' . $this->record['id'], time()); // store author-data in cookies try { SpoonCookie::set('comment_author', $author, 30 * 24 * 60 * 60, '/', '.' . $this->URL->getDomain()); SpoonCookie::set('comment_email', $email, 30 * 24 * 60 * 60, '/', '.' . $this->URL->getDomain()); SpoonCookie::set('comment_website', $website, 30 * 24 * 60 * 60, '/', '.' . $this->URL->getDomain()); } catch (Exception $e) { // settings cookies isn't allowed, but because this isn't a real problem we ignore the exception } // redirect $this->redirect($redirectLink); } } }
/** * Logout a profile. */ public static function logout() { // delete session records FrontendModel::getContainer()->get('database')->delete('profiles_sessions', 'session_id = ?', array(\SpoonSession::getSessionId())); // set is_logged_in to false \SpoonSession::set('frontend_profile_logged_in', false); // delete cookie CommonCookie::delete('frontend_profile_secret_key'); }
/** * Process the query string */ private function processQueryString() { // store the query string local, so we don't alter it. $queryString = trim($this->request->getPathInfo(), '/'); // split into chunks $chunks = (array) explode('/', $queryString); $hasMultiLanguages = $this->getContainer()->getParameter('site.multilanguage'); // single language if (!$hasMultiLanguages) { // set language id $language = $this->get('fork.settings')->get('Core', 'default_language', SITE_DEFAULT_LANGUAGE); } else { // multiple languages // default value $mustRedirect = false; // get possible languages $possibleLanguages = (array) Language::getActiveLanguages(); $redirectLanguages = (array) Language::getRedirectLanguages(); // the language is present in the URL if (isset($chunks[0]) && in_array($chunks[0], $possibleLanguages)) { // define language $language = (string) $chunks[0]; // try to set a cookie with the language try { // set cookie CommonCookie::set('frontend_language', $language); } catch (\SpoonCookieException $e) { // settings cookies isn't allowed, because this isn't a real problem we ignore the exception } // set sessions \SpoonSession::set('frontend_language', $language); // remove the language part array_shift($chunks); } elseif (CommonCookie::exists('frontend_language') && in_array(CommonCookie::get('frontend_language'), $redirectLanguages)) { // set languageId $language = (string) CommonCookie::get('frontend_language'); // redirect is needed $mustRedirect = true; } else { // default browser language // set languageId & abbreviation $language = Language::getBrowserLanguage(); // try to set a cookie with the language try { // set cookie CommonCookie::set('frontend_language', $language); } catch (\SpoonCookieException $e) { // settings cookies isn't allowed, because this isn't a real problem we ignore the exception } // redirect is needed $mustRedirect = true; } // redirect is required if ($mustRedirect) { // build URL // trim the first / from the query string to prevent double slashes $url = rtrim('/' . $language . '/' . trim($this->getQueryString(), '/'), '/'); // when we are just adding the language to the domain, it's a temporary redirect because // Safari keeps the 301 in cache, so the cookie to switch language doesn't work any more $redirectCode = $url == '/' . $language ? 302 : 301; // set header & redirect throw new RedirectException('Redirect', new RedirectResponse($url, $redirectCode)); } } // define the language defined('FRONTEND_LANGUAGE') || define('FRONTEND_LANGUAGE', $language); defined('LANGUAGE') || define('LANGUAGE', $language); // sets the locale file Language::setLocale($language); // list of pageIds & their full URL $keys = Navigation::getKeys(); // rebuild our URL, but without the language parameter. (it's tripped earlier) $url = implode('/', $chunks); $startURL = $url; // loop until we find the URL in the list of pages while (!in_array($url, $keys)) { // remove the last chunk array_pop($chunks); // redefine the URL $url = implode('/', $chunks); } // remove language from query string if ($hasMultiLanguages) { $queryString = trim(mb_substr($queryString, mb_strlen($language)), '/'); } // if it's the homepage AND parameters were given (not allowed!) if ($url == '' && $queryString != '') { // get 404 URL $url = Navigation::getURL(404); // remove language if ($hasMultiLanguages) { $url = str_replace('/' . $language, '', $url); } } // set pages $url = trim($url, '/'); // currently not in the homepage if ($url != '') { // explode in pages $pages = explode('/', $url); // reset pages $this->setPages($pages); // reset parameters $this->setParameters(array()); } // set parameters $parameters = trim(mb_substr($startURL, mb_strlen($url)), '/'); // has at least one parameter if ($parameters != '') { // parameters will be separated by / $parameters = explode('/', $parameters); // set parameters $this->setParameters($parameters); } // pageId, parentId & depth $pageId = Navigation::getPageId(implode('/', $this->getPages())); $pageInfo = Navigation::getPageInfo($pageId); // invalid page, or parameters but no extra if ($pageInfo === false || !empty($parameters) && !$pageInfo['has_extra']) { // get 404 URL $url = Navigation::getURL(404); // remove language if ($hasMultiLanguages) { $url = str_replace('/' . $language, '', $url); } // remove the first slash $url = trim($url, '/'); // currently not in the homepage if ($url != '') { // explode in pages $pages = explode('/', $url); // reset pages $this->setPages($pages); // reset parameters $this->setParameters(array()); } } // is this an internal redirect? if (isset($pageInfo['redirect_page_id']) && $pageInfo['redirect_page_id'] != '') { // get url for item $newPageURL = Navigation::getURL((int) $pageInfo['redirect_page_id']); $errorURL = Navigation::getURL(404); // not an error? if ($newPageURL != $errorURL) { // redirect throw new RedirectException('Redirect', new RedirectResponse($newPageURL, $pageInfo['redirect_code'])); } } // is this an external redirect? if (isset($pageInfo['redirect_url']) && $pageInfo['redirect_url'] != '') { // redirect throw new RedirectException('Redirect', new RedirectResponse($pageInfo['redirect_url'], $pageInfo['redirect_code'])); } }
/** * Get the token which will protect us * * @return string */ public static function getToken() { if (\SpoonSession::exists('csrf_token') && \SpoonSession::get('csrf_token') != '') { $token = \SpoonSession::get('csrf_token'); } else { $token = self::generateRandomString(10, true, true, false, false); \SpoonSession::set('csrf_token', $token); } return $token; }
/** * Get a token * * @return string */ public function getToken() { if (!SpoonSession::exists('form_token')) { $token = md5(SpoonSession::getSessionId() . rand(0, 999) . time()); SpoonSession::set('form_token', $token); } return SpoonSession::get('form_token'); }
/** * Validate the forms */ private function validateForm() { if ($this->frm->isSubmitted()) { $txtEmail = $this->frm->getField('backend_email'); $txtPassword = $this->frm->getField('backend_password'); // required fields if (!$txtEmail->isFilled() || !$txtPassword->isFilled()) { // add error $this->frm->addError('fields required'); // show error $this->tpl->assign('hasError', true); } // invalid form-token? if ($this->frm->getToken() != $this->frm->getField('form_token')->getValue()) { // set a correct header, so bots understand they can't mess with us. if (!headers_sent()) { header('400 Bad Request', true, 400); } } // all fields are ok? if ($txtEmail->isFilled() && $txtPassword->isFilled() && $this->frm->getToken() == $this->frm->getField('form_token')->getValue()) { // try to login the user if (!BackendAuthentication::loginUser($txtEmail->getValue(), $txtPassword->getValue())) { // add error $this->frm->addError('invalid login'); // store attempt in session $current = SpoonSession::exists('backend_login_attempts') ? (int) SpoonSession::get('backend_login_attempts') : 0; // increment and store SpoonSession::set('backend_login_attempts', ++$current); // show error $this->tpl->assign('hasError', true); } } // check sessions if (SpoonSession::exists('backend_login_attempts') && (int) SpoonSession::get('backend_login_attempts') >= 5) { // get previous attempt $previousAttempt = SpoonSession::exists('backend_last_attempt') ? SpoonSession::get('backend_last_attempt') : time(); // calculate timeout $timeout = 5 * (SpoonSession::get('backend_login_attempts') - 4); // too soon! if (time() < $previousAttempt + $timeout) { // sleep untill the user can login again sleep($timeout); // set a correct header, so bots understand they can't mess with us. if (!headers_sent()) { header('503 Service Unavailable', true, 503); } } else { // increment and store SpoonSession::set('backend_last_attempt', time()); } // too many attempts $this->frm->addEditor('too many attempts'); // show error $this->tpl->assign('hasTooManyAttemps', true); $this->tpl->assign('hasError', false); } // no errors in the form? if ($this->frm->isCorrect()) { // cleanup sessions SpoonSession::delete('backend_login_attempts'); SpoonSession::delete('backend_last_attempt'); // create filter with modules which may not be displayed $filter = array('authentication', 'error', 'core'); // get all modules $modules = array_diff(BackendModel::getModules(), $filter); // loop through modules and break on first allowed module foreach ($modules as $module) { if (BackendAuthentication::isAllowedModule($module)) { break; } } // redirect to the correct URL (URL the user was looking for or fallback) $this->redirect($this->getParameter('querystring', 'string', BackendModel::createUrlForAction(null, $module))); } } // is the form submitted if ($this->frmForgotPassword->isSubmitted()) { // backend email $email = $this->frmForgotPassword->getField('backend_email_forgot')->getValue(); // required fields if ($this->frmForgotPassword->getField('backend_email_forgot')->isEmail(BL::err('EmailIsInvalid'))) { // check if there is a user with the given emailaddress if (!BackendUsersModel::existsEmail($email)) { $this->frmForgotPassword->getField('backend_email_forgot')->addError(BL::err('EmailIsUnknown')); } } // no errors in the form? if ($this->frmForgotPassword->isCorrect()) { // generate the key for the reset link and fetch the user ID for this email $key = BackendAuthentication::getEncryptedString($email, uniqid()); // insert the key and the timestamp into the user settings $userId = BackendUsersModel::getIdByEmail($email); $user = new BackendUser($userId); $user->setSetting('reset_password_key', $key); $user->setSetting('reset_password_timestamp', time()); // variables to parse in the e-mail $variables['resetLink'] = SITE_URL . BackendModel::createURLForAction('reset_password') . '&email=' . $email . '&key=' . $key; // send e-mail to user BackendMailer::addEmail(SpoonFilter::ucfirst(BL::msg('ResetYourPasswordMailSubject')), BACKEND_MODULE_PATH . '/layout/templates/mails/reset_password.tpl', $variables, $email); // clear post-values $_POST['backend_email_forgot'] = ''; // show success message $this->tpl->assign('isForgotPasswordSuccess', true); // show form $this->tpl->assign('showForm', true); } else { $this->tpl->assign('showForm', true); } } }
/** * Validate the forms */ private function validateForm() { if ($this->frm->isSubmitted()) { $txtEmail = $this->frm->getField('backend_email'); $txtPassword = $this->frm->getField('backend_password'); // required fields if (!$txtEmail->isFilled() || !$txtPassword->isFilled()) { // add error $this->frm->addError('fields required'); // show error $this->tpl->assign('hasError', true); } $this->getContainer()->get('logger')->info("Trying to authenticate user '{$txtEmail->getValue()}'."); // invalid form-token? if ($this->frm->getToken() != $this->frm->getField('form_token')->getValue()) { // set a correct header, so bots understand they can't mess with us. if (!headers_sent()) { header('400 Bad Request', true, 400); } } // get the user's id $userId = BackendUsersModel::getIdByEmail($txtEmail->getValue()); // all fields are ok? if ($txtEmail->isFilled() && $txtPassword->isFilled() && $this->frm->getToken() == $this->frm->getField('form_token')->getValue()) { // try to login the user if (!BackendAuthentication::loginUser($txtEmail->getValue(), $txtPassword->getValue())) { $this->getContainer()->get('logger')->info("Failed authenticating user '{$txtEmail->getValue()}'."); // add error $this->frm->addError('invalid login'); // store attempt in session $current = \SpoonSession::exists('backend_login_attempts') ? (int) \SpoonSession::get('backend_login_attempts') : 0; // increment and store \SpoonSession::set('backend_login_attempts', ++$current); // save the failed login attempt in the user's settings if ($userId !== false) { BackendUsersModel::setSetting($userId, 'last_failed_login_attempt', time()); } // show error $this->tpl->assign('hasError', true); } } // check sessions if (\SpoonSession::exists('backend_login_attempts') && (int) \SpoonSession::get('backend_login_attempts') >= 5) { // get previous attempt $previousAttempt = \SpoonSession::exists('backend_last_attempt') ? \SpoonSession::get('backend_last_attempt') : time(); // calculate timeout $timeout = 5 * (\SpoonSession::get('backend_login_attempts') - 4); // too soon! if (time() < $previousAttempt + $timeout) { // sleep until the user can login again sleep($timeout); // set a correct header, so bots understand they can't mess with us. if (!headers_sent()) { header('503 Service Unavailable', true, 503); } } else { // increment and store \SpoonSession::set('backend_last_attempt', time()); } // too many attempts $this->frm->addEditor('too many attempts'); $this->getContainer()->get('logger')->info("Too many login attempts for user '{$txtEmail->getValue()}'."); // show error $this->tpl->assign('hasTooManyAttemps', true); $this->tpl->assign('hasError', false); } // no errors in the form? if ($this->frm->isCorrect()) { // cleanup sessions \SpoonSession::delete('backend_login_attempts'); \SpoonSession::delete('backend_last_attempt'); // save the login timestamp in the user's settings $lastLogin = BackendUsersModel::getSetting($userId, 'current_login'); BackendUsersModel::setSetting($userId, 'current_login', time()); if ($lastLogin) { BackendUsersModel::setSetting($userId, 'last_login', $lastLogin); } $this->getContainer()->get('logger')->info("Successfully authenticated user '{$txtEmail->getValue()}'."); // redirect to the correct URL (URL the user was looking for or fallback) $this->redirectToAllowedModuleAndAction(); } } // is the form submitted if ($this->frmForgotPassword->isSubmitted()) { // backend email $email = $this->frmForgotPassword->getField('backend_email_forgot')->getValue(); // required fields if ($this->frmForgotPassword->getField('backend_email_forgot')->isEmail(BL::err('EmailIsInvalid'))) { // check if there is a user with the given emailaddress if (!BackendUsersModel::existsEmail($email)) { $this->frmForgotPassword->getField('backend_email_forgot')->addError(BL::err('EmailIsUnknown')); } } // no errors in the form? if ($this->frmForgotPassword->isCorrect()) { // generate the key for the reset link and fetch the user ID for this email $key = BackendAuthentication::getEncryptedString($email, uniqid()); // insert the key and the timestamp into the user settings $userId = BackendUsersModel::getIdByEmail($email); $user = new User($userId); $user->setSetting('reset_password_key', $key); $user->setSetting('reset_password_timestamp', time()); // variables to parse in the e-mail $variables['resetLink'] = SITE_URL . BackendModel::createURLForAction('ResetPassword') . '&email=' . $email . '&key=' . $key; // send e-mail to user $from = $this->get('fork.settings')->get('Core', 'mailer_from'); $replyTo = $this->get('fork.settings')->get('Core', 'mailer_reply_to'); $message = \Common\Mailer\Message::newInstance(\SpoonFilter::ucfirst(BL::msg('ResetYourPasswordMailSubject')))->setFrom(array($from['email'] => $from['name']))->setTo(array($email))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml(BACKEND_MODULES_PATH . '/Authentication/Layout/Templates/Mails/ResetPassword.tpl', $variables); $this->get('mailer')->send($message); // clear post-values $_POST['backend_email_forgot'] = ''; // show success message $this->tpl->assign('isForgotPasswordSuccess', true); // show form $this->tpl->assign('showForm', true); } else { // errors? $this->tpl->assign('showForm', true); } } }
/** * Validate the form based on the variables in $_POST */ private function validateForm() { // form submitted if ($this->frm->isSubmitted()) { // validate email address if ($this->frm->getField('different_debug_email')->isChecked()) { $this->frm->getField('debug_email')->isEmail('Please provide a valid e-mailaddress.'); } // all valid if ($this->frm->isCorrect()) { // get selected modules $modules = $this->frm->getField('modules')->getValue(); // add blog if example data was checked if ($this->frm->getField('example_data')->getChecked() && !in_array('blog', $modules)) { $modules[] = 'blog'; } // set modules SpoonSession::set('modules', $modules); // example data SpoonSession::set('example_data', $this->frm->getField('example_data')->getChecked()); // debug mode SpoonSession::set('debug_mode', $this->frm->getField('debug_mode')->getChecked()); // specific debug email address SpoonSession::set('different_debug_email', $this->frm->getField('different_debug_email')->getChecked()); // specific debug email address text SpoonSession::set('debug_email', $this->frm->getField('debug_email')->getValue()); // redirect SpoonHTTP::redirect('index.php?step=5'); } } }