├── assets
└── snippets
│ └── FormLister
│ ├── __autoload.php
│ ├── config
│ └── core
│ │ └── default.json
│ ├── core
│ ├── FormLister.abstract.php
│ ├── controller
│ │ ├── Activate.php
│ │ ├── Content.php
│ │ ├── DeleteContent.php
│ │ ├── DeleteUser.php
│ │ ├── Form.php
│ │ ├── Login.php
│ │ ├── MailChimp.php
│ │ ├── Profile.php
│ │ ├── Register.php
│ │ └── Reminder.php
│ └── lang
│ │ ├── de
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── en
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── es
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── it
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── nl
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── pl
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ ├── ru
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ │ └── uk
│ │ ├── activate.inc.php
│ │ ├── content.inc.php
│ │ ├── csrf.inc.php
│ │ ├── deleteContent.inc.php
│ │ ├── deleteUser.inc.php
│ │ ├── form.inc.php
│ │ ├── login.inc.php
│ │ ├── mailchimp.inc.php
│ │ ├── profile.inc.php
│ │ ├── register.inc.php
│ │ └── reminder.inc.php
│ ├── docs
│ └── history.md
│ ├── lib
│ ├── DateConverter.php
│ ├── Debug.php
│ ├── FileValidator.php
│ ├── Filters.php
│ ├── Gpc.php
│ ├── Lexicon.php
│ ├── MailChimp
│ │ ├── Batch.php
│ │ └── MailChimp.php
│ ├── SubmitProtection.php
│ ├── Validator.php
│ └── captcha
│ │ ├── Captcha.php
│ │ ├── modxCaptcha
│ │ ├── connector.php
│ │ ├── modxCaptcha.php
│ │ ├── noises
│ │ │ ├── index.html
│ │ │ ├── noise1.jpg
│ │ │ ├── noise2.jpg
│ │ │ ├── noise3.jpg
│ │ │ └── noise4.jpg
│ │ ├── ttf
│ │ │ └── ftb_____.ttf
│ │ └── wrapper.php
│ │ ├── reCaptcha
│ │ └── wrapper.php
│ │ ├── smsCaptcha
│ │ ├── model.php
│ │ └── wrapper.php
│ │ └── yandexCaptcha
│ │ └── wrapper.php
│ ├── plugin.userHelper.php
│ └── snippet.FormLister.php
└── install
└── assets
├── plugins
└── userHelper.tpl
└── snippets
└── FormLister.tpl
/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/config/core/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "errorClass":" has-error",
3 | "requiredClass":" has-warning",
4 | "subject":"Новое сообщение",
5 | "messagesOuterTpl":"@CODE:
[+messages+]
",
6 | "errorTpl":"@CODE:[+message+]"
7 | }
--------------------------------------------------------------------------------
/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/Content.php:
--------------------------------------------------------------------------------
1 | lexicon->fromFile('content');
44 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]);
45 | $this->content = $this->loadModel(
46 | $this->getCFGDef('model', '\modResource'),
47 | $this->getCFGDef('modelPath', 'assets/lib/MODxAPI/modResource.php')
48 | );
49 | if (is_null($this->content)) {
50 | return;
51 | }
52 | $this->user = $this->loadModel(
53 | $this->getCFGDef('userModel', '\modUsers'),
54 | $this->getCFGDef('userModelPath', 'assets/lib/MODxAPI/modUsers.php')
55 | );
56 | $idField = $this->getCFGDef('idField', 'id');
57 | $id = $this->getCFGDef($idField);
58 | if ($idField) {
59 | if ($id) {
60 | $this->mode = 'edit';
61 | $this->id = $id;
62 | } elseif (isset($_REQUEST[$idField]) && is_scalar($_REQUEST[$idField]) && (int)$_REQUEST[$idField] > 0) {
63 | $this->id = (int)$_REQUEST[$idField];
64 | $this->mode = 'edit';
65 | }
66 | }
67 | $data = [];
68 | if ($this->mode == 'edit') {
69 | $data = $this->content->edit($this->id)->toArray('', '', '_', false);
70 | $this->mailConfig['noemail'] = 1;
71 | if ($ds = $this->getCFGDef('defaultsSources')) {
72 | $defaultsSources = "{$ds};param:contentdata";
73 | } else {
74 | $defaultsSources = "param:contentdata";
75 | }
76 | $this->config->setConfig([
77 | 'defaultsSources' => $defaultsSources,
78 | 'contentdata' => $data,
79 | 'formTpl' => $this->getCFGDef('editTpl', $this->getCFGDef('formTpl')),
80 | 'successTpl' => $this->getCFGDef('editSuccessTpl'),
81 | 'onlyUsers' => 1,
82 | 'protectSubmit' => 0,
83 | 'submitLimit' => 0
84 | ]);
85 | }
86 | $this->log('Content mode is ' . $this->mode, ['data' => $data]);
87 | }
88 |
89 | /**
90 | * @return string
91 | */
92 | public function render()
93 | {
94 | $uid = (int)$this->modx->getLoginUserID('web');
95 | $ownerField = $this->getCFGDef('ownerField', 'aid');
96 | $mode = $this->mode;
97 | $flag = true;
98 |
99 | if ($mode == 'create') {
100 | if ($this->getCFGDef('onlyUsers', 1)) {
101 | if (!$uid) {
102 | $this->redirect('exitTo');
103 | $this->renderTpl = $this->getCFGDef('skipTpl',
104 | $this->translate('create.default_skipTpl'));
105 | $flag = false;
106 | } elseif (!$this->checkUserGroups($uid, $this->getCFGDef('userGroups'))) {
107 | $this->redirect('badGroupTo');
108 | $this->renderTpl = $this->getCFGDef('badGroupTpl',
109 | $this->translate('create.default_badGroupTpl'));
110 | $flag = false;
111 | }
112 | }
113 | $this->owner = $uid;
114 | }
115 |
116 | if ($mode == 'edit') {
117 | if (!$uid) {
118 | $this->redirect('exitTo');
119 | $this->renderTpl = $this->getCFGDef('skipEditTpl',
120 | $this->translate('edit.default_skipEditTpl'));
121 | $flag = false;
122 | } elseif (!$this->checkUserGroups($uid, $this->getCFGDef('userGroups'))) {
123 | $this->redirect('badGroupTo');
124 | $this->renderTpl = $this->getCFGDef('badGroupTpl',
125 | $this->translate('edit.default_badGroupTpl'));
126 | $flag = false;
127 | } else {
128 | $cid = is_null($this->content) ? false : $this->content->getID();
129 | if ($cid) {
130 | $owner = (int)$this->content->get($ownerField);
131 | if ($this->getCFGDef('onlyOwners', 1) && $owner !== $uid) {
132 | $this->redirect('badOwnerTo');
133 | $this->renderTpl = $this->getCFGDef('badOwnerTpl',
134 | $this->translate('edit.default_badOwnerTpl'));
135 | $flag = false;
136 | }
137 | $this->owner = $uid;
138 | } else {
139 | $this->redirect('badRecordTo');
140 | $this->renderTpl = $this->getCFGDef('badRecordTpl',
141 | $this->translate('edit.default_badRecordTpl'));
142 | $flag = false;
143 | }
144 | }
145 |
146 | if ($flag && !$this->isSubmitted()) {
147 | $fields = $this->getContentFields();
148 | $this->setFields($fields);
149 | }
150 | }
151 |
152 | $this->setValid($flag);
153 |
154 | return parent::render();
155 | }
156 |
157 | /**
158 | *
159 | */
160 | public function process()
161 | {
162 | $fields = $this->getContentFields();
163 | $ownerField = $this->getCFGDef('ownerField', 'aid');
164 | $result = false;
165 | if ($fields && !is_null($this->content)) {
166 | $clearCache = $this->getCFGDef('clearCache', false);
167 | switch ($this->mode) {
168 | case 'create':
169 | if ($this->checkSubmitProtection() || $this->checkSubmitLimit()) {
170 | return;
171 | }
172 | if ($this->owner || !$this->getCFGDef('onlyUsers', 1)) {
173 | $fields[$ownerField] = $this->owner;
174 | $result = $this->content->create($fields)->save(true, $clearCache);
175 | $this->log('Create record', ['data' => $fields, 'result' => $result ,'log' => $this->content->getLog()]);
176 | }
177 | if ($result) {
178 | $url = '';
179 |
180 | $evtOut = $this->modx->invokeEvent('OnMakeDocUrl', [
181 | 'invokedBy' => __CLASS__,
182 | 'id' => $result,
183 | 'data' => $this->getFormData('fields')
184 | ]);
185 | if (is_array($evtOut) && count($evtOut) > 0) {
186 | $url = array_pop($evtOut);
187 | }
188 | if ($url) {
189 | $this->setField('content.url', $url);
190 | }
191 | $this->log('Created record', ['data' => $fields, 'result' => $result]);
192 | }
193 | break;
194 | case 'edit':
195 | $result = $this->content->fromArray($fields)->save(true, $clearCache);
196 | if ($result) {
197 | $this->log('Update record', ['data' => $fields, 'result' => $result]);
198 | }
199 | break;
200 | }
201 | }
202 | if (!$result) {
203 | $this->log('Save failed', ['model' => get_class($this->content), 'data' => $fields]);
204 | $this->addMessage($this->translate('edit.update_failed'));
205 | } else {
206 | $this->content->close();
207 | $this->setFields($this->content->edit($result)->toArray('', '', '_', false));
208 | if ($this->getCFGDef('contentFields')) {
209 | $this->setFields($this->getContentFields(true));
210 | }
211 | if ($this->owner) {
212 | $this->setFields($this->user->edit($this->owner)->toArray(), 'user');
213 | }
214 | $this->runPrepare('preparePostProcess');
215 | $this->log('Update form data', ['data' => $this->getFormData('fields')]);
216 | if ($this->mode == 'create') {
217 | parent::process();
218 | } else {
219 | $this->postProcess();
220 | }
221 | }
222 | }
223 |
224 | /**
225 | *
226 | */
227 | public function postProcess()
228 | {
229 | $this->setFormStatus(true);
230 | $this->runPrepare('prepareAfterProcess');
231 | if ($this->mode == 'create') {
232 | if ($this->getCFGDef('editAfterCreate', 0)) {
233 | $idField = $this->getCFGDef('idField');
234 | $this->redirect('redirectTo', [$idField => $this->getField($idField)]);
235 | } else {
236 | $this->redirect();
237 | }
238 | $this->renderTpl = $this->getCFGDef('successTpl', $this->translate('create.default_successTpl'));
239 | } else {
240 | if ($successTpl = $this->getCFGDef('successTpl')) {
241 | $this->renderTpl = $successTpl;
242 | } else {
243 | $this->addMessage($this->translate('edit.update_success'));
244 | }
245 | }
246 | }
247 |
248 | /**
249 | * @param bool $flip
250 | * @return array
251 | */
252 | public function getContentFields($flip = false)
253 | {
254 | $fields = [];
255 | $contentFields = $this->getCFGDef('contentFields');
256 | $contentFields = $this->config->loadArray($contentFields, '');
257 | if (!$contentFields) {
258 | $fields = $this->filterFields($this->getFormData('fields'), $this->allowedFields, $this->forbiddenFields);
259 | $this->log('Unable to get juxtaposition of content fields', ['contentFields' => $fields]);
260 | } else {
261 | if ($flip || ($this->mode == 'edit' && !$this->isSubmitted())) {
262 | $contentFields = array_flip($contentFields);
263 | }
264 | foreach ($contentFields as $field => $formField) {
265 | $formField = $this->getField($formField);
266 | if ($formField !== '' || $this->getCFGDef('allowEmptyFields', 1)) {
267 | $fields[$field] = $formField;
268 | }
269 | }
270 | $this->log('Juxtaposition of content fields', ['contentFields' => $fields]);
271 | }
272 |
273 | return $fields;
274 | }
275 |
276 | /**
277 | * @return string
278 | */
279 | public function getMode()
280 | {
281 | return $this->mode;
282 | }
283 |
284 | /**
285 | * @param $uid
286 | * @param string $groups
287 | * @return bool
288 | */
289 | public function checkUserGroups($uid, $groups = '')
290 | {
291 | $flag = true;
292 | if (is_scalar($groups) && !empty($groups) && !is_null($this->user)) {
293 | $groups = explode(';', $groups);
294 | if (!empty($groups)) {
295 | $userGroups = $this->user->getUserGroups($uid);
296 | $flag = !empty(array_intersect($groups, $userGroups));
297 | }
298 | }
299 | $this->log('Check user groups', ['result' => $flag]);
300 |
301 | return $flag;
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/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/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/Form.php:
--------------------------------------------------------------------------------
1 | mailConfig = [
32 | 'isHtml' => $this->getCFGDef('isHtml', 1),
33 | 'to' => $this->getCFGDef('to', ''),
34 | 'from' => $this->getCFGDef('from', $this->modx->getConfig('emailsender')),
35 | 'fromName' => $this->getCFGDef('fromName', $this->modx->getConfig('site_name')),
36 | 'subject' => $this->getCFGDef('subject', ''),
37 | 'replyTo' => $this->getCFGDef('replyTo', ''),
38 | 'cc' => $this->getCFGDef('cc', ''),
39 | 'bcc' => $this->getCFGDef('bcc', ''),
40 | 'noemail' => $this->getCFGDef('noemail', false)
41 | ];
42 | $this->lexicon->fromFile('form');
43 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]);
44 | }
45 |
46 | /**
47 | * Формирует текст письма для отправки
48 | * Если основной шаблон письма не задан, то формирует список полей формы
49 | * @param string $tplParam имя параметра с шаблоном письма
50 | * @return null|string
51 | */
52 | public function renderReport ($tplParam = 'reportTpl')
53 | {
54 | $tpl = $this->getCFGDef($tplParam, '');
55 | $skipPrerender = $this->getCFGDef('skipPrerender', 0);
56 | if (empty($tpl) && $tplParam == 'reportTpl') {
57 | $tpl = '@CODE:';
58 | foreach ($this->getFormData('fields') as $key => $value) {
59 | $tpl .= \APIhelpers::e($key) . ": [+{$key}.value+]" . PHP_EOL;
60 | }
61 | $skipPrerender = false;
62 | }
63 | $out = $this->parseChunk($tpl, $skipPrerender ? $this->getFormData('fields') : $this->prerenderForm(true));
64 |
65 | return $out;
66 | }
67 |
68 | /**
69 | * Получает тему письма из шаблона или строки
70 | * @param string $param
71 | * @return mixed|null|string
72 | */
73 | public function renderSubject ($param = 'subject')
74 | {
75 | $subject = $this->getCFGDef($param . 'Tpl');
76 | if (!empty($subject)) {
77 | $subject = $this->parseChunk($subject, $this->prerenderForm(true));
78 | } else {
79 | $subject = $this->getCFGDef($param, '');
80 | }
81 | if($param !== 'subject' && empty($subject)) {
82 | $subject = $this->renderSubject();
83 | }
84 |
85 | return $subject;
86 | }
87 |
88 | /**
89 | * @return array
90 | */
91 | public function getAttachments ()
92 | {
93 | $attachments = [];
94 | $attach = $this->config->loadArray($this->getCFGDef('attachments'));
95 | $formfiles = $this->getFormData('files');
96 | foreach ($attach as $field) {
97 | if (!isset($formfiles[$field])) continue;
98 | $files = $formfiles[$field];
99 | if (!isset($files[0])) {
100 | $files = array($files);
101 | }
102 | foreach ($files as $file) {
103 | if ($file['error'] === 0) {
104 | $attachments[] = array('filepath' => $file['tmp_name'], 'filename' => $file['name']);
105 | }
106 | }
107 | }
108 | $userfiles = $this->config->loadArray($this->getCFGDef('attachFiles'));
109 | foreach ($userfiles as $field => $files) {
110 | if (!isset($files[0])) {
111 | $files = array($files);
112 | }
113 | foreach ($files as $file) {
114 | if (isset($file['filepath']) && isset($file['filename'])) {
115 | $attachments[] = array(
116 | 'filepath' => MODX_BASE_PATH . $file['filepath'],
117 | 'filename' => $file['filename']
118 | );
119 | }
120 | }
121 | }
122 |
123 | return $attachments;
124 | }
125 |
126 | /**
127 | * @return $this
128 | */
129 | public function setFileFields ()
130 | {
131 | $fields = [];
132 | $attach = $this->config->loadArray($this->getCFGDef('attachments'));
133 | $formfiles = $this->getFormData('files');
134 | foreach ($attach as $field) {
135 | if (!isset($formfiles[$field])) continue;
136 | $files = $formfiles[$field];
137 | if (!isset($files[0])) {
138 | $files = array($files);
139 | }
140 | foreach ($files as $file) {
141 | if ($file['error'] === 0) {
142 | $fields[$field][] = $file['name'];
143 | }
144 | }
145 | }
146 | $userfiles = $this->config->loadArray($this->getCFGDef('attachFiles'));
147 | foreach ($userfiles as $field => $files) {
148 | if (!isset($files[0])) {
149 | $files = array($files);
150 | }
151 | foreach ($files as $file) {
152 | if (isset($file['filename']) && isset($file['filepath'])) {
153 | $fields[$field][] = $file['filename'];
154 | }
155 | }
156 | }
157 | if (!empty($fields)) {
158 | $this->setFields($fields);
159 | }
160 |
161 | return $this;
162 | }
163 |
164 | /**
165 | * Оправляет письмо
166 | * @return mixed
167 | */
168 | public function sendReport ()
169 | {
170 | $mailer = new Mailer($this->modx, array_merge(
171 | $this->mailConfig,
172 | ['subject' => $this->renderSubject()]
173 | ));
174 | $attachments = $this->getAttachments();
175 | if ($attachments) {
176 | $mailer->attachFiles($attachments);
177 | $this->log('Attachments', $attachments);
178 | $field = [];
179 | foreach ($attachments as $file) {
180 | $field[] = $file['filename'];
181 | }
182 | $this->setField('attachments', $field);
183 | }
184 | $report = $this->renderReport();
185 | $out = $mailer->send($report) || $this->getCFGDef('ignoreMailerResult', 0);
186 | $this->log('Mail report', [
187 | 'report' => $report,
188 | 'mailer_config' => $mailer->config,
189 | 'result' => $out
190 | ]);
191 |
192 | return $out;
193 | }
194 |
195 | /**
196 | * Оправляет копию письма на указанный адрес
197 | * @return mixed
198 | */
199 | public function sendAutosender ()
200 | {
201 | $to = $this->getCFGDef('autosender', '');
202 |
203 | $config = $this->getMailSendConfig($to, 'autosenderFromName', 'autoSubject');
204 | $asConfig = $this->config->loadArray($this->getCFGDef('autoMailConfig'));
205 | if (!empty($asConfig) && is_array($asConfig)) {
206 | $asConfig = $this->parseMailerParams($asConfig);
207 | $config = array_merge($config, $asConfig);
208 | }
209 | $mailer = new Mailer($this->modx, $config);
210 | $report = $this->renderReport('automessageTpl');
211 | $out = empty($to) ? true : $mailer->send($report);
212 | $this->log(
213 | 'Mail autosender report',
214 | [
215 | 'report' => $report,
216 | 'mailer_config' => $mailer->config,
217 | 'result' => $out
218 | ]
219 | );
220 |
221 | return $out;
222 | }
223 |
224 | /**
225 | * Отправляет копию письма на адрес из поля email
226 | * @return mixed
227 | */
228 | public function sendCCSender ()
229 | {
230 | $to = $this->getField($this->getCFGDef('ccSenderField', 'email'), '');
231 |
232 | if ($this->getCFGDef('ccSender', 0)) {
233 | $config = $this->getMailSendConfig($to, 'ccSenderFromName', 'ccSubject');
234 | $ccConfig = $this->config->loadArray($this->getCFGDef('ccMailConfig'));
235 | if (!empty($ccConfig) && is_array($ccConfig)) {
236 | $ccConfig = $this->parseMailerParams($ccConfig);
237 | $config = array_merge($config, $ccConfig);
238 | }
239 | $mailer = new Mailer($this->modx, $config);
240 | $report = $this->renderReport('ccSenderTpl');
241 | $out = empty($to) ? true : $mailer->send($report);
242 | $this->log(
243 | 'Mail CC report',
244 | [
245 | 'report' => $report,
246 | 'mailer_config' => $mailer->config,
247 | 'result' => $out
248 | ]
249 | );
250 | } else {
251 | $out = true;
252 | }
253 |
254 | return $out;
255 | }
256 |
257 | /**
258 | * @return string
259 | */
260 | public function render ()
261 | {
262 | if ($this->isSubmitted() && ($this->checkSubmitLimit() || $this->checkSubmitProtection())) {
263 | return $this->renderForm();
264 | }
265 |
266 | return parent::render();
267 | }
268 |
269 | /**
270 | *
271 | */
272 | public function process ()
273 | {
274 | $now = time() + $this->modx->getConfig('server_offset_time');
275 | $this->setField('form.date', date($this->getCFGDef('dateFormat', $this->translate('form.dateFormat')), $now));
276 | $this->setFileFields();
277 | $this->mailConfig = $this->parseMailerParams($this->mailConfig);
278 | if ($this->sendReport()) {
279 | $this->sendCCSender();
280 | $this->sendAutosender();
281 | $this->setSubmitProtection()->postProcess();
282 | } else {
283 | $this->addMessage($this->translate('form.form_failed'));
284 | }
285 | }
286 |
287 | /**
288 | * @param array $cfg
289 | * @return array
290 | */
291 | public function parseMailerParams ($cfg = [])
292 | {
293 | if ($this->getCFGDef('parseMailerParams', 0) && !empty($cfg)) {
294 | $plh = \APIhelpers::renameKeyArr($this->prerenderForm(true), '[', ']', '+');
295 | $search = array_keys($plh);
296 | $replace = array_values($plh);
297 | foreach ($cfg as $key => &$value) {
298 | if(empty($value)) continue;
299 | $value = str_replace($search, $replace, $value);
300 | }
301 | $config = \APIhelpers::renameKeyArr($this->modx->config, '[(', ')]', '');
302 | $search = array_keys($config);
303 | $replace = array_values($config);
304 | foreach ($cfg as $key => &$value) {
305 | $value = str_replace($search, $replace, $value);
306 | }
307 | }
308 |
309 | return $cfg;
310 | }
311 |
312 | /**
313 | *
314 | */
315 | public function postProcess ()
316 | {
317 | $this->setFormStatus(true);
318 | $this->runPrepare('prepareAfterProcess');
319 | if ($this->getCFGDef('deleteAttachments', 0)) {
320 | $this->deleteAttachments();
321 | }
322 | $this->redirect();
323 | $tpl = $this->getCFGDef('successTpl', $this->translate('form.default_successTpl'));
324 | if (!empty($tpl)) {
325 | $this->renderTpl = $tpl;
326 | }
327 | }
328 |
329 | /**
330 | * @param string $to
331 | * @param string $fromParam
332 | * @param string $subjectParam
333 | * @return array
334 | */
335 | public function getMailSendConfig ($to, $fromParam, $subjectParam = 'subject')
336 | {
337 | $subject = $this->renderSubject($subjectParam);
338 |
339 | $out = array_merge(
340 | $this->mailConfig,
341 | [
342 | 'subject' => $subject,
343 | 'to' => $to,
344 | 'fromName' => $this->getCFGDef($fromParam, $this->modx->getConfig('site_name'))
345 | ]
346 | );
347 | $out = $this->parseMailerParams($out);
348 |
349 | return $out;
350 | }
351 |
352 | /**
353 | * @return $this
354 | */
355 | public function deleteAttachments ()
356 | {
357 | $files = $this->getAttachments();
358 | foreach ($files as $file) {
359 | $this->fs->delete($file['filepath']);
360 | }
361 |
362 | return $this;
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/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/core/controller/MailChimp.php:
--------------------------------------------------------------------------------
1 | lexicon->fromFile('mailchimp');
20 | $this->log('Lexicon loaded', ['lexicon' => $this->lexicon->getLexicon()]);
21 | }
22 |
23 | /**
24 | * @return bool
25 | */
26 | public function process()
27 | {
28 | $errorMessage = $this->translate('mc.subscription_failed');
29 | if (!$this->getCFGDef('apiKey')) {
30 | $this->addMessage($errorMessage);
31 |
32 | return false;
33 | }
34 | $MailChimp = new \DrewM\MailChimp\MailChimp($this->getCFGDef('apiKey'));
35 | $list_id = $this->getCFGDef('listId');
36 | if (!$list_id) {
37 | $this->addMessage($errorMessage);
38 |
39 | return false;
40 | }
41 |
42 | $MailChimp->post("lists/{$list_id}/members", [
43 | 'email_address' => $this->getField('email'),
44 | 'merge_fields' => ['NAME' => $this->getField('name')],
45 | 'status' => 'pending',
46 | ]);
47 | if (!$MailChimp->getLastError()) {
48 | $this->addMessage($errorMessage);
49 |
50 | return false;
51 | } else {
52 | $this->setFormStatus(true);
53 | $this->runPrepare('prepareAfterProcess');
54 | $this->renderTpl = $this->getCFGDef('successTpl', $this->translate('mc.default_successTpl'));
55 |
56 | return true;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/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/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/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/core/lang/de/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'Dieses Konto muss nicht, oder kann nicht aktiviert werden.';
13 | $_lang['activate.update_failed'] = 'Fehler beim Fortfahren.';
14 | $_lang['activate.default_successTpl'] = '@CODE:Der Link zum Aktivieren Ihres Kontos wurde gesendet.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Dein Benutzerkonto ist aktiv.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/de/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Die Authentifizierung der Anfrage ist fehlgeschlagen'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/de/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Nur registrierte Benutzer können Passwörter wiederherstellen.';
13 | $_lang['reminder.update_failed'] = 'Fehler beim Fortfahren.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:Der Link zum Wiederherstellen Ihres Passworts wurde gesendet.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:Das neue Passwort wurde gesendet.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/en/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'This user account need no activation or cannot be activated.';
13 | $_lang['activate.update_failed'] = 'Failed to proceed.';
14 | $_lang['activate.default_successTpl'] = '@CODE:The link to activate your account has been mailed.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Your account is activated.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/en/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Failed to authenticate request'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/en/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Only registered users can restore passwords.';
13 | $_lang['reminder.update_failed'] = 'Failed to proceed.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:The link to restore your password has been mailed.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:New password has been mailed.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/es/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'Esta cuenta de usuario no necesita activación o no puede ser activada.';
13 | $_lang['activate.update_failed'] = 'Fallo al proceder.';
14 | $_lang['activate.default_successTpl'] = '@CODE:El enlace para activar su cuenta ha sido enviado.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Tu cuenta está activa.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/es/content.inc.php:
--------------------------------------------------------------------------------
1 | 'No se pudo autenticar la solicitud'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/es/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Solo los usuarios registrados pueden restaurar contraseñas.';
13 | $_lang['reminder.update_failed'] = 'Fallo al proceder.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:El enlace para restaurar su contraseña ha sido enviado.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:La nueva contraseña ha sido enviada.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/it/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'Questo account utente non ha bisogno di attivazione o non può essere attivato.';
13 | $_lang['activate.update_failed'] = 'Impossibile procedere.';
14 | $_lang['activate.default_successTpl'] = '@CODE:Il link per attivare il tuo account è stato inviato via mail.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Il tuo account è attivato.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/it/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Impossibile autenticare la richiesta'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/it/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Solo gli utenti registrati possono ripristinare le password.';
13 | $_lang['reminder.update_failed'] = 'Impossibile procedere.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:Il link per ripristinare la password è stato inviato per posta.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:La nuova password è stata inviata via mail.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/nl/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'Dit gebruikersaccount hoeft niet te worden geactiveerd of kan niet worden geactiveerd.';
13 | $_lang['activate.update_failed'] = 'Update mislukt.';
14 | $_lang['activate.default_successTpl'] = '@CODE:De link om uw account te activeren is gemaild.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Uw account is geactiveerd.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/nl/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Kan het verzoek niet verifiëren'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/nl/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Alleen geregistreerde gebruikers kunnen wachtwoorden herstellen.';
13 | $_lang['reminder.update_failed'] = 'Kan niet doorgaan.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:De link om uw wachtwoord te herstellen is gemaild.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:Nieuw wachtwoord is gemaild.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/pl/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+activate.url+]';
12 | $_lang['activate.no_activation'] = 'To konto nie potrzebuje aktywacji lub nie może zostać aktywowane.';
13 | $_lang['activate.update_failed'] = 'Akcja zakończona niepowodzeniem.';
14 | $_lang['activate.default_successTpl'] = '@CODE:Wiadomość z linkiem aktywacyjnym została wysłana na wskazany adres e-mail.';
15 | $_lang['activate.default_resetSuccessTpl'] = '@CODE:Twoje konto zostało aktywowane.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/pl/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Nie udało się uwierzytelnić żądania'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/pl/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
12 | $_lang['reminder.users_only'] = 'Tylko zarejestrowani użytkownicy mogą zresetować hasło.';
13 | $_lang['reminder.update_failed'] = 'Akcja zakończona niepowodzeniem.';
14 | $_lang['reminder.default_successTpl'] = '@CODE:Wiadomość z linkiem resetującym hasło została wysłana na wskazany adres e-mail.';
15 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:Nowe hasło zostało wysłane na wskazany adres e-mail.';
16 |
17 | return $_lang;
18 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/ru/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
14 | $_lang['activate.no_activation'] = 'Эта учетная запись не требует активации или не может быть активирована.';
15 | $_lang['activate.update_failed'] = 'Не удалось выполнить операцию.';
16 | $_lang['activate.default_successTpl'] = '@CODE:Вам отправлено письмо со ссылкой для активации учетной записи.';
17 | $_lang['activate.default_activateSuccessTpl'] = '@CODE:Учетная запись успешно активирована.';
18 |
19 | return $_lang;
20 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/ru/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Не удалось проверить подлинность запроса'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/ru/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
14 | $_lang['reminder.users_only'] = 'Только зарегистрированные пользователи могут восстанавливать пароли.';
15 | $_lang['reminder.update_failed'] = 'Не удалось выполнить операцию.';
16 | $_lang['reminder.default_successTpl'] = '@CODE:Вам отправлено письмо со ссылкой для восстановления пароля.';
17 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:Вам отправлено письмо с новым паролем.';
18 |
19 | return $_lang;
20 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/uk/activate.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
14 | $_lang['activate.no_activation'] = 'Цей обліковий запис не вимагає активації або не може бути активованим.';
15 | $_lang['activate.update_failed'] = 'Не вдалося виконати операцію.';
16 | $_lang['activate.default_successTpl'] = '@CODE:Вам відправлено лист з посиланням для активації облікового запису.';
17 | $_lang['activate.default_activateSuccessTpl'] = '@CODE:Обліковий запис успішно активований.';
18 |
19 | return $_lang;
20 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/uk/content.inc.php:
--------------------------------------------------------------------------------
1 | 'Неможливо перевірити справжність запиту'
4 | ];
5 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/core/lang/uk/deleteContent.inc.php:
--------------------------------------------------------------------------------
1 | [+reset.url+]';
14 | $_lang['reminder.users_only'] = 'Тільки зареєстровані користувачі можуть відновлювати паролі.';
15 | $_lang['reminder.update_failed'] = 'Не вдалося виконати операцію.';
16 | $_lang['reminder.default_successTpl'] = '@CODE:Вам відправлено лист з посиланням для відновлення пароля.';
17 | $_lang['reminder.default_resetSuccessTpl'] = '@CODE:Вам відправлено лист з новим паролем.';
18 |
19 | return $_lang;
20 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/DateConverter.php:
--------------------------------------------------------------------------------
1 | dateFormat)) {
19 | $date = DateTime::createFromFormat($this->dateFormat, $value);
20 | if ($date !== false) {
21 | $date = $date->getTimestamp();
22 | }
23 | }
24 |
25 | return $date;
26 | }
27 |
28 | /**
29 | * @param $value
30 | */
31 | public function fromTimestamp($value) {
32 | $date = false;
33 | if (!empty($value) && !empty($this->dateFormat)) {
34 | $date = date($this->dateFormat, $value);
35 | }
36 |
37 | return $date;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/Debug.php:
--------------------------------------------------------------------------------
1 | modx = $modx;
29 | $this->timeStart = microtime(true);
30 | if (isset($cfg['caller'])) {
31 | $this->caller = $cfg['caller'];
32 | }
33 | }
34 |
35 | /**
36 | * @param $message
37 | * @param array $data
38 | */
39 | public function log($message, $data = array())
40 | {
41 | if (is_array($data) && isset($data[0]) && is_array($data[0])) {
42 | $data = array_pop($data);
43 | }
44 | $this->log[] = array(
45 | 'message' => $message,
46 | 'data' => $this->dumpData($data, 'pre'),
47 | 'time' => microtime(true) - $this->timeStart
48 | );
49 | }
50 |
51 | /**
52 | * @param $data
53 | * @param string $wrap
54 | * @param string $charset
55 | * @return array|mixed|string
56 | */
57 | public function dumpData($data, $wrap = '', $charset = 'UTF-8')
58 | {
59 | $out = \APIHelpers::sanitarTag(print_r($this->cleanData($data), 1), $charset);
60 | if (!empty($wrap) && is_string($wrap)) {
61 | $out = "<{$wrap}>{$out}{$wrap}>";
62 | }
63 |
64 | return $out;
65 | }
66 |
67 | /**
68 | * @param $data
69 | * @return array
70 | */
71 | public function cleanData($data) {
72 | if (is_array($data)) {
73 | foreach ($data as $key => $value) {
74 | if (is_object($value)) {
75 | $data[$key] = 'Object: ' . get_class($value);
76 | } elseif (is_array($value)) {
77 | $data[$key] = $this->cleanData($value);
78 | }
79 | }
80 | if (empty($data)) {
81 | $data = 'No data provided' . PHP_EOL;
82 | }
83 | }
84 |
85 | return $data;
86 | }
87 |
88 | public function saveLog()
89 | {
90 | $out = '';
91 | foreach ($this->log as $entry) {
92 | $out .= "{$entry['message']}
";
93 | if ($entry['data']) {
94 | $out .= $entry['data'];
95 | }
96 | $out .= "Time: {$entry['time']}
";
97 | $out .= '
';
98 | }
99 | $time = microtime(true) - $this->timeStart;
100 | $out .= "Total time: {$time}
";
101 | if ($out) {
102 | $this->modx->logEvent(0, 1, $out, $this->caller);
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/FileValidator.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/lib/Filters.php:
--------------------------------------------------------------------------------
1 | setGpcSeed();
18 | $this->fields = $fields;
19 | }
20 |
21 | /**
22 | * @return string
23 | */
24 | private function setGpcSeed ()
25 | {
26 | $this->gpc_seed = 'sanitize_seed_' . base_convert(md5(realpath(MODX_MANAGER_PATH . 'includes/protect.inc.php')),
27 | 16, 36);
28 |
29 | return;
30 | }
31 |
32 | /**
33 | * Remove fucking modX_sanitize_gpc
34 | *
35 | * @param $target
36 | * @param int $count
37 | * @return mixed
38 | */
39 | public function removeGpc (&$target, $count = 0)
40 | {
41 | if (empty($this->gpc_seed) || empty($this->fields)) return;
42 |
43 | foreach ($target as $key => $value) {
44 | if (!in_array($key, $this->fields)) {
45 | continue;
46 | }
47 | if (is_array($value)) {
48 | $count++;
49 | if (10 < $count) {
50 | break;
51 | }
52 | $this->removeGpc($value, $count);
53 | $count--;
54 | } else {
55 | $value = str_replace($this->gpc_seed, '', $value);
56 | $value = str_replace('sanitized_by_modxfields;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/Lexicon.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/MailChimp/MailChimp.php:
--------------------------------------------------------------------------------
1 |
9 | * @version 2.1
10 | */
11 | class MailChimp
12 | {
13 | private $api_key;
14 | private $api_endpoint = 'https://.api.mailchimp.com/3.0';
15 |
16 | /* SSL Verification
17 | Read before disabling:
18 | http://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/
19 | */
20 | public $verify_ssl = true;
21 |
22 | private $last_error = '';
23 | private $last_response = array();
24 | private $last_request = array();
25 |
26 | /**
27 | * Create a new instance
28 | * @param string $api_key Your MailChimp API key
29 | */
30 | public function __construct($api_key)
31 | {
32 | $this->api_key = $api_key;
33 |
34 | list(, $datacentre) = explode('-', $this->api_key);
35 | $this->api_endpoint = str_replace('', $datacentre, $this->api_endpoint);
36 |
37 | $this->last_response = array('headers'=>null, 'body'=>null);
38 | }
39 |
40 | /**
41 | * Create a new instance of a Batch request. Optionally with the ID of an existing batch.
42 | * @param string $batch_id Optional ID of an existing batch, if you need to check its status for example.
43 | * @return Batch New Batch object.
44 | */
45 | public function newBatch($batch_id=null)
46 | {
47 | return new Batch($this, $batch_id);
48 | }
49 |
50 | /**
51 | * Convert an email address into a 'subscriber hash' for identifying the subscriber in a method URL
52 | * @param string $email The subscriber's email address
53 | * @return string Hashed version of the input
54 | */
55 | public function getSubscriberHash($email)
56 | {
57 | return md5(strtolower($email));
58 | }
59 |
60 | /**
61 | * Get the last error returned by either the network transport, or by the API.
62 | * If something didn't work, this should contain the string describing the problem.
63 | * @return array|false describing the error
64 | */
65 | public function getLastError()
66 | {
67 | if ($this->last_error) return $this->last_error;
68 | return false;
69 | }
70 |
71 | /**
72 | * Get an array containing the HTTP headers and the body of the API response.
73 | * @return array Assoc array with keys 'headers' and 'body'
74 | */
75 | public function getLastResponse()
76 | {
77 | return $this->last_response;
78 | }
79 |
80 | /**
81 | * Get an array containing the HTTP headers and the body of the API request.
82 | * @return array Assoc array
83 | */
84 | public function getLastRequest()
85 | {
86 | return $this->last_request;
87 | }
88 |
89 | /**
90 | * Make an HTTP DELETE request - for deleting data
91 | * @param string $method URL of the API request method
92 | * @param array $args Assoc array of arguments (if any)
93 | * @param int $timeout Timeout limit for request in seconds
94 | * @return array|false Assoc array of API response, decoded from JSON
95 | */
96 | public function delete($method, $args=array(), $timeout=10)
97 | {
98 | return $this->makeRequest('delete', $method, $args, $timeout);
99 | }
100 |
101 | /**
102 | * Make an HTTP GET request - for retrieving data
103 | * @param string $method URL of the API request method
104 | * @param array $args Assoc array of arguments (usually your data)
105 | * @param int $timeout Timeout limit for request in seconds
106 | * @return array|false Assoc array of API response, decoded from JSON
107 | */
108 | public function get($method, $args=array(), $timeout=10)
109 | {
110 | return $this->makeRequest('get', $method, $args, $timeout);
111 | }
112 |
113 | /**
114 | * Make an HTTP PATCH request - for performing partial updates
115 | * @param string $method URL of the API request method
116 | * @param array $args Assoc array of arguments (usually your data)
117 | * @param int $timeout Timeout limit for request in seconds
118 | * @return array|false Assoc array of API response, decoded from JSON
119 | */
120 | public function patch($method, $args=array(), $timeout=10)
121 | {
122 | return $this->makeRequest('patch', $method, $args, $timeout);
123 | }
124 |
125 | /**
126 | * Make an HTTP POST request - for creating and updating items
127 | * @param string $method URL of the API request method
128 | * @param array $args Assoc array of arguments (usually your data)
129 | * @param int $timeout Timeout limit for request in seconds
130 | * @return array|false Assoc array of API response, decoded from JSON
131 | */
132 | public function post($method, $args=array(), $timeout=10)
133 | {
134 | return $this->makeRequest('post', $method, $args, $timeout);
135 | }
136 |
137 | /**
138 | * Make an HTTP PUT request - for creating new items
139 | * @param string $method URL of the API request method
140 | * @param array $args Assoc array of arguments (usually your data)
141 | * @param int $timeout Timeout limit for request in seconds
142 | * @return array|false Assoc array of API response, decoded from JSON
143 | */
144 | public function put($method, $args=array(), $timeout=10)
145 | {
146 | return $this->makeRequest('put', $method, $args, $timeout);
147 | }
148 |
149 | /**
150 | * Performs the underlying HTTP request. Not very exciting.
151 | * @param string $http_verb The HTTP verb to use: get, post, put, patch, delete
152 | * @param string $method The API method to be called
153 | * @param array $args Assoc array of parameters to be passed
154 | * @return array|false Assoc array of decoded result
155 | */
156 | private function makeRequest($http_verb, $method, $args=array(), $timeout=10)
157 | {
158 | if (!function_exists('curl_init') || !function_exists('curl_setopt')) {
159 | throw new \Exception("cURL support is required, but can't be found.");
160 | }
161 |
162 | $url = $this->api_endpoint.'/'.$method;
163 |
164 | $this->last_error = '';
165 | $response = array('headers'=>null, 'body'=>null);
166 | $this->last_response = $response;
167 |
168 | $this->last_request = array(
169 | 'method' => $http_verb,
170 | 'path' => $method,
171 | 'url' => $url,
172 | 'body' => '',
173 | 'timeout'=> $timeout,
174 | );
175 |
176 | $ch = curl_init();
177 | curl_setopt($ch, CURLOPT_URL, $url);
178 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/vnd.api+json',
179 | 'Content-Type: application/vnd.api+json',
180 | 'Authorization: apikey '.$this->api_key));
181 | curl_setopt($ch, CURLOPT_USERAGENT, 'DrewM/MailChimp-API/3.0 (github.com/drewm/mailchimp-api)');
182 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
183 | curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
184 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl);
185 | curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
186 | curl_setopt($ch, CURLOPT_ENCODING, '');
187 | curl_setopt($ch, CURLINFO_HEADER_OUT, true);
188 |
189 | switch($http_verb) {
190 | case 'post':
191 | curl_setopt($ch, CURLOPT_POST, true);
192 | $this->attachRequestPayload($ch, $args);
193 | break;
194 |
195 | case 'get':
196 | $query = http_build_query($args);
197 | curl_setopt($ch, CURLOPT_URL, $url.'?'.$query);
198 | break;
199 |
200 | case 'delete':
201 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
202 | break;
203 |
204 | case 'patch':
205 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
206 | $this->attachRequestPayload($ch, $args);
207 | break;
208 |
209 | case 'put':
210 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
211 | $this->attachRequestPayload($ch, $args);
212 | break;
213 | }
214 |
215 | $response['body'] = curl_exec($ch);
216 | $response['headers'] = curl_getinfo($ch);
217 |
218 | $this->last_request['headers'] = $response['headers']['request_header'];
219 |
220 | if ($response['body'] === false) {
221 | $this->last_error = curl_error($ch);
222 | }
223 |
224 | curl_close($ch);
225 |
226 | return $this->formatResponse($response);
227 | }
228 |
229 | /**
230 | * Encode the data and attach it to the request
231 | * @param resource $ch cURL session handle, used by reference
232 | * @param array $data Assoc array of data to attach
233 | */
234 | private function attachRequestPayload(&$ch, $data)
235 | {
236 | $encoded = json_encode($data);
237 | $this->last_request['body'] = $encoded;
238 | curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
239 | }
240 |
241 | /**
242 | * Decode the response and format any error messages for debugging
243 | * @param array $response The response from the curl request
244 | * @return array|false The JSON decoded into an array
245 | */
246 | private function formatResponse($response)
247 | {
248 | $this->last_response = $response;
249 |
250 | if (!empty($response['body'])) {
251 |
252 | $d = json_decode($response['body'], true);
253 |
254 | if (isset($d['status']) && $d['status']!='200' && isset($d['detail'])) {
255 | $this->last_error = sprintf('%d: %s', $d['status'], $d['detail']);
256 | }
257 |
258 | return $d;
259 | }
260 |
261 | return false;
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/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/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/captcha/Captcha.php:
--------------------------------------------------------------------------------
1 | db->connect();
6 | if (empty ($modx->config)) {
7 | $modx->getSettings();
8 | }
9 | if(strstr($_SERVER['HTTP_REFERER'],$modx->getConfig('site_url')) === false || !isset($_REQUEST['formid'])) throw new Exception('Wrong captcha request');
10 | $formid = (string) $_REQUEST['formid'];
11 | include_once ('modxCaptcha.php');
12 | $width = isset($_REQUEST['w']) ? (int) $_REQUEST['w'] : 200;
13 | $height = isset($_REQUEST['h']) ? (int) $_REQUEST['h'] : 160;
14 | $captcha = new ModxCaptcha($modx, $width, $height);
15 | $_SESSION[$formid.'.captcha'] = $captcha->word;
16 | $captcha->outputImage();
17 |
--------------------------------------------------------------------------------
/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/lib/captcha/modxCaptcha/noises/index.html:
--------------------------------------------------------------------------------
1 | Unauthorized access
2 | You're not allowed to access file folder
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pathologic/FormLister/4fc2258f57a9c6286b2abd86da00738407b19f77/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise1.jpg
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pathologic/FormLister/4fc2258f57a9c6286b2abd86da00738407b19f77/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise2.jpg
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pathologic/FormLister/4fc2258f57a9c6286b2abd86da00738407b19f77/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise3.jpg
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pathologic/FormLister/4fc2258f57a9c6286b2abd86da00738407b19f77/assets/snippets/FormLister/lib/captcha/modxCaptcha/noises/noise4.jpg
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/ttf/ftb_____.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Pathologic/FormLister/4fc2258f57a9c6286b2abd86da00738407b19f77/assets/snippets/FormLister/lib/captcha/modxCaptcha/ttf/ftb_____.ttf
--------------------------------------------------------------------------------
/assets/snippets/FormLister/lib/captcha/modxCaptcha/wrapper.php:
--------------------------------------------------------------------------------
1 | cfg = $cfg;
33 | $this->captcha = new \ModxCaptcha($modx, \APIhelpers::getkey($this->cfg, 'width', 100),
34 | \APIhelpers::getkey($this->cfg, 'height', 60));
35 | }
36 |
37 | /**
38 | * Устанавливает значение капчи
39 | * @return mixed
40 | */
41 | public function init()
42 | {
43 | $formid = \APIhelpers::getkey($this->cfg, 'id');
44 | if ($formid) {
45 | $this->lastValue = isset($_SESSION[$formid . '.captcha'])
46 | ? $_SESSION[$formid . '.captcha']
47 | : $this->captcha->word;
48 | $_SESSION[$formid . '.captcha'] = $this->captcha->word;
49 | }
50 | }
51 |
52 | /**
53 | * Плейсхолдер капчи для вывода в шаблон
54 | * Может быть ссылкой на коннектор (чтобы можно было обновлять c помощью js), может быть сразу картинкой в base64
55 | * @return string
56 | */
57 | public function getPlaceholder()
58 | {
59 | $inline = \APIhelpers::getkey($this->cfg, 'inline', 1);
60 | if ($inline) {
61 | $out = $this->captcha->outputImage(true);
62 | } else {
63 | $connectorDir = \APIhelpers::getkey($this->cfg, 'connectorDir',
64 | 'assets/snippets/FormLister/lib/captcha/modxCaptcha/');
65 | $out = MODX_BASE_URL . $connectorDir . 'connector.php?formid=' . \APIhelpers::getkey($this->cfg, 'id',
66 | 'modx');
67 | $out .= '&w=' . \APIhelpers::getkey($this->cfg, 'width', 100);
68 | $out .= '&h=' . \APIhelpers::getkey($this->cfg, 'height', 60);
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 | if (empty($value)) {
83 | $out = \APIhelpers::getkey($captcha->cfg, 'errorEmptyCode', 'Введите проверочный код');
84 | } else {
85 | $out = strtolower($value) == strtolower($captcha->lastValue) ? true : \APIhelpers::getkey($captcha->cfg,
86 | 'errorCodeFailed', 'Неверный проверочный код');
87 | }
88 | $FormLister->log('Validate captcha value '.$value.' against '.$captcha->lastValue);
89 |
90 | return $out;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/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/lib/captcha/smsCaptcha/model.php:
--------------------------------------------------------------------------------
1 | '',
11 | 'phone' => '',
12 | 'code' => '',
13 | 'active' => 0,
14 | 'expires' => 0,
15 | 'ip' => ''
16 | );
17 |
18 | public function getData($phone,$formid) {
19 |
20 | $this->close();
21 | $this->markAllEncode();
22 | $this->newDoc = false;
23 | $result = $this->query("SELECT * from {$this->makeTable($this->table)} where `phone`='{$this->escape($phone)}' AND `formid`='{$this->escape($formid)}'");
24 | $this->fromArray($this->modx->db->getRow($result));
25 | $this->store($this->toArray());
26 | $this->id = $this->eraseField($this->pkName);
27 | if (is_bool($this->id) && $this->id === false) {
28 | $this->id = null;
29 | } else {
30 | $this->decodeFields();
31 | }
32 |
33 |
34 | return $this;
35 | }
36 |
37 | public function createTable()
38 | {
39 | $table = $this->modx->getFullTableName($this->table);
40 | $q = "CREATE TABLE IF NOT EXISTS {$table} (
41 | `id` INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
42 | `formid` VARCHAR(255) NOT NULL DEFAULT '',
43 | `phone` VARCHAR(20) NOT NULL DEFAULT '',
44 | `code` VARCHAR (10) NOT NULL DEFAULT '',
45 | `active` INT(1) NOT NULL DEFAULT 0,
46 | `expires` INT(10) NOT NULL DEFAULT 0,
47 | `ip` VARCHAR (16) NOT NULL DEFAULT '',
48 | KEY `formid` (`formid`),
49 | KEY `phone` (`phone`),
50 | KEY `code` (`code`),
51 | KEY `active` (`active`),
52 | KEY `expires` (`expires`)
53 | ) Engine=MyISAM
54 | ";
55 | $this->modx->db->query($q);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/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/lib/captcha/yandexCaptcha/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 | $id = \APIhelpers::getkey($this->cfg, 'id');
47 | $id = $id ? ('id="' . $id . '-captcha"') : '';
48 | $out = '';
49 | if (!empty($siteKey)) {
50 | $out = "";
51 | }
52 |
53 | return $out;
54 | }
55 |
56 | /**
57 | * @param \FormLister\Core $FormLister
58 | * @param $value
59 | * @param \FormLister\CaptchaInterface $captcha
60 | * @return bool|string
61 | */
62 | public static function validate(Core $FormLister, $value, CaptchaInterface $captcha)
63 | {
64 | $secretKey = \APIhelpers::getkey($captcha->cfg, 'secretKey');
65 | $params = http_build_query([
66 | 'secret' => $secretKey,
67 | 'token' => $value,
68 | 'ip' => \APIhelpers::getUserIP()
69 | ]);
70 | $url = "https://smartcaptcha.yandexcloud.net/validate?{$params}";
71 | $out = false;
72 | if (!empty($value)) {
73 | $curl = curl_init();
74 | curl_setopt($curl, CURLOPT_URL, $url);
75 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
76 | curl_setopt($curl, CURLOPT_TIMEOUT, 10);
77 | curl_setopt($curl, CURLOPT_USERAGENT,
78 | "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16");
79 | $response = curl_exec($curl);
80 | curl_close($curl);
81 | $response = json_decode($response, true) ?? [];
82 | $out = isset($response['status']) && $response['status'] === 'ok';
83 | }
84 | if (!$out) {
85 | $out = \APIhelpers::getkey($captcha->cfg, 'errorCodeFailed', 'Вы не прошли проверку');
86 | }
87 | $FormLister->log('YandexCaptcha validation result: ' . $out);
88 |
89 | return $out;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/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/snippet.FormLister.php:
--------------------------------------------------------------------------------
1 | logEvent(0, 1, "Parameter &formid is not set", 'FormLister');
13 | return;
14 | }
15 | if (!class_exists('\FormLister\Core')) {
16 | include_once('__autoload.php');
17 | }
18 | $out = '';
19 | $FLDir = MODX_BASE_PATH . 'assets/snippets/FormLister/';
20 | if (!isset($controller) || $controller == 'Core') {
21 | $params['controller'] = $controller = "Form";
22 | }
23 |
24 | $classname = strpos($controller, '\\') === 0 ? $controller : '\\FormLister\\'.$controller;
25 |
26 | if (!class_exists($classname)) {
27 | $dir = isset($dir) ? MODX_BASE_PATH . $dir : $FLDir . "core/controller/";
28 | if (file_exists($dir . $controller . ".php") && !class_exists($classname)) {
29 | require_once($dir . $controller . ".php");
30 | }
31 | }
32 |
33 | $DLTemplate = DLTemplate::getInstance($modx);
34 | $templatePath = $DLTemplate->getTemplatePath();
35 | $templateExtension = $DLTemplate->getTemplateExtension();
36 | if (class_exists($classname) && is_a($classname, '\\FormLister\\Core', true)) {
37 | /** @var \FormLister\Core $FormLister */
38 | $FormLister = new $classname($modx, $params);
39 | if (!$FormLister->getFormId()) return;
40 | $FormLister->initForm();
41 | $out = $FormLister->render();
42 | if ($FormLister->getFormStatus() && isset($saveObject) && is_scalar($saveObject)) {
43 | $modx->setPlaceholder($saveObject, $FormLister);
44 | }
45 |
46 | if (!is_null($FormLister->debug)) {
47 | $FormLister->debug->saveLog();
48 | }
49 | } else {
50 | $modx->logEvent(0, 1, "Controller {$classname} is missing", 'FormLister');
51 | }
52 | $DLTemplate->setTemplatePath($templatePath)->setTemplateExtension($templateExtension);
53 |
54 | return $out;
55 |
--------------------------------------------------------------------------------
/install/assets/plugins/userHelper.tpl:
--------------------------------------------------------------------------------
1 | //