0.00
83 читателя, 73 топика

[EVO] Социальный замок на контент

Заплати лайком уже известно что такое на примерах под Рево и еще каких то, но уже не очень хороших цмсках 8-). Суть, в кратце состоит в том, что продать тяжело что- то не очень оцениваемое в денежных знаках, а вот за ссылку почему бы и не поделиться аля «секретом» если юзер нажмет Like или что-то из это же серии социальных кнопок и сылка попадет к юзеру на стену.

социальный замок

До сих пор на модэкс эво такого не было по-моему и переделать тут написано как было.
Поэтому без особых сложностей было сделано:

-параметры настроек сниппета выводящего кнопки и обрабатывающего call-back'и от соц.сетей перенесены из modPropertySet просто в переменные с которыми снип дергался в нужном месте. т.е. из [[SocialLocker? &options=`ИМЯНАБОРАПАРАМЕТРОВ` &tpl=`lockshare` &unlockUrl=`103` &like=`fb,vk,twit,subscribe`]] убрано &options=`ИМЯНАБОРАПАРАМЕТРОВ`

— плейсхолдеры переписаны в стиле эво, например с [[+twitlike]] на [+twitlike+]

-в эво я не нашел как сделать чтоб страница выводила ответ типом json и из за этого сервисная страница в этом случае выдавала текст, что потребовало часть скрипта поменять…

— что то еще по мелочи, как например, в вызове не из темплейта а из чанка, по -моему на срабатывали все входящие параметры, но это уже на каждом сайте отдельно и конкретно в зависимости от настроек того же кеша и места где предполагается дергать снип. Меньше проблем если снип в темплейте по-моему…

Итак в нужном месте для кнопок,
[[SocialLocker? 
&optionsTpl=`response` 
&tpl=`lockshare` 
&unlockUrl=`192` 
&like=`fb,twit,subscribe,vk,plus1` 
&id=`[*id*]` 
&desc=`[*pagetitle*]` 

]]


где [*id*] и [*pagetitle*] это то что попадать на соц сеть будет.
Затем, unlockUrl это айди страницы где отзыв с соц.сетей обрабатывается снипетом с вызовом
[[!SocialLocker? &mode=`response`]]

Далее, SocialLocker, сам снипет:
pastie.org/8434715
в нем 4 параметра хардкодом: $subscribeGroup='5289142';
$ttwitUser='modxdeveloper'; $vkApiid='3922874' их поменяйте на свои айдишки :-)
а вот 4-й, rightSide это чанк в котором будет хранится ваша секретная инфа, которой будет делиться локер если успешно ссылочка запостилась.

Ну и напоследок, сам темплейт локера и темплейты кнопок:
lockshare
pastie.org/8434718

в нем тут 2 жс файлика:
lockershare.js
pastie.org/8434724

и unlock.js
pastie.org/8434725

fb это чанк fblike и остальные по этому же принципу названы: имя кнопки + like
<div class="sl_facebook_like"> 
<div class="fb-like" data-href="[+SharePage+]" data-send="false" data-width="90" data-show-faces="false" data-layout="button_count"></div>
</div>
<script>
function facebook_init() {
        if ('undefined' === typeof(FB)) {
                setTimeout(facebook_init, 500);
        } else {  
                FB.Event.subscribe('edge.create', function(response) { sl_unlock('facebook', 'like'); });
        } 
}
</script>

twit
<div class="sl_twitter_tweet">
        <a href="http://twitter.com/share" class="twitter-share-button" data-url="[+SharePage+]" data-counturl="[+SharePage+]" data-text="[+SharePageDesc+]" data-count="none" data-related="[+ttwit.user+]" data-lang="ru">tweet</a>
</div>
<script>
function twitter_init() {
        if (0 == $j('.sl_twitter_tweet iframe').length) {
                twttr.widgets.load();
                twitter_timeout_id = setTimeout(twitter_init, 4000); 
        } 
}
</script>

subscribe
<div id="sl_vkontakte_subscribe" class="sl_vkontakte_subscribe"></div>

vk
<div id="sl_vkontakte_like" class="sl_vkontakte_like"></div>
<script>
function vkontakte_init() { 
        if ('undefined' == typeof(VK) || 'undefined' === typeof(VK.init)) { 
                setTimeout('vkontakte_init', 500); 
        } else { 
                if (null == VK._apiId) {
                        VK.init({apiId: [+vk.apiid+], onlyWidgets: true}); 
                }                                         
                VK.Widgets.Like("sl_vkontakte_like", {type: 'button', height: 20, pageUrl: '[+SharePage+]', verb: 1});
                VK.Observer.subscribe('widgets.like.liked', function() {  sl_unlock('vkontakte', 'like'); });
                VK.Widgets.Subscribe("sl_vkontakte_subscribe", {mode: 2, soft: 0}, [+subscribe.group+]);
                VK.Observer.subscribe('widgets.subscribed', function() {  sl_unlock('vkontakte', 'subscribe'); });                                               
        } 
}
</script>


plus1
<script type="text/javascript" src="http://apis.google.com/js/plusone.js">
{"lang": "ru"}
</script>
<div class="sl_google_plus1"><g:plusone callback="sl_unlock" size="medium" href="[+SharePage+]"></g:plusone></div>


вот так, может и пригодится. *постараюсь отвечать на вопросы или коменты на баги.

Изменение дерева документов в админке с большим количеством дочерних документов (очередной хак)

В сборке Дмитрия 1.0.12-d6, есть отличная реализация вывода списка дочерних документов не в дереве. Но есть одна заковырка, это нужно зайти в каждый раздел и убрать галочку, а бывает что в разделе есть как и папки так и простые документы.

Подумал и решил немного доработать этот алгоритм, чтобы ничего не нужно было делать.
Так же переделал событие по нажатию на название пункта меню (ранее было редактирование или обзор, что по умолчанию установлено).
Стало:
1. По нажатию на пункт, при условии если это «папка» содержащая папки и документы, меню раскрывается и открывается обзор ресурса
2. Если это «папка» с документами не являющимися папками, то открывается обзор ресурса.
3. Если это «папка» с вложенными папками, только открывается меню.

Всё тестировал на MODx 1.0.12 (заменил файлы на сборке 1.0.12-d6 — полёт нормальный, но не тестировал)

Установка: заменить файлы из архива, очистить кеш браузера.
GitHub

UPD: решена проблема с выбором родительской категории. После обновления добавить в Настройках на вкладке Интерфейс и представление, Режим щелчка мышью на ресурсе — Обзор ресурса

Чуть-чуть подправляем редактирование документа через ManagerManager

Вставляю этот код на всех сайтах в чанк «mm_rules», может кому пригодится:
global $mm_fields, $modx;
$e = &$modx->Event;
	
if ($e->name=='OnDocFormRender') {
	$e->output(includeCSS($modx->config['base_url'] .'assets/js/select2/select2.css'));
	$e->output(includeJs($modx->config['base_url'] .'assets/js/select2/select2.min.js'));
	
	$e->output('
		$j(".tab-page table").attr("width", "100%");
		$j("#content_header").before($j("#tv_body"));
		$j("#tv_body").before($j("#tv_header"));
		$j("span.warning").parent("td").css({"width":"190px"});
		$j("#tv_body span.warning").parent("td").css({"width":"170px"});
		$j("input.inputBox").css({"width":"600px"});
		$j("input[name^=tv]").css({"width":"600px"});
		$j(".tab-page textarea").css({"width":"600px"});
		$j(".tab-page textarea#ta").css({"width":"100%"});
		$j("input[name=menuindex].inputBox").css({"width":"50px", "text-align":"right", "margin-right":"10px"});
		$j("input.imageField").css({"width":"525px"});
		$j("input.DatePicker").css({"width":"150px"});
		$j("textarea[name=introtext]").css({"height":"150px"});

		$j("#content_header.sectionHeader").append("<div id=\"editor_choice\" style=\"float:right;font-weight:normal\"> </div>");
		$j("#editor_choice").append($j("#which_editor").prev("span.warning")).append(" ").append($j("#which_editor"));
		
		{ // этот кусок, если вы использыете плагин content_history
			if ($historycount) {
				$historycount = $historycount.match(/\|\s+(\d+)\s+\]/i);
				if ($historycount) $historycount = $historycount[1]; else $historycount = 0;
			} else $historycount = -1;
			'.mm_createTab("История изменений документа <span id=history-count></span>", "history").'
			$j("#table-history").hide();
			$j("#tab-intro-history").after($j("#section-ch"));
			$j("span.ch_toggle_entries").parent().hide();
			$j("#ch-body").show();
			if ($historycount!=-1) $j("#history-count").html("("+$historycount+")");
			$j(".ch_view_limit").parent().before($j(".ch_record").parent());
		}
	');
	
	// select2 - http://ivaynberg.github.io/select2/
	$e->output('$j(".sectionBody select").select2({minimumResultsForSearch:20,width:"element"});');
	if (is_array($mm_fields) && count($mm_fields)>0) {
		foreach (array_keys($mm_fields) as $field) {
			if ($mm_fields[$field]['fieldtype']=='select' && $mm_fields[$field]['tv']) {
				$e->output('$j("'.$mm_fields[$field]['fieldtype'].'[name=\''.$mm_fields[$field]['fieldname'].'\']").select2({minimumResultsForSearch:5,width:"608px"});'."\n");
			}
		}
	}
}



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

[EVO] BR вместо P в TinyMCE

Возможно это обсуждалось у нас, но я не нашел. Решил поделиться.
Иногда нужно чтобы в TinyMCE при нажатии enter у нас появлялось
<br />
а не
<p>&nbsp;</p>


Да, br можно поставить нажав shift+enter, но в самом начале кода редактора мне это не удалось сделать. Обязательно br заменялось на
<p>&nbsp;</p>


Для этого идем assets/plugins/tinymce/js/
Открываем файл mce_init.js.inc

находим строку 18
force_p_newlines                 : [+force_p_newlines+],

Закомментируем ее (или удаляем)

вместо нее добавляем три новых строки

force_br_newlines: true,
force_p_newlines: false,
forced_root_block: '',

Не забываем почистить кэш браузера!
Был рад кому-нибудь помочь.

ShopKeeper, сохраняем сессию с товарам в базе. Чтобы корзина не отчищалась.

Итак, для чего это нужно?
Много работаю с ШК, и много приходится допиливать всяких мелочей.
Представляю на Ваш суд плагин для сохранения сессии с товарами в БД, чтобы можно было продолжить наполнять корзину на следующий день, или когда захочется.
У меня заказчики оптовики, и там набирают по много позиций. Возможно для кого-то это тоже будет актуально.

Работает только для авторизованных пользователей сайта!

Для начала идем в PhpMyAdmin и создаем новое поле в таблице modx_web_users (у вас префикс может быть другой в базе).
Имя поля sksession, тип LONGTEXT (так как данных у меня например здесь бывает очень много).

Далее нам необходимо создать событие в ШК для плагина. Сам автор ШК рекомендует это делать.

Открываем class.shopkeeper.php и находим примерно строку 277, там должно быть
$_SESSION['addit_params'] = $addit_paramsStr;

и после этого добавляем
$evtOut = $this->modx->invokeEvent('OnSHKaddItem');


Теперь нам необходимо добавить в БД сайт это событие, выполняем следующий запрос в базу
INSERT INTO `modx_system_eventnames` VALUES (NULL, 'OnSHKaddItem', '6', 'Shopkeeper');
(повторюсь, что префикс у вас может быть другой, и надо будет исправить его на ваш.)
Далее создаем плагин SkSaveSession и ставим ему события OnSHKaddItem, OnSHKbeforeSendOrder, OnWebLogin
код плагина
$e = &$modx->Event;
$id = $modx->getLoginUserId();

if (($e->name == 'OnSHKaddItem')) {
$ses = $_SESSION['purchases'];
$addit = $_SESSION['addit_params'];
$res = $ses."|||".$addit;  
$modx->db->query( "UPDATE modx_web_users SET sksession='".$res."'  WHERE id='".$id."'");

}

if (($e->name == 'OnSHKbeforeSendOrder')) {
  $ses = '';
  $modx->db->query( "UPDATE modx_web_users SET sksession='".$ses."' WHERE id='".$id."'");

}

if (($e->name == 'OnWebLogin')) {

$query = $modx->db->query( "SELECT sksession FROM modx_web_users WHERE id='".$id."'");
$data = mysql_fetch_array($query);


if ($data['sksession']!='') 
{
  $res = explode("|||", $data['sksession']);
  $_SESSION['purchases']=$res[0];
  $_SESSION['addit_params']=$res[1];
}

}


Вот как бы и все. При каждом добавлении товара в корзину сессия пишется в базу. При отправке заказа база подчищается. При авторизации пользователя сессия принимает значение поля из базы.

П.С. Сильно не пинать, ибо в кодерстве не силен я :)

UPD 26.08.2013 исправил пару ошибок.

Руссифицированный модуль EasyPoll 0.3.3 для организации простого голосования на сайте

Внимание: Информация в статье устарела, рабочую версию модуля можно установить из репозитория, спасибо говорим vanchelo .

Клиент озаботил меня задачей организации голосования на сайте. После поисков было обнаружено только одно почти рабочее решение — модуль ЕasyРoll.

К сожалению, разработка довольно старая, в css используется привязка к файлам уже не существующей темы оформления Modx, руссификация оставляет желать лучшего. Кроме того вывод сниппета работает на mootools, что вызывает конфликт с jquery-свистелками на сайте и они перестают работать.

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

Скачать руссифицированный EasyPoll

Правки:
а) русский язык выставлен в модуле по умолчанию, перевод существенно откорректирован.
б) добавлена папка с файлами иконок (проект iconza.ru) прямо в директорию модуля, и подкорректирован файл css — теперь отображение иконок в модуле не зависит от выбранной темы MODX.
в) подкорректирован css файл вывода, убрана зависимость от темы MODX.

Для установки модуля и быстрого развертывания опроса см. файл readme.txt в архиве.

Решение конфликта jquery — mootools:
Для вывода опроса используется библиотека mootools, что приводит к конфлику с jquery.
Если вы используете на своем сайте jquery, необходимо в скриптах запуска применить функцию jQuery.noConflict().

Например, при вызове fancybox вместо:

$(function(){
    $("a[rel=group]").fancybox();
});

нужно выводить, например, так:

var $j = jQuery.noConflict();
$j(function($){
    $("a[rel=group]").fancybox();
});


p.s если в выводе сниппета используете параметр &css для указания пути к таблице стилей по умолчанию, следите за регистром в названии директорий и файлов. Некоторые хостинги чуствительны к регистру в названиях файлов и директорий.

[EVO] Подстановка данных пользователя в форму eForm.

Необходимость вставить данные пользователя в форму возникает, например, при оформлении заказа в интернет-магазине на Shopkeeper. Там же можно сниппетом Personalize выводить разные формы для авторизованных и неавторизованных пользователей. Либо сразу использовать шаблон из chunk_shopOrderFormWebUser.tpl, где подстановка происходит используя конструкцию типа
[*phx:input=`&_PHX_INTERNAL_&`:userinfo=`fullname`*]

Если заморачиваться на отказе от использования pHx, то можно попробовать другой вариант подстановки данных.

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

[REVO] Установка фавикона в панели управления сайтом

modx faviconЗачастую у пользователей таких как я, открыто в одном окне браузера очень много вкладок, и мы начинаем путём перебора искать нашу вкладку с панелью управления MODX.
Но к счастью, есть простой способ чтобы добавить различные иконки фавикона в панель управления MODX.
Просто, откройте настройки системы (Revolution 2.1 или выше) Система->Настройки системы. В поле поиска введите "favicon" и нажмите ввод. Система должна найти результат manager_favicon_url.
Читать дальше →

[EVO] Курс валют


<?php
$xmlURL = 'http://www.cbr.ru/scripts/XML_daily.asp?date_req='.date('d/m/Y');
$tpl = isset($tpl) ? $modx->getChunk($tpl) : '€ = [+euro+] Р, $ = [+usd+] Р';

//кэширование 6 часов
$filename = MODX_BASE_PATH.'assets/cache/kurs.xml';
if (!file_exists($filename) || (file_exists($filename) && time() > filemtime($filename) + 60*60*6)) {
	$file = file_get_contents($xmlURL);
	if ($file) {
		file_put_contents($filename, $file);
		@chmod($filename, 0666);
	}
}

$xml = simplexml_load_file($filename); 
if ($xml != false){
	$usd = $xml->xpath('Valute[@ID="R01235"]/Value');
	$usd = round(str_replace(',','.',$usd[0]),1);
	$euro = $xml->xpath('Valute[@ID="R01239"]/Value');
	$euro = round(str_replace(',','.',$euro[0]),1);
	$output = str_replace(array('[+usd+]','[+euro+]'),array($usd,$euro),$tpl);
	return $output;
}
?>