Алексей

Алексей

С нами с 25 декабря 2012; Место в рейтинге пользователей: #69
Илья Уткин
29 февраля 2016, 09:36
1
+2
Если такой адрес нужно убрать из индекса, просто добавь в robots.txt такую строку
Clean-param: an *
Василий Наумкин
14 февраля 2016, 09:23
1
+3
Я просто закрываю все служебные директории паролем через Nginx и нет проблем.

А можно еще и скомбинировать это с пропуском по IP, через директиву satisfy. Кто в разрешённом списке — ходит без авторизации, а у других запрашивается логин-пароль.

Очень удобно, рекомендую.
Klike
21 января 2016, 12:37
1
+1
Мда, а я зациклился на одном из комментариев, что нужно where так вызывать, якобы работает. И всё)
Спасибо, Василий!!!

Рабочий код:
{$_modx->runSnippet('!pdoPage', [
    'parents' => 9,
    'depth' => 0,
    'pageLimit' => 7,
    'limit' => 9,
    'element' => 'getTickets',
    'class' => 'Ticket',
    'loadModels' => 'ms2gallery',
    'tpl' => 'tpl.Blog.card',
    'tplPageWrapper' => '@INLINE <div class="pagination"><ul class="pagination">{$prev}{$pages}{$next}</ul></div>',
    'leftJoin' => '{
            		"360x260" : {
            			"class" : "msResourceFile",
            			"alias" : "360x260",
            			"on" : "360x260.resource_id = Ticket.id AND 360x260.path LIKE \'%/360x260/\' AND 360x260.rank=0"
            		}
            	}',
    'select' => '{ "360x260" : "360x260.url as thumb" }',
    'where' => '{ "autotag:LIKE" :  "%'~$tag~'%"}',
    'groupby' => 'Ticket.id',
    'ajaxMode' => 'default',
    'showLog' => false,
])}
Fi1osof
08 января 2016, 17:47
1
+4
Запретите права на обновление файлов github.com/modxcms/revolution/blob/2.x/core/model/modx/processors/browser/file/rename.class.php#L15
Нефиг обновлять. Тогда ОК будет.

И еще у вас дыра серьезная есть: права new_tv true. Можно создать TV-ху с EVAL-ом и обновиться до судо.
Fi1osof
07 января 2016, 11:57
20
+12
Если ключ не хотите светить, то однозначно запрос надо слать с вашего сервера на донора. В MODX есть готовый CURL-клиент. Вот код для примера:
$client = $modx->getService('rest.modRestCurlClient');
$result = $client->request('https://ya.ru', '/', 'POST', $params = array('foo'  => 'foo'));
print $result;
Можете с этим кодом к консоли поиграться.
Василий Наумкин
06 января 2016, 09:04
4
+2
Я бы написал плагин на событие сохранения комментария:
if ($modx->event->name == 'OnBeforeCommentSave') {
	if (stripos($_POST['text'], 'b-nosov.blogspot') !== false) {
		$modx->event->output('Хватит спамить!');
	}
}
Email очень просто изменить, поэтому лучше проверять текст комментария на спамерскую ссылку.
Максим Кузнецов
15 декабря 2015, 19:22
2
0
По своему опыту реализации такой задачи, опишу главную особенность его интеграции: единожды инициализировав редактор на форме и, впоследствии, при попытке переместить ее, используя, допустим, кнопку «ответить», редактор будет умирать. Тоже самое с ним случается при добавлении им комментария через ajax.
Данная проблема актуальна для данного редактора и решается последовательным уничтожением в dom-e и последующей повторной инициализацией.

Соответственно — необходимо вынести процесс создания/удаления редактора, написать свою логику работы при нажатии на кнопку «ответить» (до уничтожения формы сохранять уже введенные данные и вставлять в свежесозданную форму) и отредактировать tickets/js/web/default.js, вклинив в него нужные процессы.

Для наглядности, приведу пример часть своего кода, которым решал данную задачу.

Функция создания/удаления формы:
var editor, editorText;
	
function createCommentEditor() {
	if (!editor) {
		editor = CKEDITOR.replace('comment-editor', {
			customConfig: 'comments.config.js'
		});
		CKEDITOR.instances['comment-editor'].setData(editorText);
	}
}
function removeCommentEditor() {
	if (editor) {
		editorText = editor.getData();

		editor.destroy();
		editor = null;
	}
}

Первичное создании формы и логика для кнопки «ответить»:
//первичное подключение редактора
	createCommentEditor();

	//при нажатии на кнопку "ответить"
	$('.comment-reply > a.reply').click(function(){
		//replyMe - класс, навешивающийся на кнопку "ответить" при первом нажатии
		
		//если пользователь нажал на уже активную кнопку "ответить" - возвращаем редактор на место
		if($(this).hasClass('replyMe')) {
			removeCommentEditor();
			//#formWillReturn - контейнер, где по умолчанию находится форма (в дефолтном состоянии)
			//#comment-form - айди формы редактора
			$("#comment-form").appendTo("#formWillReturn");
			createCommentEditor();
			//#returnEditor - id кнопки "вернуть редактор на место"
			$("#returnEditor").hide();
		}
		else {
			//здесь переносим редактор под комментарий, на который пользователь хочет ответить
			//кнопка "ответить" находится внутри элемента li с классом ticket-comment и атрибутом data-id=[[+id]]
			var place = $(this).parents('li.ticket-comment').data('id');
			removeCommentEditor();
			
			//у каждого элемента li.ticket-comment есть по умолчанию пустой контейнер для редактора вида <div id="comments-tree-[[+id]]"></div>
			//вставляем в него редактор
			$("#comment-form").appendTo("#comments-tree-"+place);
			
			createCommentEditor();
			
			//показываем кнопку "вернуть редактор на место"
			$("#returnEditor").show();
		}
	});
	
	//при нажатии на кнопку "вернуть редактор"
	$('#returnEditor').click(function(){
		//удаляем все выделенные кнопки "ответить"
		$('.comment-reply a').removeClass('replyMe');
		removeCommentEditor();
		$("#comment-form").appendTo("#formWillReturn");
		createCommentEditor();
		//возвращаем скрытому полю параметр родителя, к которому комментарий будет привязываться в случае успешного добавления
		$('#comment-form input[name="parent"]').val(0);
		
		//прячем кнопку "вернуть редактор"
		$("#returnEditor").hide();
	});

tickets/js/web/default.js
var Tickets = {
	...
	,ticket: {
		...
		,save: function(form, button)  {
			$(form).ajaxSubmit({
				...
				,success: function(response) {
					$(button).removeAttr('disabled');
					if (response.success) {
						//Если комментарий успешно добавлен - реинициализируем форму
						removeCommentEditor();
						Tickets.forms.comment(false);
						$('#comment-preview-placeholder').html('').hide();
						//и очищаем ее
						$('#comment-editor',form).val('');
						
						//после инициализации мы возвращаем форму на место, так что прячем кнопку "вернуть редактор", если она была
						$("#returnEditor").hide();
						$('.ticket-comment-body').removeClass('antwortComment');

						// autoPublish = 0
						if (!response.data.length && response.message) {
							Tickets.Message.info(response.message);
						}
						else {
							Tickets.comment.insert(response.data.comment);
							Tickets.utils.goto($(response.data.comment).attr('id'));
						}
						
						editorText = '';
						

						Tickets.comment.getlist();
						prettyPrint();
						createCommentEditor();
						
						...

Данное решение было выполнено довольно давно (~начало 2014), поэтому не исключаю, что в редакторе/коде тикетсов что-то поменялось, но не уверен, что это в значительной степени изменит логику работы.

Возможно, забыл добавить какой-то кусок кода — в случае чего пишите.

UPD: плюс, насколько я помню, у тикетсов была проблема с подхватыванием введенных пользователем данных в форму ckeditor, но затрудняюсь сказать точнее.
Василий Наумкин
10 декабря 2015, 07:26
8
+5
У меня на сайте, например, бывают платные разделы. Чтобы добавить пользователю доступ в них при оплате, работает вот такой плагин:
case 'OnWebPageInit':
if ($uid = $modx->user->id) {
	if ($extended = $modx->user->Profile->get('extended')) {
		if (!empty($extended['updateGroups'])) {
			unset($_SESSION['modx.user.'.$modx->user->id.'.userGroupNames']);
			$extended['updateGroups'] = 0;
			$modx->user->Profile->set('extended', $extended);
			$modx->user->Profile->save();
			
			$ctxQuery = $modx->newQuery('modContext');
			$ctxQuery->select($modx->getSelectColumns('modContext', '', '', array('key')));
			if ($ctxQuery->prepare() && $ctxQuery->stmt->execute()) {
				if ($contexts = $ctxQuery->stmt->fetchAll(PDO::FETCH_COLUMN)) {
					$serialized = serialize($contexts);
					$modx->exec("UPDATE {$modx->getTableName('modUser')} SET {$modx->escape('session_stale')} = {$modx->quote($serialized)}");
				}
			}
		}
	}
}
break;
Написан давно, работает без нареканий.

Для разлогинивания заблокированных пользователей использую вот такой код в том же плагине:
if ($modx->user->id) {
	if (!$modx->user->active || $modx->user->Profile->blocked) {
		$modx->runProcessor('security/logout');
		$modx->sendRedirect('/');
	}
}

Если это всё не то — прошу прощения.
Максим
07 октября 2015, 13:52
8
+2
Может быть кому-то пригодится простенький сниппет для вызова mFilter2, который дописывает в параметр filters имена назначенных для категории опций — эти опции выводятся в фильтре чекбоксами:
<?php
$catid = $modx->resource->id;
$q = $modx->newQuery('msCategoryOption');
$q->select(array(
    'msCategoryOption.category_id',
    'msCategoryOption.option_id',
    'mso.key'
    ));
$q->where(array(
    'msCategoryOption.category_id' => $catid
    )
    );
$q->leftJoin('msOption','mso','msCategoryOption.option_id = mso.id');
$q->prepare();
$q->stmt->execute();
$options = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
$_options = array();
foreach ($options as $option) {
    $_options[] = 'msoption|'.$option['key'];
}
$_options = implode(',',$_options);
$scriptProperties['filters'] = implode(',',array($scriptProperties['filters'],$_options));
return $modx->runSnippet('mFilter2',$scriptProperties);
Виталий Зиборов
03 октября 2015, 04:53
1
0
Владимир, доброе утро, уточняю ситуацию.
Что хотелось бы получить в идеале:
Есть система сбора заказов на услуги. Потенциальный клиент получает ссылку на анкету и заполняет её, прикрепляя необходимые документы. В принципе, пользователя пока ещё не существует, он формируется только после обработки заявки.
Если без регистрации нельзя, то в принципе, это тоже решаемо, можно цеплять на менеджера, а потом создавать клиентов и перекидывать файлы на них. /тогда попутный вопрос, как лучше сделать переброску?/ Я так понимаю, что основная привязка тут должна быть через имя списка.
Форма заявки сейчас обрабатывается FormIt`ом, но загрузки файлов пока нет, файлы хотелось бы подгрузить через UserFiles.
Попутно встает вопрос передачи списка загруженных файлов в текст письма и самих файлов во вложения (не обязательно, но желательно).
Потом, по ходу обработки заказа, заказчики могут подгружать ещё документы уже на свой оформленный заказ, но уже в других формах и с регистрацией.
Спасибо.