+1.13
127 читателей, 216 топиков

Защита от спама без каптчи. Плагин.


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

Посему малость дописал решение, используя веб-сервис Akismet. Он платный, но во-первых при больших объемах это не такие и большие деньги, а во-вторых там есть возможность подключить один сайт бесплатно на один аккаунт.

Читать дальше →

Пакет сео-плюшек для ленивых менеджеров



В который раз убеждаюсь, что у программистов мысли рождаются одинаково) Честно, не этот пост послужил отправной точкой для создания нижеследующего пакета) Реально параллельно мысли шли)

Вообщем решил собрать по сусекам все что у меня есть полезного и нужного для СЕО оптимизации и объединить в один пакет.

Что мы умеем?

  • Проставлять alt длля картинок согласно шаблону, с порядковым номеро
  • Проставлять title для ссылок согласно содержанию, а если там пустота — ставить свой текст по шаблону, также с порядковым номером
  • Вытягивать код в одну строку (спасибо Agel_Nash), но оставлять нетронутым тэг pre (лично я не пользовался режением Евгения, именно из-за этого)
  • Убирать внешние ссылки, но оставлять возможность перехода по ним (не забываем в роботе прописать Disallow: /exit.php)
  • Убирать циклиечские ссылки (т.е.ссылки на самих себя) — где-то слышал, что это не зер гуд
  • Формировать ключевики из тэгов h1-h6,b,i,strong и докидывать получившиеся к основным

В принципе и не так много, но весьма полезно.

Минусы решения:
  • Т.к. идет постобработка, то увеличивается время генерации страницы. Хотя я разницы особо и не заметил, ибо там простые, по-сути, математические действия

Плюсы:
  • Установил и оно работает
  • Работает как со старыми, так и с новыми документами, не нужно ничего пересохранять
  • Смотрит не только в поле контента, а по всей странице. Поэтому дополняет «чанки, шаблоны и прочие телевизоры)»
  • Делает MODX реально лучшим движком для СЕО)



Читать дальше →

Удаление старых изображений. Плагинчик.

По мотивам вот этого топика написал плагин, который удаляет старые, неиспользуемые, изображения.
В отличии от предыдущего скрипта, мой использует Ajax, так что количество файлов в папке не на что не влияет.

Читать дальше →

Еще одна реализация вставки нескольких картинок с текстом (custom TV).

Выглядит так.

Ссылка для скачивание — MultiPhotosText
Сделано через custom TV.
Требует установленного плагина TINYMCE.
Используется jQuery и jQuery UI.
Сниппет готового нет, но трудностей с его написанием не должно быть по примеру multiphotos.
Результат сохраняется в json строке:
{«1»:{«img_url»:«путь к картинке», «text»: «сам текст»}}

Можно сортировать картинки, перетаскиваются за серое поле.
Написал для использования в карусели где есть картинки плюс текст с небольшими элементами форматирования.
Есть проблемы, после того как прикрутил возможность сортировки вылезли косяки (надеюсь исправить в следующей версии).
1) При первой попытке перетащить картинку экран дергается, пока не отследил почему.
2) При перетаскивании не видно текста, когда отпускаешь кнопку мышки текст встает на свое место. Это известная проблема с TINYMCE.
3) Не всегда картинки меняются местами, особенно это касается если хочешь поставить картинку первой или последней. В середину перемещаются легко. Если две картинки проще добавить третье поле, поменять местами и удалить пустое поле.
(Пытался исправить ситуацию с помощью параметра distance в jquery ui sortable не помогло)
4) Дизайн, не с первого взгляда понятно что можно сортировать, плюс мелкие кнопки для добавления/удаления картинки.

Манипуляций с самими картинками (изменения размера, обрезание) не происходят. Считаю что картинки для галерей необходимо готовить дизайнеру.

Исправление раскладки msearch2

Это скорее всего, простоq вопрос, но я не могу понять где это включается…
Подскажите, люди добрые:)
На сайте минишоп эта функция работает. Но с одной проблемой: если ввести не «тов», а «njd», то будет искать «тов». Но если ввести вместо «това» — «njdf», то уже не ищет. Почему так?)
Спасибо!

EditDocs - модуль для редактирования полей базы & TV параметров (Evo) update 15.04.2017

Я долго пользовался Fast content csv для разных случаев, но в последних версиях evo он работал через раз и разбираться не очень хотелось, решил запилить свое решение.
Модуль умеет:

1)Редактировать основные поля и TV группы документов разной вложенности.
2)Импортировать из Excel или Calc
3)Обновлять таблицы из Excel или Calc и производить сравнение по выбранному TV.
4)Экспортировать в CSV с выбранным уровнем вложенности.


Редактирование происходит в поле Input, внесение результата идет аяксом на событие onblur().
Модуль не рекамендуется блониданкам и прочему офисному планктону. Хотя в шаблонах tpl вы найдете где можно оставить только нужные поля для редактирования и добавить вывод только нужных TV. По дефолту они все выводятся через плейсхолдер.

Для удобства сделал кнопку для очистки кэша, после внесения изменений это необходимо.
ОБЯЗАТЕЛЬНО наличие DocLister и Modx API.

Скачать можно с гитхаба https://github.com/Grinyaha/editDocs
Установка стандартная, содерджимое архива закидываем в modules. Создаем новый модуль editDocs и вставляем туда
include_once($modx->config['base_path'].'assets/modules/editdocs/editdocs.module.php');


UPD 28.01.2017 — переписал функционал по новому, исправил баги, добавил уровни вложенности. Спасибо огромное Pathologic за помощь!

UPD 01.02.2017
— перевод модуля на ООП.
— добавлена опционально ajax-пагинация

UPD 11.02.2017
— добавил импорт из Excel или Calc
— добавил апдейт из Excel или Calc
— мелкие фиксы

UPD 12.03.2017
— удалил чанк пагинации для редактирования полей базы и ТВ (сама пагинация осталась)

UPD. 15.04.2017
Добавлен экспорт в CSV и сравнение на наличие в базе по выбранному ТВ.
мелкие исправления.

Спасибо Agel_Nash Pathologic a-sharapov
за помощь!
И спасибо какому-то доброжелателю за донат в 200 руб. Это было неожиданно :)

А кому понравился модуль может задонатить мне на чай :)

R948295169787
Z350511691467

MODx Letters (бывший EasyNewsletter)

UPD проверьте папку cache в корне модуля и добавьте ее если она отсутствует!!!
Переписал EasyNewsletter.

Сервисы почтовой рассылки сейчас очень популярны. Однако не все компании прибегают к платным услугам рассылки и подписки на новости. Главные задачи сервиса почтовых рассылок: ведение клиентской базы и рассылка им писем. Очень важным этапом подготовки к внедрению сервиса почтовых рассылок является правильная настройка домена для того, чтобы письма, отправленные на адреса, не попадали в спам. Сюда входит не только правильная настройка mx-записей, но и настройка dkim и spf.
Читать дальше →

Костыль для защиты документа в зависимости от группы пользователя

В версиях до 1.2.1-d9.1.0 почему-то не хотели работать права пользователей. Для решения этой проблемы можно обновиться до последней версии, либо присобачить нижеследующее решение.

Лечение:

В файле manager/includes/secure_web_documents.inc.php комментим строчку 26:
$modx->db->update('privateweb = 1', $modx->getFullTableName("site_content"), "id IN (".implode(", ",$ids).")");


Выполняем запрос к mySql:
Update `modx_site_contnet` set privateweb=0

Обратите внимание, что префикс может быть иным

Далее создаем плагин на OnWebPageInit, вставляем:
$e = $modx->event;

if ($e->name == 'OnWebPageInit') {
	if ($_SESSION['mgrInternalKey']) return;
	$currentID = $modx->documentIdentifier;
	$modx->db->query('Update '.$modx->getFullTableName('site_content').' set privateweb=0 where id='.$currentID); 
	
	$errorPage = $modx->getConfig('unauthorized_page');
	$errorPage = $modx->makeUrl($errorPage);
	$sql = 'Select GROUP_CONCAT(`document_group`) from '.$modx->getFullTableName('document_groups').' where `document`='.$currentID;
	//echo $sql;
	//exit();
	$dg = $modx->db->getValue($sql);
	if (!$dg) return;
	if (!$_SESSION['webInternalKey']) $modx->sendRedirect($errorPage);
	
	$wg = $modx->db->getValue('Select GROUP_CONCAT(`webgroup`) from '.$modx->getFullTableName('webgroup_access').' where `documentgroup` in ('.$dg.')');
	
	$access = $modx->db->getValue('Select count(*) from '.$modx->getFullTableName('web_groups').' where `webgroup` in ('.$wg.') and `webuser`='.$_SESSION['webInternalKey']);
	if (!$access) $modx->sendRedirect($errorPage);
	
}

Должно заработать. Проверял на сайте с 1.2-d8.1.4

DocInfo && published

Столкнулся с необходимостью с помощью сниппета доставать поля из неопубликованных ресурсов, но как оказалось DocInfo не имеет входящего параметра published и по умолчанию достает поля только из опубликованных ресурсов. Так как сниппет построен на основе методов getPageInfo, getTemplateVarOutput, getTemplateVar которые принимают входящим параметром published — немного доработал код сниппета DocInfo чтобы можно было указывать опубликован ли ресурс, пример:
[[DocInfo? &docid=`10` &field=`tvname` &published=`0`]]
код:
<?php
/**
 * DocInfo
 *
 * @category  parser
 * @version   0.4
 * @license     GNU General Public License (GPL), http://www.gnu.org/copyleft/gpl.html
 * @param string $field Значение какого поля необходимо достать
 * @param int $docid ID документа
 * @param int $tv является ли поле TV параметром (0 - нет || 1 - да)
 * @param int $published является ли ресурс опубликованным (0 - нет || 1 - да || all - оба варианта) добавлено GTX59
 * @param int $render Преобразовывать ли значение TV параметра в соответствии с его визуальным компонентом
 * @return string Значение поля документа или его TV параметра
 * @author akool, Agel_Nash <Agel_Nash@xaker.ru>
 *
 * @TODO getTemplateVarOutput не применяет визуальный компонент к TV параметрам у которых значение совпадает со значением по умолчанию
 * 
 * @example
*       [[DocInfo? &docid=`15` &field=`pagetitle`]]
*       [[DocInfo? &docid=`10` &field=`tvname`]]
*       [[DocInfo? &docid=`3` &field=`tvname` &render=`1`]]
*/
if(!defined('MODX_BASE_PATH')){die('What are you doing? Get out of here!');}
$default_field = array('type','contentType','pagetitle','longtitle','description','alias','link_attributes','published','pub_date','unpub_date','parent','isfolder','introtext','content','richtext','template','menuindex','searchable','cacheable','createdon','createdby','editedon','editedby','deleted','deletedon','deletedby','publishedon','publishedby','menutitle','donthit','haskeywords','hasmetatags','privateweb','privatemgr','content_dispo','hidemenu','alias_visible');
$docid = (isset($docid) && (int)$docid>0) ? (int)$docid : $modx->documentIdentifier;
$field = (isset($field)) ? $field : 'pagetitle';
$render = (isset($render)) ? $render : 0;
$published = (isset($published) && in_array($published, array(0,1,'all'))) ? $published : 1;
$output = '';
if (in_array($field, $default_field)) {
    $doc = $modx->getPageInfo($docid, $published, $field);
    $output = $doc[$field];
}else{
    if(isset($render) && 1==$render){
        $tv = $modx->getTemplateVarOutput($field, $docid, $published);
        $output = $tv[$field];
    }else{
        $tv = $modx->getTemplateVar($field,'*',$docid, $published);
        $output = ($tv['value']!='') ? $tv['value'] : $tv['defaultText'];
    }
}
return $output;