├── assets └── snippets │ └── FormLister │ ├── core │ ├── lang │ │ ├── en │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── register.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── reminder.inc.php │ │ │ ├── activate.inc.php │ │ │ └── content.inc.php │ │ ├── es │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── register.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ │ ├── nl │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── register.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ │ ├── it │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── register.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ │ ├── pl │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── register.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ │ ├── uk │ │ │ ├── csrf.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── register.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── reminder.inc.php │ │ │ ├── activate.inc.php │ │ │ └── content.inc.php │ │ ├── ru │ │ │ ├── csrf.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── register.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ │ └── de │ │ │ ├── csrf.inc.php │ │ │ ├── mailchimp.inc.php │ │ │ ├── deleteUser.inc.php │ │ │ ├── register.inc.php │ │ │ ├── profile.inc.php │ │ │ ├── login.inc.php │ │ │ ├── form.inc.php │ │ │ ├── deleteContent.inc.php │ │ │ ├── activate.inc.php │ │ │ ├── reminder.inc.php │ │ │ └── content.inc.php │ └── controller │ │ ├── MailChimp.php │ │ ├── DeleteUser.php │ │ ├── DeleteContent.php │ │ ├── Login.php │ │ ├── Register.php │ │ ├── Activate.php │ │ ├── Profile.php │ │ ├── Reminder.php │ │ ├── Content.php │ │ └── Form.php │ ├── lib │ ├── captcha │ │ ├── modxCaptcha │ │ │ ├── noises │ │ │ │ ├── index.html │ │ │ │ ├── noise1.jpg │ │ │ │ ├── noise2.jpg │ │ │ │ ├── noise3.jpg │ │ │ │ └── noise4.jpg │ │ │ ├── ttf │ │ │ │ └── ftb_____.ttf │ │ │ ├── connector.php │ │ │ ├── wrapper.php │ │ │ └── modxCaptcha.php │ │ ├── Captcha.php │ │ ├── smsCaptcha │ │ │ ├── model.php │ │ │ └── wrapper.php │ │ ├── yandexCaptcha │ │ │ └── wrapper.php │ │ └── reCaptcha │ │ │ └── wrapper.php │ ├── Lexicon.php │ ├── DateConverter.php │ ├── Gpc.php │ ├── Debug.php │ ├── SubmitProtection.php │ ├── MailChimp │ │ ├── Batch.php │ │ └── MailChimp.php │ ├── Filters.php │ ├── FileValidator.php │ └── Validator.php │ ├── config │ └── core │ │ └── default.json │ ├── snippet.FormLister.php │ ├── plugin.userHelper.php │ └── __autoload.php └── install └── assets ├── snippets └── FormLister.tpl └── plugins └── userHelper.tpl /assets/snippets/FormLister/core/lang/en/csrf.inc.php: -------------------------------------------------------------------------------- 1 | 'Failed to authenticate request' 4 | ]; 5 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/lang/es/csrf.inc.php: -------------------------------------------------------------------------------- 1 | 'No se pudo autenticar la solicitud' 4 | ]; 5 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/lang/nl/csrf.inc.php: -------------------------------------------------------------------------------- 1 | 'Kan het verzoek niet verifiëren' 4 | ]; 5 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/index.html: -------------------------------------------------------------------------------- 1 |
Time: {$entry['time']}
"; 97 | $out .= 'Total time: {$time}
"; 101 | if ($out) { 102 | $this->modx->logEvent(0, 1, $out, $this->caller); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/captcha/smsCaptcha/wrapper.php: -------------------------------------------------------------------------------- 1 | cfg = $cfg; 28 | $this->modx = $modx; 29 | } 30 | 31 | /** 32 | * Устанавливает значение капчи 33 | * @return mixed 34 | */ 35 | public function init() 36 | { 37 | return; 38 | } 39 | 40 | /** 41 | * Плейсхолдер капчи для вывода в шаблон 42 | * @return string 43 | */ 44 | public function getPlaceholder() 45 | { 46 | return ''; 47 | } 48 | 49 | /** 50 | * @param \FormLister\Core $FormLister 51 | * @param $value 52 | * @param \FormLister\CaptchaInterface $captcha 53 | * @return bool|string 54 | */ 55 | public static function validate(Core $FormLister, $value, CaptchaInterface $captcha) 56 | { 57 | $id = \APIhelpers::getkey($captcha->cfg, 'id'); 58 | if (empty($value)) { 59 | return \APIhelpers::getkey($captcha->cfg, 'errorEmptyCode', 60 | 'Введите код авторизации'); 61 | } 62 | 63 | if (empty($_SESSION[$id . '.smscaptcha'])) { 64 | return \APIhelpers::getkey($captcha->cfg, 'errorCodeRequired', 65 | 'Получите код авторизации'); 66 | } 67 | 68 | $sms = $FormLister->loadModel('SmsModel'); 69 | 70 | if (is_null($sms->getData($_SESSION[$id . '.smscaptcha'], $id)->getID())) { 71 | 72 | return \APIhelpers::getkey($captcha->cfg, 'errorCodeRequired', 'Получите код авторизации'); 73 | } 74 | 75 | if ($sms->get('code') != $value) { 76 | 77 | return \APIhelpers::getkey($captcha->cfg, 'errorCodeFailed', 'Неверный код авторизации'); 78 | } 79 | 80 | if ($sms->get('expires') < time()) { 81 | $sms->delete($sms->getID()); 82 | 83 | return \APIhelpers::getkey($captcha->cfg, 'errorCodeExpired', 84 | 'Код авторизации истек, получите новый'); 85 | } else { 86 | if (!$sms->get('active')) { 87 | $sms->set('active', 0)->set('expires', time() + \APIhelpers::getkey($captcha->cfg, 'codeLifeTime', 88 | 86400))->set('ip', \APIhelpers::getUserIP())->save(); 89 | } else { 90 | 91 | return \APIhelpers::getkey($captcha->cfg, 'errorCodeUsed', 92 | 'Код авторизации уже использовался'); 93 | } 94 | $out = true; 95 | 96 | $FormLister->setField('captcha.phone', $sms->get('phone')); 97 | } 98 | $FormLister->log('Validate captcha value '.$value.' against '.$sms->get('code')); 99 | 100 | return $out; 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/DeleteUser.php: -------------------------------------------------------------------------------- 1 | lexicon->fromFile('deleteUser'); 26 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 27 | $uid = $modx->getLoginUserId('web'); 28 | $userdata = []; 29 | if ($uid) { 30 | $this->user = $this->loadModel( 31 | $this->getCFGDef('model', '\modUsers'), 32 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 33 | ); 34 | if (!is_null($this->user)) { 35 | $userdata = $this->user->edit($uid)->toArray(); 36 | unset($userdata['password']); 37 | } 38 | $this->config->setConfig([ 39 | 'ignoreMailerResult' => 1, 40 | 'keepDefaults' => 1, 41 | 'protectSubmit' => 0, 42 | 'submitLimit' => 0, 43 | 'userdata' => $userdata 44 | ]); 45 | } 46 | } 47 | 48 | /** 49 | * Загружает в formData данные не из формы 50 | * @param string $sources список источников 51 | * @param string $arrayParam название параметра с данными 52 | * @return $this 53 | */ 54 | public function setExternalFields ($sources = 'array', $arrayParam = 'defaults') 55 | { 56 | parent::setExternalFields($sources, $arrayParam); 57 | parent::setExternalFields('array', 'userdata'); 58 | 59 | return $this; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function render() 66 | { 67 | if (!$this->modx->getLoginUserID('web')) { 68 | $this->redirect('exitTo'); 69 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('deleteUser.default_skipTpl')); 70 | $this->setValid(false); 71 | }; 72 | 73 | return parent::render(); 74 | } 75 | 76 | 77 | /** 78 | * 79 | */ 80 | public function process() 81 | { 82 | $uid = (int)$this->modx->getLoginUserID('web'); 83 | if (!is_null($this->user)) { 84 | $password = $this->getField('password'); 85 | if ($this->user->testAuth($uid, $password, true)) { 86 | $result = $this->user->delete($uid, true); 87 | if ($result) { 88 | $this->user->logout(); 89 | parent::process(); 90 | } else { 91 | return $this->addMessage($this->translate('deleteUser.delete_failed')); 92 | } 93 | } 94 | } 95 | 96 | return $this->addMessage($this->translate('deleteUser.delete_failed')); 97 | } 98 | 99 | /** 100 | * 101 | */ 102 | public function postProcess() 103 | { 104 | parent::postProcess(); 105 | $this->renderTpl = $this->getCFGDef('successTpl', $this->translate('deleteUser.default_successTpl')); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/DeleteContent.php: -------------------------------------------------------------------------------- 1 | content = $this->loadModel( 35 | $this->getCFGDef('model', '\modResource'), 36 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modResource.php') 37 | ); 38 | $this->user = $this->loadModel( 39 | $this->getCFGDef('model', '\modUsers'), 40 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 41 | ); 42 | $this->lexicon->fromFile('deleteContent'); 43 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 44 | $idField = $this->getCFGDef('idField','id'); 45 | if (isset($_REQUEST[$idField]) && is_scalar($_REQUEST[$idField])) { 46 | $this->id = (int)$_REQUEST[$idField]; 47 | } 48 | $this->config->setConfig([ 49 | 'ignoreMailerResult' => 1, 50 | 'protectSubmit' => 0, 51 | 'submitLimit' => 0 52 | ]); 53 | } 54 | 55 | /** 56 | * @return string 57 | */ 58 | public function render() 59 | { 60 | $flag = false; 61 | $uid = $this->modx->getLoginUserID('web'); 62 | if (!$uid) { 63 | $this->redirect('exitTo'); 64 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('deleteContent.default_skipTpl')); 65 | } elseif (!$this->id || !$this->content->edit($this->id)->getID() || $this->content->get('deleted')) { 66 | $this->redirect('badRecordTo'); 67 | $this->renderTpl = $this->getCFGDef('badRecordTpl', 68 | $this->translate('deleteContent.default_badRecordTpl')); 69 | } elseif ($uid != $this->content->edit($this->id)->get($this->getCFGDef('ownerField','aid'))) { 70 | $this->renderTpl = $this->getCFGDef('badOwnerTpl', 71 | $this->translate('deleteContent.default_badOwnerTpl')); 72 | } else { 73 | $flag = true; 74 | $this->setFields($this->content->edit($this->id)->toArray()); 75 | $this->setFields($this->user->edit($uid)->toArray(),'user'); 76 | }; 77 | $this->setValid($flag); 78 | 79 | return parent::render(); 80 | } 81 | 82 | 83 | /** 84 | * 85 | * @throws \Exception 86 | */ 87 | public function process() 88 | { 89 | $result = $this->content->delete($this->id, true); 90 | if ($result) { 91 | return parent::process(); 92 | } else { 93 | return $this->addMessage($this->translate('deleteContent.delete_failed')); 94 | } 95 | } 96 | 97 | public function postProcess() 98 | { 99 | parent::postProcess(); 100 | $this->renderTpl = $this->getCFGDef('successTpl', $this->translate('deleteContent.default_successTpl')); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/plugin.userHelper.php: -------------------------------------------------------------------------------- 1 | event; 9 | if (!class_exists('\\FormLister\\Core')) { 10 | include_once(MODX_BASE_PATH . 'assets/snippets/FormLister/__autoload.php'); 11 | } 12 | if (($e->name == 'OnWebAuthentication' || $e->name == 'OnUserAuthentication') && isset($userObj)) { 13 | /** 14 | * @var modUsers $userObj 15 | */ 16 | if ($savedpassword != $userObj->getPassword($userpassword)) { 17 | $fails = (int)$userObj->get('failedlogincount'); 18 | $userObj->set('failedlogincount', ++$fails); 19 | if ($fails > $maxFails) { 20 | $userObj->set('blockeduntil', time() + $blockTime); 21 | $userObj->set('failedlogincount', 0); 22 | } 23 | $userObj->save(); 24 | } 25 | } 26 | if (($e->name == 'OnWebLogin' || $e->name == 'OnUserLogin') && isset($userObj)) { 27 | if (!$userObj->get('lastlogin')) { 28 | $userObj->set('lastlogin', time()); 29 | } else { 30 | $userObj->set('lastlogin', $userObj->get('thislogin')); 31 | } 32 | $userObj->set('thislogin', time()); 33 | $userObj->set('logincount', (int)$userObj->get('logincount') + 1); 34 | $userObj->set('failedlogincount', 0); 35 | $userObj->save(false, false); 36 | if (isset($_COOKIE[$cookieName])) { 37 | $userObj->setAutoLoginCookie($cookieName, $cookieLifetime); 38 | } 39 | } 40 | //Updating session_id in cookie, if user is login and just saved 41 | if (($e->name == 'OnWebSaveUser' || $e->name == 'OnUserSave') && isset($userObj)) { 42 | if( (int)$modx->getLoginUserID('web') == (int)$id && isset($_COOKIE[$cookieName]) ) { //checking, if current logined user was saved 43 | $cookieParts = explode("|", $_COOKIE[$cookieName], 4); 44 | if(isset($cookieParts[2]) && ($userObj->get('sessionid') != $cookieParts[2])) { //checking, if session ids in cookie and in user object became not equals 45 | $userObj->setAutoLoginCookie($cookieName, $cookieLifetime); 46 | } 47 | } 48 | } 49 | 50 | if ($e->name == 'OnWebPageInit' || $e->name == 'OnPageNotFound') { 51 | if (function_exists('app')) { 52 | $model = isset($params['model']) && class_exists($params['model']) ? $params['model'] : '\\Pathologic\\EvolutionCMS\\MODxAPI\\modUsers'; 53 | } else { 54 | $model = isset($params['model']) && class_exists($params['model']) ? $params['model'] : '\\modUsers'; 55 | } 56 | $user = new $model($modx); 57 | if ($uid = (int)$modx->getLoginUserID('web')) { 58 | if ($trackWebUserActivity == 'Yes') { 59 | $sid = $modx->sid = session_id(); 60 | $pageId = (int)$modx->documentIdentifier; 61 | $uid = function_exists('app') ? $uid : -1 * $uid; 62 | $name = $modx->db->escape($_SESSION['webShortname'] ?? ''); 63 | $q = $modx->db->query("REPLACE INTO {$modx->getFullTableName('active_users')} (`sid`, `internalKey`, `username`, `lasthit`, `action`, `id`) values('{$sid}', {$uid}, '{$name}', '{$modx->time}', 998, {$pageId})"); 64 | $modx->updateValidatedUserSession(); 65 | } 66 | if (isset($_REQUEST[$logoutKey])) { 67 | $user->logOut($cookieName, true); 68 | $page = $modx->getConfig('site_url') . (isset($_REQUEST['q']) ? $_REQUEST['q'] : ''); 69 | $query = $_GET; 70 | unset($query[$logoutKey], $query['q']); 71 | if ($query) { 72 | $page .= '?' . http_build_query($query); 73 | } 74 | $modx->sendRedirect($page); 75 | } elseif (!$user->edit($uid)->getID() || $user->checkBlock($uid)) { 76 | $user->logOut($cookieName, true); 77 | } 78 | } else { 79 | $user->AutoLogin($cookieLifetime, $cookieName, true); 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/SubmitProtection.php: -------------------------------------------------------------------------------- 1 | isSubmitted() && $this->getCFGDef('protectSubmit', 1)) { 23 | $formId = $this->getFormId(); 24 | $hash = $this->getFormHash(); 25 | if (isset($_SESSION[$formId . '_hash']) 26 | && $_SESSION[$formId . '_hash'] == $hash 27 | && $hash != '') { 28 | $result = true; 29 | $this->addMessage($this->translate('form.protectSubmit')); 30 | $this->log('Submit protection enabled'); 31 | } 32 | } 33 | 34 | return $result; 35 | } 36 | 37 | /** 38 | * Проверка повторной отправки в течение определенного времени, в секундах 39 | * @return bool если защита сработала, то true 40 | */ 41 | public function checkSubmitLimit() 42 | { 43 | $submitLimit = $this->getCFGDef('submitLimit', 60); 44 | $result = false; 45 | $formId = $this->getFormId(); 46 | if (isset($_SESSION[$formId . '_limit']) && $this->isSubmitted() && $submitLimit > 0) { 47 | if (time() < $submitLimit + $_SESSION[$formId . '_limit']) { 48 | $result = true; 49 | $this->addMessage($this->translate('form.submitLimit') . 50 | ($submitLimit >= 60 51 | ? round($submitLimit / 60, 0) . ' ' . $this->translate('form.minutes') . '.' 52 | : $submitLimit . ' ' . $this->translate('form.seconds') . '.' 53 | )); 54 | $this->log('Submit limit enabled'); 55 | } else { 56 | unset($_SESSION[$formId . '_limit']); 57 | } //time expired 58 | } 59 | 60 | return $result; 61 | } 62 | 63 | /** 64 | * @return $this 65 | */ 66 | public function setSubmitProtection() 67 | { 68 | $formId = $this->getFormId(); 69 | if ($this->getCFGDef('protectSubmit', 1)) { 70 | $_SESSION[$formId . '_hash'] = $this->getFormHash(); 71 | } //hash is set earlier 72 | if ($this->getCFGDef('submitLimit', 60) > 0) { 73 | $_SESSION[$formId . '_limit'] = time(); 74 | } 75 | 76 | return $this; 77 | } 78 | 79 | /** 80 | * @return array|string 81 | */ 82 | public function getFormHash() 83 | { 84 | $hash = []; 85 | $protectSubmit = $this->getCFGDef('protectSubmit', 1); 86 | if (!is_numeric($protectSubmit)) { //supplied field names 87 | $protectSubmit = $this->config->loadArray($protectSubmit); 88 | foreach ($protectSubmit as $field) { 89 | $hash[] = $this->getField(trim($field)); 90 | } 91 | } else //all required fields 92 | { 93 | $rules = $this->getValidationRules(); 94 | foreach (array_keys($rules) as $field) { 95 | if (isset($rules[$field]['required'])) { 96 | $hash[] = $this->getField($field); 97 | } 98 | } 99 | if (empty($hash)) { 100 | $this->log('No rules found to run submit protection'); 101 | } 102 | } 103 | if ($hash) { 104 | $hash = md5(jsonHelper::toJSON($hash)); 105 | } 106 | 107 | return $hash; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/captcha/reCaptcha/wrapper.php: -------------------------------------------------------------------------------- 1 | cfg = $cfg; 26 | $this->modx = $modx; 27 | } 28 | 29 | /** 30 | * Устанавливает значение капчи 31 | * @return mixed 32 | */ 33 | public function init() 34 | { 35 | return; 36 | } 37 | 38 | /** 39 | * Плейсхолдер капчи для вывода в шаблон 40 | * Может быть ссылкой на коннектор (чтобы можно было обновлять c помощью js), может быть сразу картинкой в base64 41 | * @return string 42 | */ 43 | public function getPlaceholder() 44 | { 45 | $siteKey = \APIhelpers::getkey($this->cfg, 'siteKey'); 46 | $reCAPTCHAversion = \APIhelpers::getkey($this->cfg, 'reCAPTCHAversion', "2"); 47 | $classButton = \APIhelpers::getkey($this->cfg, 'classButton', "g-recaptcha"); 48 | $textButton = \APIhelpers::getkey($this->cfg, 'textButton', "Submit"); 49 | $type = \APIhelpers::getkey($this->cfg, 'type', 'image'); 50 | $size = \APIhelpers::getkey($this->cfg, 'size', 'normal'); 51 | $tabindex = \APIhelpers::getkey($this->cfg, 'tabindex', 0); 52 | $theme = \APIhelpers::getkey($this->cfg, 'theme', 'light'); 53 | $id = \APIhelpers::getkey($this->cfg, 'captchaid', \APIhelpers::getkey($this->cfg, 'id')); 54 | $id = 'id="' . $id . '-recaptcha"'; 55 | $badge = \APIhelpers::getkey($this->cfg, 'badge', 'bottomright'); 56 | $callback = \APIhelpers::getkey($this->cfg, 'callback', ''); 57 | $expcallback = \APIhelpers::getkey($this->cfg, 'expired_callback', ''); 58 | $out = ''; 59 | if (!empty($siteKey)) { 60 | switch($reCAPTCHAversion) { 61 | case "3": 62 | $callback = \APIhelpers::getkey($this->cfg, 'callback', 'onSubmit'); 63 | $out = ""; 64 | break; 65 | default: 66 | $out = ""; 67 | break; 68 | } 69 | } 70 | 71 | return $out; 72 | } 73 | 74 | /** 75 | * @param \FormLister\Core $FormLister 76 | * @param $value 77 | * @param \FormLister\CaptchaInterface $captcha 78 | * @return bool|string 79 | */ 80 | public static function validate(Core $FormLister, $value, CaptchaInterface $captcha) 81 | { 82 | $secretKey = \APIhelpers::getkey($captcha->cfg, 'secretKey'); 83 | $url = "https://www.google.com/recaptcha/api/siteverify?secret=" . $secretKey . "&response=" . $value . "&remoteip=" . \APIhelpers::getUserIP(); 84 | $out = false; 85 | if (!empty($value)) { 86 | $curl = curl_init(); 87 | curl_setopt($curl, CURLOPT_URL, $url); 88 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 89 | curl_setopt($curl, CURLOPT_TIMEOUT, 10); 90 | curl_setopt($curl, CURLOPT_USERAGENT, 91 | "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"); 92 | $response = curl_exec($curl); 93 | curl_close($curl); 94 | $response = json_decode($response, true); 95 | $out = $response['success']; 96 | } 97 | if (!$out) { 98 | $out = \APIhelpers::getkey($captcha->cfg, 'errorCodeFailed', 'Вы не прошли проверку'); 99 | } 100 | $FormLister->log('reCaptcha validation result: '.$out); 101 | 102 | return $out; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/__autoload.php: -------------------------------------------------------------------------------- 1 | '/../../lib/APIHelpers.class.php', 9 | 'AssetsHelper' => '/../../lib/Helpers/Assets.php', 10 | 'DLTemplate' => '/../DocLister/lib/DLTemplate.class.php', 11 | 'DLphx' => '/../DocLister/lib/DLphx.class.php', 12 | 'DrewM\\MailChimp\\Batch' => '/lib/MailChimp/Batch.php', 13 | 'DrewM\\MailChimp\\MailChimp' => '/lib/MailChimp/MailChimp.php', 14 | 'FormLister\\Activate' => '/core/controller/Activate.php', 15 | 'FormLister\\CaptchaInterface' => '/lib/captcha/Captcha.php', 16 | 'FormLister\\Content' => '/core/controller/Content.php', 17 | 'FormLister\\Core' => '/core/FormLister.abstract.php', 18 | 'FormLister\\DateConverter' => '/lib/DateConverter.php', 19 | 'FormLister\\DeleteContent' => '/core/controller/DeleteContent.php', 20 | 'FormLister\\DeleteUser' => '/core/controller/DeleteUser.php', 21 | 'FormLister\\FileValidator' => '/lib/FileValidator.php', 22 | 'FormLister\\Filters' => '/lib/Filters.php', 23 | 'FormLister\\Form' => '/core/controller/Form.php', 24 | 'FormLister\\Login' => '/core/controller/Login.php', 25 | 'FormLister\\MailChimp' => '/core/controller/MailChimp.php', 26 | 'FormLister\\Profile' => '/core/controller/Profile.php', 27 | 'FormLister\\Register' => '/core/controller/Register.php', 28 | 'FormLister\\Reminder' => '/core/controller/Reminder.php', 29 | 'FormLister\\SubmitProtection' => '/lib/SubmitProtection.php', 30 | 'FormLister\\Validator' => '/lib/Validator.php', 31 | 'Formatter\\HtmlFormatter' => '/../../lib/Formatter/HtmlFormatter.php', 32 | 'Formatter\\SqlFormatter' => '/../../lib/Formatter/SqlFormatter.php', 33 | 'Helpers\\Collection' => '/../../lib/Helpers/Collection.php', 34 | 'Helpers\\Config' => '/../../lib/Helpers/Config.php', 35 | 'Helpers\\Debug' => '/lib/Debug.php', 36 | 'Helpers\\FS' => '/../../lib/Helpers/FS.php', 37 | 'Helpers\\Gpc' => '/lib/Gpc.php', 38 | 'Helpers\\Lexicon' => '/../../lib/Helpers/Lexicon.php', 39 | 'Helpers\\Lexicon\\AbstractLexiconHandler' => '/../../lib/Helpers/LexiconHandlers/AbstractLexiconHandler.php', 40 | 'Helpers\\Lexicon\\EvoBabelLexiconHandler' => '/../../lib/Helpers/LexiconHandlers/EvoBabelLexiconHandler.php', 41 | 'Helpers\\Mailer' => '/../../lib/Helpers/Mailer.php', 42 | 'Helpers\\PHPThumb' => '/../../lib/Helpers/PHPThumb.php', 43 | 'Helpers\\Video' => '/../../lib/Helpers/Video.php', 44 | 'MODxAPI' => '/../../lib/MODxAPI/MODx.php', 45 | 'MODxAPIhelpers' => '/../../lib/MODxAPI/MODx.php', 46 | 'ModxCaptcha' => '/lib/captcha/modxCaptcha/modxCaptcha.php', 47 | 'ModxCaptchaWrapper' => '/lib/captcha/modxCaptcha/wrapper.php', 48 | 'ReCaptchaWrapper' => '/lib/captcha/reCaptcha/wrapper.php', 49 | 'SmsCaptchaWrapper' => '/lib/captcha/smsCaptcha/wrapper.php', 50 | 'SmsModel' => '/lib/captcha/smsCaptcha/model.php', 51 | 'SummaryText' => '/../../lib/class.summary.php', 52 | 'autoTable' => '/../../lib/MODxAPI/autoTable.abstract.php', 53 | 'jsonHelper' => '/../DocLister/lib/jsonHelper.class.php', 54 | 'modCategories' => '/../../lib/MODxAPI/modCategories.php', 55 | 'modChunk' => '/../../lib/MODxAPI/modChunk.php', 56 | 'modModule' => '/../../lib/MODxAPI/modModule.php', 57 | 'modPlugin' => '/../../lib/MODxAPI/modPlugin.php', 58 | 'modResource' => '/../../lib/MODxAPI/modResource.php', 59 | 'modSnippet' => '/../../lib/MODxAPI/modSnippet.php', 60 | 'modTV' => '/../../lib/MODxAPI/modTV.php', 61 | 'modTemplate' => '/../../lib/MODxAPI/modTemplate.php', 62 | 'modUsers' => '/../../lib/MODxAPI/modUsers.php', 63 | 'sqlHelper' => '/../DocLister/lib/sqlHelper.class.php', 64 | 'xNop' => '/../DocLister/lib/xnop.class.php' 65 | ); 66 | } 67 | if (isset($classes[$class])) { 68 | require dirname(__FILE__) . $classes[$class]; 69 | } 70 | }; 71 | spl_autoload_register($loader, true); 72 | // @codeCoverageIgnoreEnd 73 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/Login.php: -------------------------------------------------------------------------------- 1 | user = $this->loadModel( 37 | $this->getCFGDef('model', '\modUsers'), 38 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 39 | ); 40 | $requestUri = $_SERVER['REQUEST_URI']; 41 | if (0 === strpos($requestUri, MODX_BASE_URL)) { 42 | $requestUri = substr($requestUri, strlen(MODX_BASE_URL)); 43 | } 44 | $this->requestUri = $this->modx->getConfig('site_url') . $requestUri; 45 | $this->context = $this->getCFGDef('context', 'web'); 46 | $this->lexicon->fromFile('login'); 47 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 48 | $this->dateFormat = $this->getCFGDef('dateFormat', ''); 49 | } 50 | 51 | /** 52 | * @return string 53 | */ 54 | public function render() 55 | { 56 | if ($id = $this->modx->getLoginUserID($this->context)) { 57 | $this->redirect('exitTo'); 58 | $this->user->edit($id); 59 | $this->setFields($this->user->toArray()); 60 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->lexicon->getMsg('login.default_skipTpl')); 61 | $this->setValid(false); 62 | }; 63 | 64 | return parent::render(); 65 | } 66 | 67 | 68 | /** 69 | * 70 | */ 71 | public function process() 72 | { 73 | if (is_null($this->user)) { 74 | $this->addMessage($this->lexicon->getMsg('login.user_failed')); 75 | 76 | return; 77 | } 78 | $login = $this->getField($this->getCFGDef('loginField', 'username')); 79 | if (!is_scalar($login)) { 80 | $login = ''; 81 | } 82 | $password = $this->getField($this->getCFGDef('passwordField', 'password')); 83 | $remember = $this->getField($this->getCFGDef('rememberField', 'rememberme')); 84 | if ($this->user->checkBlock($login)) { 85 | $this->addMessage($this->lexicon->getMsg('login.user_blocked')); 86 | 87 | return; 88 | } 89 | $this->user->edit($login); 90 | 91 | if ($this->getCFGDef('checkActivation', 0) && !$this->user->get('verified')) { 92 | $this->addMessage($this->lexicon->getMsg('login.user_notactivated')); 93 | 94 | return; 95 | } 96 | 97 | $auth = $this->user->testAuth($login, $password, false, true); 98 | if (!$auth) { 99 | $this->addMessage($this->lexicon->getMsg('login.user_failed')); 100 | 101 | return; 102 | } 103 | if ($remember) { 104 | $remember = $this->getCFGDef('cookieLifetime', 60 * 60 * 24 * 365 * 5); 105 | } 106 | $loginCookie = $this->getCFGDef('cookieName', 'WebLoginPE'); 107 | $this->user->authUser($login, $remember, $loginCookie, true); 108 | $this->setFormStatus(true); 109 | $this->runPrepare('prepareAfterProcess'); 110 | if (isset($this->modx->documentIdentifier) && $this->modx->documentIdentifier == $this->modx->getConfig('unauthorized_page')) { 111 | $uaPage = $this->modx->makeUrl($this->modx->getConfig('unauthorized_page'), "", "", "full"); 112 | $requested = explode('?', $this->requestUri); 113 | if (array_shift($requested) != $uaPage) { 114 | $this->setField('redirectTo', $this->requestUri); 115 | $this->sendRedirect($this->requestUri); 116 | } else { 117 | $this->redirect(); 118 | } 119 | } else { 120 | $this->redirect(); 121 | } 122 | $this->setFields($this->user->toArray()); 123 | if ($dob = $this->fromTimestamp($this->getField('dob'))) { 124 | $this->setField('dob', $dob); 125 | } 126 | $this->renderTpl = $this->getCFGDef('successTpl'); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/MailChimp/Batch.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class Batch 12 | { 13 | private $MailChimp; 14 | 15 | private $operations = array(); 16 | private $batch_id; 17 | 18 | public function __construct(MailChimp $MailChimp, $batch_id=null) 19 | { 20 | $this->MailChimp = $MailChimp; 21 | $this->batch_id = $batch_id; 22 | } 23 | 24 | /** 25 | * Add an HTTP DELETE request operation to the batch - for deleting data 26 | * @param string $id ID for the operation within the batch 27 | * @param string $method URL of the API request method 28 | * @return void 29 | */ 30 | public function delete($id, $method) 31 | { 32 | $this->queueOperation('DELETE', $id, $method); 33 | } 34 | 35 | /** 36 | * Add an HTTP GET request operation to the batch - for retrieving data 37 | * @param string $id ID for the operation within the batch 38 | * @param string $method URL of the API request method 39 | * @param array $args Assoc array of arguments (usually your data) 40 | * @return void 41 | */ 42 | public function get($id, $method, $args=array()) 43 | { 44 | $this->queueOperation('GET', $id, $method, $args); 45 | } 46 | 47 | /** 48 | * Add an HTTP PATCH request operation to the batch - for performing partial updates 49 | * @param string $id ID for the operation within the batch 50 | * @param string $method URL of the API request method 51 | * @param array $args Assoc array of arguments (usually your data) 52 | * @return void 53 | */ 54 | public function patch($id, $method, $args=array()) 55 | { 56 | $this->queueOperation('PATCH', $id, $method, $args); 57 | } 58 | 59 | /** 60 | * Add an HTTP POST request operation to the batch - for creating and updating items 61 | * @param string $id ID for the operation within the batch 62 | * @param string $method URL of the API request method 63 | * @param array $args Assoc array of arguments (usually your data) 64 | * @return void 65 | */ 66 | public function post($id, $method, $args=array()) 67 | { 68 | $this->queueOperation('POST', $id, $method, $args); 69 | } 70 | 71 | /** 72 | * Add an HTTP PUT request operation to the batch - for creating new items 73 | * @param string $id ID for the operation within the batch 74 | * @param string $method URL of the API request method 75 | * @param array $args Assoc array of arguments (usually your data) 76 | * @return void 77 | */ 78 | public function put($id, $method, $args=array()) 79 | { 80 | $this->queueOperation('PUT', $id, $method, $args); 81 | } 82 | 83 | /** 84 | * Execute the batch request 85 | * @param int $timeout Request timeout in seconds (optional) 86 | * @return array|false Assoc array of API response, decoded from JSON 87 | */ 88 | public function execute($timeout=10) 89 | { 90 | $req = array('operations' => $this->operations); 91 | 92 | $result = $this->MailChimp->post('batches', $req, $timeout); 93 | 94 | if ($result && isset($result['id'])) { 95 | $this->batch_id = $result['id']; 96 | } 97 | 98 | return $result; 99 | } 100 | 101 | /** 102 | * Check the status of a batch request. If the current instance of the Batch object 103 | * was used to make the request, the batch_id is already known and is therefore optional. 104 | * @param string $batch_id ID of the batch about which to enquire 105 | * @return array|false Assoc array of API response, decoded from JSON 106 | */ 107 | public function checkStatus($batch_id=null) 108 | { 109 | if ($batch_id===null && $this->batch_id) $batch_id = $this->batch_id; 110 | return $this->MailChimp->get('batches/'.$batch_id); 111 | } 112 | 113 | /** 114 | * Add an operation to the internal queue. 115 | * @param string $http_verb GET, POST, PUT, PATCH or DELETE 116 | * @param string $id ID for the operation within the batch 117 | * @param string $method URL of the API request method 118 | * @param array $args Assoc array of arguments (usually your data) 119 | * @return void 120 | */ 121 | private function queueOperation($http_verb, $id, $method, $args=null) 122 | { 123 | $operation = array( 124 | 'operation_id' => $id, 125 | 'method' => $http_verb, 126 | 'path' => $method, 127 | ); 128 | 129 | if ($args) { 130 | $key = ($http_verb == 'GET' ? 'params' : 'body'); 131 | $operation[$key] = json_encode($args); 132 | } 133 | 134 | $this->operations[] = $operation; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/Filters.php: -------------------------------------------------------------------------------- 1 | $min : $size >= $min; 99 | if (!$flag) { 100 | break; 101 | } 102 | } 103 | 104 | return $flag; 105 | } 106 | 107 | /** 108 | * @param $value 109 | * @param $min 110 | * @param $max 111 | * @param bool $strict 112 | * @return bool 113 | */ 114 | public static function sizeBetween($value, $min, $max, $strict = false): bool 115 | { 116 | $value = self::value($value); 117 | $flag = false; 118 | foreach ($value as $file) { 119 | $size = round($file['size'] / 1024, 0); 120 | $flag = $strict ? $size > $min && $size < $max : $size >= $min && $size <= $max; 121 | if (!$flag) { 122 | break; 123 | } 124 | } 125 | 126 | return $flag; 127 | } 128 | 129 | /** 130 | * @param $value 131 | * @param $max 132 | * @param bool $strict 133 | * @return bool 134 | */ 135 | public static function maxCount($value, $max, $strict = false): bool 136 | { 137 | $value = self::value($value); 138 | $count = self::getCount($value); 139 | 140 | return $strict ? $count < $max : $count <= $max; 141 | } 142 | 143 | /** 144 | * @param $value 145 | * @param $min 146 | * @param bool $strict 147 | * @return bool 148 | */ 149 | public static function minCount($value, $min, $strict = false): bool 150 | { 151 | $value = self::value($value); 152 | $count = self::getCount($value); 153 | 154 | return $strict ? $count > $min : $count >= $min; 155 | } 156 | 157 | /** 158 | * @param $value 159 | * @param $min 160 | * @param $max 161 | * @return bool 162 | */ 163 | public static function countBetween($value, $min, $max, $strict = false): bool 164 | { 165 | $value = self::value($value); 166 | $count = self::getCount($value); 167 | 168 | return $strict ? $count > $min && $count < $max : $count >= $min && $count <= $max; 169 | } 170 | 171 | /** 172 | * @param $value 173 | * @return bool 174 | */ 175 | protected static function isArray($value): bool 176 | { 177 | return isset($value[0]); 178 | } 179 | 180 | /** 181 | * @param $value 182 | * @return array 183 | */ 184 | protected static function value($value): array 185 | { 186 | $out = []; 187 | $isArray = self::isArray($value); 188 | if (!empty($value) && !$isArray) { 189 | $out = [$value]; 190 | } elseif ($isArray) { 191 | $out = $value; 192 | } 193 | 194 | return $out; 195 | } 196 | 197 | /** 198 | * @param $value 199 | * @return int 200 | */ 201 | protected static function getCount($value): int 202 | { 203 | $count = 0; 204 | foreach ($value as $file) { 205 | if (!$file['error'] && is_uploaded_file($file['tmp_name'])) { 206 | $count++; 207 | } 208 | } 209 | 210 | return $count; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/Register.php: -------------------------------------------------------------------------------- 1 | user = $this->loadModel( 31 | $this->getCFGDef('model', '\modUsers'), 32 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 33 | ); 34 | $this->lexicon->fromFile('register'); 35 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 36 | $this->dateFormat = $this->getCFGDef('dateFormat', ''); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function render () 43 | { 44 | if ($id = $this->modx->getLoginUserID('web')) { 45 | $this->redirect('exitTo'); 46 | $this->user->edit($id); 47 | $this->setFields($this->user->toArray()); 48 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('register.default_skipTpl')); 49 | $this->setValid(false); 50 | }; 51 | 52 | return parent::render(); 53 | } 54 | 55 | public function getValidationRules($param = 'rules') 56 | { 57 | $rules = parent::getValidationRules($param); // TODO: Change the autogenerated stub 58 | if (isset($rules['password']) && isset($rules['repeatPassword']) && !empty($this->getField('password')) && isset($this->rules['repeatPassword']['equals'])) { 59 | $rules['repeatPassword']['equals']['params'] = $this->getField('password'); 60 | } 61 | 62 | return $rules; 63 | } 64 | 65 | /** 66 | * Custom validation rule 67 | * Проверяет уникальность email 68 | * @param $fl 69 | * @param $value 70 | * @return bool 71 | */ 72 | public static function uniqueEmail ($fl, $value) 73 | { 74 | $result = true; 75 | if (is_scalar($value) && !is_null($fl->user)) { 76 | $fl->user->set('email', $value); 77 | $result = $fl->user->isUnique('email'); 78 | } 79 | 80 | return $result; 81 | } 82 | 83 | /** 84 | * Custom validation rule 85 | * Проверяет уникальность имени пользователя 86 | * @param $fl 87 | * @param $value 88 | * @return bool 89 | */ 90 | public static function uniqueUsername ($fl, $value) 91 | { 92 | $result = true; 93 | if (is_scalar($value) && !is_null($fl->user)) { 94 | $fl->user->set('username', $value); 95 | $result = $fl->user->isUnique('username'); 96 | } 97 | 98 | return $result; 99 | } 100 | 101 | /** 102 | * 103 | */ 104 | public function process () 105 | { 106 | if (!empty($this->allowedFields)) { 107 | $this->allowedFields[] = 'username'; 108 | $this->allowedFields[] = 'password'; 109 | $this->allowedFields[] = 'email'; 110 | } 111 | if (!empty($this->forbiddenFields)) { 112 | $_forbidden = array_flip($this->forbiddenFields); 113 | unset($_forbidden['username'], $_forbidden['password'], $_forbidden['email']); 114 | $this->forbiddenFields = array_keys($_forbidden); 115 | } 116 | 117 | //регистрация без логина, по емейлу 118 | if ($this->getField('username') == '') { 119 | $this->setField('username', $this->getField('email')); 120 | } 121 | //регистрация со случайным паролем 122 | if ($this->getField('password') == '' && !isset($this->rules['password'])) { 123 | $this->setField('password', APIhelpers::genPass($this->getCFGDef('passwordLength', 6))); 124 | } 125 | $password = $this->getField('password'); 126 | $fields = $this->filterFields($this->getFormData('fields'), $this->allowedFields, $this->forbiddenFields); 127 | if (isset($fields['dob']) && ($dob = $this->toTimestamp($fields['dob']))) { 128 | $fields['dob'] = $dob; 129 | } 130 | $checkActivation = $this->getCFGDef('checkActivation', 0); 131 | $fields['verified'] = (int)!$checkActivation; 132 | $fields['username'] = is_scalar($fields['username']) ? $fields['username'] : ''; 133 | $fields['email'] = is_scalar($fields['email']) ? $fields['email'] : ''; 134 | $fields['role'] = (int)$this->getCFGDef('userRole', 0); 135 | $this->user->create($fields); 136 | $this->user->setUserGroupsByName(0, $this->config->loadArray($this->getCFGDef('userGroups'))); 137 | $result = $this->user->save(true); 138 | $this->log('Register user', [ 139 | 'data' => $fields, 140 | 'result' => $result, 141 | 'log' => $this->user->getLog() 142 | ]); 143 | if (!$result) { 144 | $this->addMessage($this->translate('register.registration_failed')); 145 | } else { 146 | $this->user->close(); 147 | $userdata = $this->user->edit((int)$result)->toArray(); 148 | $this->setFields($userdata); 149 | if ($dob = $this->fromTimestamp($this->getField('dob'))) { 150 | $this->setField('dob', $dob); 151 | } 152 | $this->setField('user.password', $password); 153 | $this->runPrepare('preparePostProcess'); 154 | if ($checkActivation) { 155 | $hash = md5(jsonHelper::toJSON($userdata)); 156 | $uidName = $this->getCFGDef('uidName', $this->user->fieldPKName()); 157 | $query = http_build_query([ 158 | $uidName => $result, 159 | 'hash' => $hash 160 | ]); 161 | $url = $this->getCFGDef('activateTo', isset($this->modx->documentIdentifier) && $this->modx->documentIdentifier > 0 ? $this->modx->documentIdentifier : $this->modx->getConfig('site_start')); 162 | if(is_numeric($url)) { 163 | $url = $this->modx->makeUrl($url, "", $query, 'full'); 164 | } else { 165 | $url = $this->modx->getConfig('site_url') . $url . '?' . $query; 166 | } 167 | $this->setField('activate.url', $url); 168 | } 169 | parent::process(); 170 | } 171 | } 172 | 173 | /** 174 | * 175 | */ 176 | public function postProcess () 177 | { 178 | parent::postProcess(); 179 | $tpl = $this->getCFGDef('successTpl', $this->translate('register.default_successTpl')); 180 | if (!empty($tpl)) { 181 | $this->renderTpl = $tpl; 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/captcha/modxCaptcha/modxCaptcha.php: -------------------------------------------------------------------------------- 1 | modx = $modx; 31 | $this->dir_font = __DIR__ . $this->dir_font; 32 | $this->dir_noise = __DIR__ . $this->dir_noise; 33 | $this->im_width = $width; 34 | $this->im_height = $height; 35 | $this->word = $this->pickWord(); 36 | } 37 | 38 | /** 39 | * @param bool $inline 40 | * @return string 41 | */ 42 | public function outputImage($inline = false) 43 | { 44 | /* output the image as jpeg */ 45 | $this->drawImage(); 46 | ob_clean(); 47 | if ($inline) { 48 | ob_start(); 49 | imagejpeg($this->im); 50 | $image = ob_get_contents(); 51 | ob_end_clean(); 52 | 53 | return 'data:image/jpeg;base64,' . base64_encode($image); 54 | } 55 | header("Content-type: image/jpeg"); 56 | imagejpeg($this->im); 57 | imagedestroy($this->im); 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function pickWord() 64 | { 65 | // set default words 66 | $words = "MODX,Access,Better,BitCode,Chunk,Cache,Desc,Design,Excell,Enjoy,URLs,TechView,Gerald,Griff,Humphrey,Holiday,Intel,Integration,Joystick,Join(),Oscope,Genetic,Light,Likeness,Marit,Maaike,Niche,Netherlands,Ordinance,Oscillo,Parser,Phusion,Query,Question,Regalia,Righteous,Snippet,Sentinel,Template,Thespian,Unity,Enterprise,Verily,Veri,Website,WideWeb,Yap,Yellow,Zebra,Zygote"; 67 | $words = $this->modx->getConfig('captcha_words') ? $this->modx->getConfig('captcha_words') : $words; 68 | $words = str_replace(array(' ', ',,'), array('', ','), $words); 69 | $arr_words = explode(',', $words); 70 | 71 | /* pick one randomly for text verification */ 72 | 73 | return (string)$arr_words[array_rand($arr_words)] . rand(10, 999); 74 | } 75 | 76 | /** 77 | * @return resource 78 | */ 79 | private function drawText() 80 | { 81 | $dir = dir($this->dir_font); 82 | $fontstmp = array(); 83 | while (false !== ($file = $dir->read())) { 84 | if (substr($file, -4) == '.ttf') { 85 | $fontstmp[] = $this->dir_font . $file; 86 | } 87 | } 88 | $dir->close(); 89 | $text_font = (string)$fontstmp[array_rand($fontstmp)]; 90 | $chars = mb_str_split($this->word); 91 | $_chars = array(); 92 | $maxWidth = $this->im_width / count($chars); 93 | $text_size = round(max($maxWidth, $this->im_height) * 3 /4.5 ); 94 | $maxHeight = 0; 95 | $totalWidth = 0; 96 | foreach ($chars as $index => $value) { 97 | $text_angle = rand(-20, 20); 98 | $size = $text_size; 99 | $box = imagettfbbox($size, $text_angle, $text_font, $value); 100 | $charWidth = $box[2] - $box[0]; 101 | $charHeight = abs($box[5] - $box[3]); 102 | $_chars[] = array( 103 | 'angle' => $text_angle, 104 | 'size' => $size, 105 | 'width' => $charWidth, 106 | 'height' => $charHeight 107 | ); 108 | if ($charHeight > $maxHeight) $maxHeight = $charHeight; 109 | $totalWidth += $charWidth; 110 | } 111 | 112 | $minRatio = min(1, $this->im_width / $totalWidth, $this->im_height / $maxHeight); 113 | $size = round($text_size * $minRatio * 0.9); 114 | 115 | $totalWidth = 0; 116 | foreach ($_chars as $index => &$data) { 117 | $data['size'] = $size; 118 | $box = imagettfbbox($data['size'], $data['angle'], $text_font, $chars[$index]); 119 | $charWidth = $box[2] - $box[0]; 120 | $charHeight = abs($box[5] - $box[3]); 121 | $data['width'] = $charWidth; 122 | $data['height'] = $charHeight; 123 | $totalWidth += $charWidth; 124 | } 125 | /* create canvas for text drawing */ 126 | $im_text = imagecreate($this->im_width, $this->im_height); 127 | $bg_color = imagecolorallocate($im_text, 255, 255, 255); 128 | $text_x = ($this->im_width - $totalWidth) / 2; 129 | foreach ($_chars as $index => $data) { 130 | /* calculate center position of text */ 131 | $text_y = ($this->im_height + $data['height'])/2; 132 | /* pick color for text */ 133 | $text_color = imagecolorallocate($im_text, rand(10, 200), rand(10, 200), rand(10, 200)); 134 | 135 | /* draw text into canvas */ 136 | imagettftext( 137 | $im_text, 138 | $data['size'], 139 | $data['angle'], 140 | (int)$text_x, 141 | (int)$text_y, 142 | $text_color, 143 | $text_font, 144 | $chars[$index]); 145 | $text_x += $data['width']; 146 | } 147 | /* remove background color */ 148 | imagecolortransparent($im_text, $bg_color); 149 | 150 | return $im_text; 151 | } 152 | 153 | 154 | /** 155 | * @return null|resource 156 | */ 157 | private function drawImage() 158 | { 159 | 160 | /* pick one background image randomly from image directory */ 161 | $img_file = $this->dir_noise . "noise" . rand(1, 4) . ".jpg"; 162 | 163 | /* create "noise" background image from your image stock*/ 164 | 165 | $noise_img = imagecreatefromjpeg($img_file); 166 | $noise_width = imagesx($noise_img); 167 | $noise_height = imagesy($noise_img); 168 | 169 | /* resize the background image to fit the size of image output */ 170 | $this->im = imagecreatetruecolor($this->im_width, $this->im_height); 171 | imagecopyresampled( 172 | $this->im, 173 | $noise_img, 174 | 0, 0, 0, 0, 175 | $this->im_width, 176 | $this->im_height, 177 | $noise_width, 178 | $noise_height 179 | ); 180 | 181 | /* put text image into background image */ 182 | imagecopymerge( 183 | $this->im, 184 | $this->drawText(), 185 | 0, 0, 0, 0, 186 | $this->im_width, 187 | $this->im_height, 188 | 70 189 | ); 190 | 191 | return $this->im; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/Activate.php: -------------------------------------------------------------------------------- 1 | user = $this->loadModel( 37 | $this->getCFGDef('model', '\modUsers'), 38 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 39 | ); 40 | $this->lexicon->fromFile('activate'); 41 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 42 | $userField = $this->getCFGDef('userField', 'email'); 43 | $this->userField = $userField; 44 | $uidName = $this->getCFGDef('uidName', $this->user->fieldPKName()); 45 | if (!isset($_REQUEST['formid']) && !isset($_REQUEST[$userField]) && (isset($_REQUEST['hash']) && !empty($_REQUEST['hash']) && isset($_REQUEST[$uidName]) && !empty($_REQUEST[$uidName]))) { 46 | $this->setField('hash', $_REQUEST['hash']); 47 | $this->setField('id', (int)$_REQUEST[$uidName]); 48 | $this->mode = 'activate'; 49 | } 50 | $this->log('Activate mode is ' . $this->mode); 51 | } 52 | 53 | /** 54 | * @return string 55 | */ 56 | public function render() 57 | { 58 | if ($id = (int)$this->modx->getLoginUserID('web')) { 59 | $this->redirect('exitTo'); 60 | $this->user->edit($id); 61 | $this->setFields($this->user->toArray()); 62 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('activate.default_skipTpl')); 63 | $this->setValid(false); 64 | } 65 | 66 | if ($this->mode == 'activate') { 67 | $this->renderActivate(); 68 | } 69 | 70 | return parent::render(); 71 | } 72 | 73 | /** 74 | * 75 | */ 76 | public function renderActivate() 77 | { 78 | $hash = $this->getField('hash'); 79 | $uid = (int)$this->getField('id'); 80 | if (is_scalar($hash) && $hash && $hash == $this->getUserHash($uid)) { 81 | $this->process(); 82 | } else { 83 | $this->addMessage($this->translate('activate.update_failed')); 84 | $this->setValid(false); 85 | } 86 | 87 | return; 88 | } 89 | 90 | /** 91 | * @param $uid 92 | * @return bool|string 93 | */ 94 | public function getUserHash($uid) 95 | { 96 | if (is_null($this->user)) { 97 | $hash = false; 98 | } else { 99 | $userdata = $this->user->edit($uid)->toArray(); 100 | $hash = $this->user->getID() && !$userdata['verified'] ? md5(jsonHelper::toJson($userdata)) : false; 101 | } 102 | 103 | return $hash; 104 | } 105 | 106 | /** 107 | * 108 | */ 109 | public function process() 110 | { 111 | switch ($this->mode) { 112 | /** 113 | * Задаем хэш, отправляем пользователю ссылку для активации 114 | */ 115 | case "hash": 116 | $uid = $this->getField($this->userField); 117 | $password = $this->getField('password'); 118 | if ($hash = $this->getUserHash($uid)){ 119 | $this->setFields($this->user->toArray()); 120 | $url = $this->getCFGDef('activateTo', isset($this->modx->documentIdentifier) && $this->modx->documentIdentifier > 0 ? $this->modx->documentIdentifier : $this->modx->getConfig('site_start')); 121 | $uidName = $this->getCFGDef('uidName', $this->user->fieldPKName()); 122 | $query = http_build_query([$uidName => $this->getField($this->userField), 'hash' => $hash]); 123 | if(is_numeric($url)) { 124 | $url = $this->modx->makeUrl($url, "", $query, 'full'); 125 | } else { 126 | $url .= '?' . $query; 127 | } 128 | $this->setField('activate.url', $url); 129 | $this->mailConfig['to'] = $this->user->get('email'); 130 | parent::process(); 131 | } else { 132 | $this->addMessage($this->translate('activate.no_activation')); 133 | } 134 | break; 135 | /** 136 | * Отправляем пользователю письмо для активации, если указан шаблон такого письма 137 | */ 138 | case "activate": 139 | $uid = (int)$this->getField('id'); 140 | $hash = $this->getField('hash'); 141 | if ($hash && $hash == $this->getUserHash($uid)) { 142 | $result = $this->user->edit($uid)->set('verified', 1)->save(true); 143 | $this->log('Activate user', ['user' => $uid, 'result' => $result]); 144 | if (!$result) { 145 | $this->addMessage($this->translate('activate.update_failed')); 146 | } else { 147 | $this->setFields($this->user->toArray()); 148 | if ($tpl = $this->getCFGDef('activateReportTpl')) { 149 | $this->mailConfig['to'] = $this->getField('email'); 150 | $this->config->setConfig([ 151 | 'reportTpl' => $tpl 152 | ]); 153 | parent::process(); 154 | } 155 | } 156 | } else { 157 | $this->addMessage($this->translate('activate.update_failed')); 158 | } 159 | break; 160 | } 161 | } 162 | 163 | /** 164 | * @return string 165 | */ 166 | public function getMode() { 167 | return $this->mode; 168 | } 169 | 170 | /** 171 | * 172 | */ 173 | public function postProcess() 174 | { 175 | $this->setFormStatus(true); 176 | $this->runPrepare('prepareAfterProcess'); 177 | switch ($this->mode) { 178 | case 'hash': 179 | $tpl = $this->getCFGDef('successTpl', 180 | $this->translate('activate.default_successTpl')); 181 | break; 182 | case 'activate': 183 | $this->redirect(); 184 | $tpl = $this->getCFGDef('activateSuccessTpl', 185 | $this->translate('activate.default_activateSuccessTpl')); 186 | } 187 | if (!empty($tpl)) { 188 | $this->renderTpl = $tpl; 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/Profile.php: -------------------------------------------------------------------------------- 1 | lexicon->fromFile('profile'); 29 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]); 30 | $uid = (int)$modx->getLoginUserId('web'); 31 | if ($uid) { 32 | /* @var $user \modUsers */ 33 | $user = $this->loadModel( 34 | $this->getCFGDef('model', '\modUsers'), 35 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 36 | ); 37 | $this->user = $user->edit($uid); 38 | $this->config->setConfig([ 39 | 'userdata' => $this->user->toArray() 40 | ]); 41 | } 42 | $this->dateFormat = $this->getCFGDef('dateFormat', ''); 43 | } 44 | 45 | /** 46 | * Загружает в formData данные не из формы 47 | * @param string $sources список источников 48 | * @param string $arrayParam название параметра с данными 49 | * @return $this 50 | */ 51 | public function setExternalFields ($sources = 'array', $arrayParam = 'defaults') 52 | { 53 | parent::setExternalFields($sources, $arrayParam); 54 | parent::setExternalFields('array', 'userdata'); 55 | 56 | return $this; 57 | } 58 | 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function render () 64 | { 65 | if (is_null($this->user) || !$this->user->getID()) { 66 | $this->redirect('exitTo'); 67 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('profile.default_skipTpl')); 68 | $this->setValid(false); 69 | } 70 | if (!$this->isSubmitted() && ($dob = $this->getField('dob'))) { 71 | $this->setField('dob', $this->fromTimestamp($dob)); 72 | } 73 | 74 | return parent::render(); 75 | } 76 | 77 | public function getValidationRules($param = 'rules') 78 | { 79 | $rules = parent::getValidationRules($param); // TODO: Change the autogenerated stub 80 | $password = $this->getField('password'); 81 | if (empty($password) || !is_scalar($password)) { 82 | $this->forbiddenFields[] = 'password'; 83 | if (isset($rules['password'])) { 84 | unset($rules['password']); 85 | } 86 | if (isset($rules['repeatPassword'])) { 87 | unset($rules['repeatPassword']); 88 | } 89 | } else { 90 | if (isset($rules['repeatPassword']['equals'])) { 91 | $rules['repeatPassword']['equals']['params'] = $this->getField('password'); 92 | } 93 | } 94 | 95 | return $rules; 96 | } 97 | 98 | /** 99 | * @param $fl 100 | * @param $value 101 | * @return bool 102 | */ 103 | public static function uniqueEmail ($fl, $value) 104 | { 105 | $result = true; 106 | if (is_scalar($value) && !is_null($fl->user) && ($fl->user->get("email") !== $value)) { 107 | /* @var $user \modUsers */ 108 | $user = clone($fl->user); 109 | $user->set('email', $value); 110 | $result = $user->isUnique('email'); 111 | } 112 | 113 | return $result; 114 | } 115 | 116 | /** 117 | * @param $fl 118 | * @param $value 119 | * @return bool 120 | */ 121 | public static function uniqueUsername ($fl, $value) 122 | { 123 | $result = true; 124 | if (is_scalar($value) && !is_null($fl->user) && ($fl->user->get("email") !== $value)) { 125 | /* @var $user \modUsers */ 126 | $user = clone($fl->user); 127 | $user->set('username', $value); 128 | $result = $user->isUnique('username'); 129 | } 130 | 131 | return $result; 132 | } 133 | 134 | /** 135 | * 136 | */ 137 | public function process () 138 | { 139 | if ($this->user->get('username') == $this->user->get('email') && !empty($this->getField('email')) && empty($this->getField('username'))) { 140 | $this->setField('username', $this->getField('email')); 141 | if (!empty($this->allowedFields)) { 142 | $this->allowedFields[] = 'username'; 143 | } 144 | if (!empty($this->forbiddenFields)) { 145 | $_forbidden = array_flip($this->forbiddenFields); 146 | unset($_forbidden['username']); 147 | $this->forbiddenFields = array_keys($_forbidden); 148 | } 149 | } 150 | 151 | $newpassword = $this->getField('password'); 152 | $password = $this->user->get('password'); 153 | if (!empty($newpassword) && ($password !== $this->user->getPassword($newpassword))) { 154 | if (!empty($this->allowedFields)) { 155 | $this->allowedFields[] = 'password'; 156 | } 157 | if (!empty($this->forbiddenFields)) { 158 | $_forbidden = array_flip($this->forbiddenFields); 159 | unset($_forbidden['password']); 160 | $this->forbiddenFields = array_keys($_forbidden); 161 | } 162 | } 163 | $fields = $this->filterFields($this->getFormData('fields'), $this->allowedFields, $this->forbiddenFields); 164 | if (isset($fields['username'])) { 165 | $fields['username'] = is_scalar($fields['username']) ? $fields['username'] : ''; 166 | } 167 | if (isset($fields['email'])) { 168 | $fields['email'] = is_scalar($fields['email']) ? $fields['email'] : ''; 169 | } 170 | if (isset($fields['dob']) && ($dob = $this->toTimestamp($fields['dob']))) { 171 | $fields['dob'] = $dob; 172 | } 173 | $verificationField = $this->getCFGDef('verificationField', 'email'); 174 | if (isset($fields[$verificationField]) && $this->user->get($verificationField) != $fields[$verificationField]) { 175 | $fields['verified'] = 0; 176 | } 177 | $result = (int)$this->user->fromArray($fields)->save(true); 178 | $this->log('Update profile', [ 179 | 'data' => $fields, 180 | 'result' => $result, 181 | 'log' => $this->user->getLog() 182 | ]); 183 | if ($result) { 184 | $this->setFormStatus(true); 185 | $this->user->close(); 186 | $this->setFields($this->user->edit($result)->toArray()); 187 | if ($dob = $this->fromTimestamp($this->getField('dob'))) { 188 | $this->setField('dob', $dob); 189 | } 190 | $this->setField('user.password', $newpassword); 191 | $this->runPrepare('preparePostProcess'); 192 | $this->runPrepare('prepareAfterProcess'); 193 | $checkActivation = $this->getCFGDef('checkActivation', 0); 194 | if ($checkActivation && !$this->getField('verified')) { 195 | $this->user->logOut('WebLoginPE', true); 196 | $this->redirect('exitTo'); 197 | } 198 | $this->redirect(); 199 | if ($successTpl = $this->getCFGDef('successTpl')) { 200 | $this->renderTpl = $successTpl; 201 | } else { 202 | $this->addMessage($this->translate('profile.update_success')); 203 | } 204 | } else { 205 | $this->addMessage($this->translate('profile.update_failed')); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/core/controller/Reminder.php: -------------------------------------------------------------------------------- 1 | user = $this->loadModel( 50 | $this->getCFGDef('model', '\modUsers'), 51 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modUsers.php') 52 | ); 53 | $this->lexicon->fromFile('reminder'); 54 | $this->log('Lexicon loaded', array('lexicon' => $this->lexicon->getLexicon())); 55 | $hashField = $this->getCFGDef('hashField', 'hash'); 56 | $uidField = $this->getCFGDef('uidField', $this->user->fieldPKName()); 57 | $uidName = $this->getCFGDef('uidName', $uidField); 58 | $userField = $this->getCFGDef('userField', 'email'); 59 | $this->hashField = $hashField; 60 | $this->uidField = $uidField; 61 | $this->userField = $userField; 62 | $this->uidName = $uidName; 63 | $this->config->setConfig([ 64 | 'protectSubmit' => 0 65 | ]); 66 | if ((isset($_REQUEST[$hashField]) && !empty($_REQUEST[$hashField])) && (isset($_REQUEST[$uidName]) && !empty($_REQUEST[$uidName]))) { 67 | $this->setFields($_REQUEST); 68 | $this->mode = 'reset'; 69 | $this->config->setConfig([ 70 | 'rules' => $this->getCFGDef('resetRules'), 71 | 'reportTpl' => $this->getCFGDef('resetReportTpl'), 72 | 'submitLimit' => 0 73 | ]); 74 | } 75 | $this->log('Reminder mode is ' . $this->mode); 76 | } 77 | 78 | /** 79 | * @return string 80 | */ 81 | public function render () 82 | { 83 | if ($id = (int)$this->modx->getLoginUserID('web')) { 84 | $this->redirect('exitTo'); 85 | $this->user->edit($id); 86 | $this->setFields($this->user->toArray()); 87 | $this->renderTpl = $this->getCFGDef('skipTpl', $this->translate('reminder.default_skipTpl')); 88 | $this->setValid(false); 89 | } 90 | 91 | if ($this->mode == 'reset') { 92 | $this->renderReset(); 93 | } 94 | 95 | return parent::render(); 96 | } 97 | 98 | 99 | /** 100 | * 101 | */ 102 | public function renderReset () 103 | { 104 | $hash = $this->getField($this->hashField); 105 | $uid = $this->getField($this->uidName); 106 | $uid = (int)$uid; 107 | $_hash = $this->getUserHash($uid); 108 | if (is_scalar($hash) && $hash && $hash == $_hash) { 109 | if ($this->getCFGDef('resetTpl')) { 110 | $this->setField('user.hash', $hash); 111 | $this->setField('user.id', $uid); 112 | $this->renderTpl = $this->getCFGDef('resetTpl'); 113 | 114 | return; 115 | } 116 | $this->process(); 117 | } else { 118 | $this->addMessage($this->translate('reminder.update_failed')); 119 | } 120 | } 121 | 122 | public function getValidationRules($param = 'rules') 123 | { 124 | $rules = parent::getValidationRules($param); // TODO: Change the autogenerated stub 125 | if (isset($rules['password']) && isset($rules['repeatPassword']) && !empty($this->getField('password')) && isset($this->rules['repeatPassword']['equals'])) { 126 | $rules['repeatPassword']['equals']['params'] = $this->getField('password'); 127 | } 128 | 129 | return $rules; 130 | } 131 | 132 | /** 133 | * @param $uid 134 | * @return bool|string 135 | */ 136 | public function getUserHash ($uid) 137 | { 138 | if (is_null($this->user)) { 139 | $hash = false; 140 | } else { 141 | $userdata = $this->user->edit($uid)->toArray(); 142 | $hash = $this->user->getID() ? md5(jsonHelper::toJSON($userdata)) : false; 143 | } 144 | 145 | return $hash; 146 | } 147 | 148 | /** 149 | * 150 | */ 151 | public function process () 152 | { 153 | switch ($this->mode) { 154 | /** 155 | * Задаем хэш, отправляем пользователю ссылку для восстановления пароля 156 | */ 157 | case "hash": 158 | $user = $this->getField($this->userField); 159 | if ($hash = $this->getUserHash($user)) { 160 | $this->setFields($this->user->toArray()); 161 | $url = $this->getCFGDef('resetTo', 162 | isset($this->modx->documentIdentifier) && $this->modx->documentIdentifier > 0 ? $this->modx->documentIdentifier : $this->modx->getConfig('site_start')); 163 | $uidName = $this->getCFGDef('uidName', $this->uidField); 164 | $query = http_build_query([$uidName => $this->getField($this->uidField), $this->hashField => $hash]); 165 | if(is_numeric($url)) { 166 | $url = $this->modx->makeUrl($url, "", $query, 'full'); 167 | } else { 168 | $url .= '?' . $query; 169 | } 170 | $this->setField('reset.url', $url); 171 | $this->mailConfig['to'] = $this->user->get('email'); 172 | parent::process(); 173 | } else { 174 | $this->addMessage($this->translate('reminder.users_only')); 175 | } 176 | break; 177 | /** 178 | * Если пароль не задан, то создаем пароль 179 | * Отправляем пользователю письмо с паролем, если указан шаблон такого письма 180 | * Если не указан, то запрещаем отправку письма, пароль будет показан на экране 181 | */ 182 | case "reset": 183 | $uid = (int)$this->getField($this->uidName); 184 | $hash = $this->getField($this->hashField); 185 | if ($hash && $hash == $this->getUserHash($uid)) { 186 | if ($this->getField('password') == '' && !isset($this->rules['password'])) { 187 | $this->setField('password', APIhelpers::genPass($this->getCFGDef('passwordLength', 6))); 188 | } 189 | $fields = $this->filterFields($this->getFormData('fields'), array($this->userField, 'password')); 190 | $result = $this->user->edit($uid)->fromArray($fields)->save(true); 191 | $this->log('Update password', ['data' => $fields, 'result' => $result]); 192 | if (!$result) { 193 | $this->addMessage($this->translate('reminder.update_failed')); 194 | } else { 195 | $this->setField('newpassword', $this->getField('password')); 196 | $this->setFields($this->user->toArray()); 197 | $this->mailConfig['to'] = $this->getField('email'); 198 | parent::process(); 199 | } 200 | } else { 201 | $this->addMessage($this->translate('reminder.update_failed')); 202 | } 203 | break; 204 | } 205 | } 206 | 207 | /** 208 | * @return string 209 | */ 210 | public function getMode() { 211 | return $this->mode; 212 | } 213 | 214 | /** 215 | * 216 | */ 217 | public function postProcess () 218 | { 219 | $this->setFormStatus(true); 220 | $this->runPrepare('prepareAfterProcess'); 221 | switch ($this->mode) { 222 | case 'hash': 223 | $this->renderTpl = $this->getCFGDef('successTpl', 224 | $this->translate('reminder.default_successTpl')); 225 | break; 226 | case 'reset': 227 | default: 228 | $this->redirect(); 229 | $this->renderTpl = $this->getCFGDef('resetSuccessTpl', 230 | $this->translate('reminder.default_resetSuccessTpl')); 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/Validator.php: -------------------------------------------------------------------------------- 1 | format($format) == $value; 30 | } 31 | 32 | /** 33 | * @param $value 34 | * @param $min 35 | * @return bool 36 | */ 37 | public static function min($value, $min): bool 38 | { 39 | return is_scalar($value) && $value >= $min; 40 | } 41 | 42 | /** 43 | * @param $value 44 | * @param $max 45 | * @return bool 46 | */ 47 | public static function max($value, $max): bool 48 | { 49 | return is_scalar($value) && $value <= $max; 50 | } 51 | 52 | /** 53 | * @param $value 54 | * @param $min 55 | * @return bool 56 | */ 57 | public static function greater($value, $min): bool 58 | { 59 | return is_scalar($value) && $value > $min; 60 | } 61 | 62 | /** 63 | * @param $value 64 | * @param $max 65 | * @return bool 66 | */ 67 | public static function less($value, $max): bool 68 | { 69 | return is_scalar($value) && $value < $max; 70 | } 71 | 72 | /** 73 | * @param $value 74 | * @param $min 75 | * @param $max 76 | * @param bool $strict 77 | * @return bool 78 | */ 79 | public static function between($value, $min, $max, $strict = false): bool 80 | { 81 | return (is_scalar($value) && ($strict ? $value > $min && $value < $max : $value >= $min && $value <= $max)); 82 | } 83 | 84 | /** 85 | * @param $value 86 | * @param $allowed 87 | * @return bool 88 | */ 89 | public static function equals($value, $allowed): bool 90 | { 91 | return is_scalar($value) && $value === $allowed; 92 | } 93 | 94 | /** 95 | * @param $value 96 | * @param array $allowed 97 | * @return bool 98 | */ 99 | public static function in($value, $allowed): bool 100 | { 101 | return is_scalar($value) && in_array($value, $allowed, true); 102 | } 103 | 104 | /** 105 | * @param $value 106 | * @return bool 107 | */ 108 | public static function alpha($value): bool 109 | { 110 | return (bool) is_scalar($value) && preg_match('/^\pL++$/uD', $value); 111 | } 112 | 113 | /** 114 | * @param $value 115 | * @return bool 116 | */ 117 | public static function numeric($value): bool 118 | { 119 | return (bool) is_scalar($value) && preg_match('/^[0-9]+$/', $value); 120 | } 121 | 122 | /** 123 | * @param $value 124 | * @return bool 125 | */ 126 | public static function alphaNumeric($value): bool 127 | { 128 | return (bool) is_scalar($value) && preg_match('/^[\pL\pN]++$/uD', $value); 129 | } 130 | 131 | /** 132 | * @param $value 133 | * @return bool 134 | */ 135 | public static function slug($value): bool 136 | { 137 | return (bool) is_scalar($value) && preg_match('/^[\pL\pN\-\_]++$/uD', $value); 138 | } 139 | 140 | /** 141 | * @param $value 142 | * @return bool 143 | */ 144 | public static function decimal($value): bool 145 | { 146 | return (bool) is_scalar($value) && preg_match('/^[0-9]+(?:\.[0-9]+)?$/D', $value); 147 | } 148 | 149 | 150 | /** 151 | * @param $value 152 | * @return bool 153 | */ 154 | public static function phone($value): bool 155 | { 156 | return (bool) is_scalar($value) && preg_match('#^[0-9\(\)\+ \-]+$#', $value); 157 | } 158 | 159 | /** 160 | * @param $value 161 | * @param $regexp 162 | * @return bool 163 | */ 164 | public static function matches($value, $regexp): bool 165 | { 166 | return (bool) is_scalar($value) && preg_match($regexp, $value); 167 | } 168 | 169 | /** 170 | * @param $value 171 | * @return bool 172 | */ 173 | public static function url($value): bool 174 | { 175 | return (bool) is_scalar($value) && preg_match( 176 | '~^ 177 | [-a-z0-9+.]++:// 178 | (?!-)[-a-z0-9]{1,63}+(? $minLength : $length >= $minLength; 223 | } 224 | 225 | /** 226 | * @param $value 227 | * @param $maxLength 228 | * @param bool $strict 229 | * @return bool 230 | */ 231 | public static function maxLength($value, $maxLength, $strict = false): bool 232 | { 233 | if (!is_scalar($value)) { 234 | return false; 235 | } 236 | $length = self::getLength($value); 237 | 238 | return $strict ? $length < $maxLength : $length <= $maxLength; 239 | } 240 | 241 | /** 242 | * @param $value 243 | * @param $minLength 244 | * @param $maxLength 245 | * @param bool $strict 246 | * @return bool 247 | */ 248 | public static function lengthBetween($value, $minLength, $maxLength, $strict = false): bool 249 | { 250 | if (!is_scalar($value)) { 251 | return false; 252 | } 253 | $length = self::getLength($value); 254 | 255 | return $strict ? $length > $minLength && $length < $maxLength : $length >= $minLength && $length <= $maxLength; 256 | } 257 | 258 | /** 259 | * @param $value 260 | * @param $minSize 261 | * @param bool $strict 262 | * @return bool 263 | */ 264 | public static function minCount($value, $minSize, $strict = false): bool 265 | { 266 | if (!is_array($value)) { 267 | return false; 268 | } 269 | $count = count($value); 270 | 271 | return $strict ? $count > $minSize : $count >= $minSize; 272 | } 273 | 274 | /** 275 | * @param $value 276 | * @param $maxSize 277 | * @param bool $strict 278 | * @return bool 279 | */ 280 | public static function maxCount($value, $maxSize, $strict = false): bool 281 | { 282 | if (!is_array($value)) { 283 | return false; 284 | } 285 | $count = count($value); 286 | 287 | return $strict ? $count < $maxSize : $count <= $maxSize; 288 | } 289 | 290 | /** 291 | * @param $value 292 | * @param $minSize 293 | * @param $maxSize 294 | * @param bool $strict 295 | * @return bool 296 | */ 297 | public static function countBetween($value, $minSize, $maxSize, $strict = false): bool 298 | { 299 | if (!is_array($value)) { 300 | return false; 301 | } 302 | $count = count($value); 303 | 304 | return $strict ? $count > $minSize && $count < $maxSize : $count >= $minSize && $count <= $maxSize; 305 | } 306 | 307 | /** 308 | * @param $string 309 | * @return int 310 | */ 311 | protected static function getLength($string) 312 | { 313 | return mb_strlen($string); 314 | } 315 | 316 | /** 317 | * @param $email 318 | * @return string 319 | */ 320 | protected static function sanitizeEmail($email) 321 | { 322 | if (function_exists('idn_to_ascii')) { 323 | $_email = explode('@', $email); 324 | $_email[1] = $_email[1] ?? ''; 325 | if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) { 326 | $_email[1] = idn_to_ascii($_email[1], IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); 327 | } else { 328 | $_email[1] = idn_to_ascii($_email[1]); 329 | } 330 | $email = implode('@', $_email); 331 | } 332 | 333 | return $email; 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /assets/snippets/FormLister/lib/MailChimp/MailChimp.php: -------------------------------------------------------------------------------- 1 | 9 | * @version 2.1 10 | */ 11 | class MailChimp 12 | { 13 | private $api_key; 14 | private $api_endpoint = 'https://