0.00
87 читателей, 58 топиков

DBOperations

<?php
/*
DBOperations
Perform database operations
v0.1 Lev Zabudkin (zabudkin@gmail.com)

in examples below site_content table used just and only just for examples, no more.

— Snippet call
— DBOperations? &p=`placeholder prefix` &q=`query` &o=`operation` &tn=`table name` &f=`field list` &w=`where clause` &tpl=`template`

default values: &p=`db`, &o=`select`, &f=`*`, &tpl=``
default return: nothing
default set: placeholders of &t.&f
default set in template &tpl: [+fieldname+]

for use in variables:
%userid% — current userid of loggedin modx user
%prefix% — table prefix of installed modx
%GET.variable% — value of variable from $_GET array
%POST.variable% — value of variable from $_POST array
%REQUEST.variable% — value of variable from $_REQUEST array
%SESSION.variable% — value of variable from $_SESSION array
also available as placeholders (for example: [+GET.variable+]) if you call snippet without arguments, just [[DBOperations]]
— Parameters
— $tn [ string ]
table name
REQUIRED, if not set and if $q not set, then database operations not performed, just sets placeholders of POST,GET,REQUEST,SESSION

$q [ string ]
db query
optional. If set, then &t, &f, &w will be ignored
example: [[DBOperations? &q=`SELECT product_name FROM %prefix%carts WHERE id='[*id*]' AND userid='%userid%']]
result: [+db.product_name+] from table %prefix%carts where id is current document id and userid is id of current loggedin modx user

$tpl [ string ]
template
optional
template for output, placeholders set to fields names of table
example: [[DBOperations? &t=`site_content` &tpl=`@CODE: [+id+]=[+pagetitle+]
`]]
result: 1=Home
2=Blog
… (etc)

$p [ string ]
placeholders prefix
optional, default: db
placeholder prefix
example: [[DBOperations? &p=`product` &t=`products` &f=`name,price`]]
result: [+product.fieldname+]
where fieldname is name of returned field (name or price) from db table products
$o [ string ]
operation, one of: select/insert/update (or short s/i/u)
optional, default: select
example: [[DBOperations &f=`price` &w=`id=[*id*]`]]
result: [+db.price+] from table %prefix%site_content (see default values) where id is current document id

$f [ string ]
field list
optional, default: *
example: [[DBOperations &f=`cacheable`]]
result: [+db.cacheable+] from table %prefix%site_content (see default values)

FOR INSERT/UPDATE specify field list in JSON format, for example:
{«pagetitle»:«newpagetitle»,«content»:«newcontent»,«price»:20}

$w [ string ]
where clause
optional, default: *
example: [[DBOperations &w=`userid='%userid%']]
result: [+db.fieldname+] from table %prefix%site_content (see default values) where userid is id of current loggedin modx user

$e [ int ]
escape or not of GET,POST,REQUEST,SESSION
optional, default: always escape

— Example
— Create new document (http://url?parent=2&content=newcontent&pagetitle=newpagetitle):

[!DBOperations? &o=`i` &t=`%prefix%site_content`
&f=`{«parent»:%REQUEST_parent%,«pagetitle»:"%REQUEST_pagetitle%",«content»:"%REQUEST_content%",«published»:1}` !]
`!]

*/
global $modx;
$userid=$modx->getLoginUserID();
$prefix=$modx->db->config['table_prefix'];
$p = isset($p)? $p: «db»;
$o = isset($o)? $o: «select»;
$e = isset($e)? $e: 1;

function sreplace(&$fr,&$to,&$s) {return preg_replace('/%(.*?)%/', '', str_replace($fr, $to, $s));}

$ss = array("%prefix%", "%userid%");
$sr = array($prefix, $userid);

foreach ($_SESSION as $key => $value) {
$k=«SESSION_$key»; $modx->setPlaceholder($k,$value);
$value= ($e==1)? $modx->db->escape($value): $value;
array_push($ss,"%$k%"); array_push($sr, $value);
}
foreach ($_GET as $key => $value) {
$k=«GET_$key»; $modx->setPlaceholder($k,$value);
$value= ($e==1)? $modx->db->escape($value): $value;
array_push($ss,"%$k%"); array_push($sr, $value);
}
foreach ($_POST as $key => $value) {
$k=«POST_$key»; $modx->setPlaceholder($k,$value);
$value= ($e==1)? $modx->db->escape($value): $value;
array_push($ss,"%$k%"); array_push($sr, $value);
}
foreach ($_REQUEST as $key => $value) {
$k=«REQUEST_$key»; $modx->setPlaceholder($k,$value);
$value= ($e==1)? $modx->db->escape($value): $value;
array_push($ss,"%$k%"); array_push($sr, $value);
}
$tn = isset($tn)? sreplace($ss, $sr, $tn): "";
$f = isset($f)? sreplace($ss, $sr, $f): "*";
$tpl = isset($tpl)? $modx->getTpl(sreplace($ss, $sr, $tpl)): "";

if (isset($q)){
$res = $modx->db->query(sreplace($ss, $sr, $q));
}elseif ($tn!="") {
switch ($o) {
case 'select':
case 's':
if ($res = $modx->db->select($f, $tn, sreplace($ss, $sr, $w))){
if($modx->db->getRecordCount($res)) {
while($row = $modx->db->getRow($res)) {
foreach ($row as $key => $value){
if ($r==0) $modx->setPlaceholder("$p.$key",$value);
$modx->setPlaceholder("$p$r.$key",$value);
}
if ($tpl!="") $out.=$modx->parseText($tpl, $row);
$r++;
}
}
}
return $out;
case 'insert':
case 'i':
$modx->db->insert(json_decode($f,true), $tn);
break;
case 'update':
case 'u':
$modx->db->update(json_decode($f,true), $tn, $w);
break;
}
}
?>

MiltiPhotos и EVO 1.1 +

Не люблю старые решения но когда обновляешь сайты иногда приходиться с ними дружиться.

Тут уже спрашивали как исправить ситуацию с MultiPhotos.

Подсказали тут простой фикс, решил поделиться:)

Необходимо в настройках плагина просто заполнить все поля

не только список id но и роли (1,2,3) и список шаблонов после чего начинает работать :)
prnt.sc/czl0s4

правда еще превью не туда ссылается.

Пределываем paramEdit на multiTV

И так, суть состоит в том, чтобы избавится от phx и paramEdit и переделать все доп параметры товаров на multiTV.

И так начнем.
P.S. Если вы устанавливаете SHK из Extras. То там уже изменен нужный файлик для совместимости с multiTV.
github.com/extras-evolution/Shopkeeper/commit/928d54ac4ef167d7178535afedc866692d15ed4b
если же нет то рекомендую обновить, иначе работать не будет.

Теперь наш json из multiTV будет передаваться в корзину и выводится в плесхолдере
[+addit_data+]
Дальше на multiTV можно делать все что душе пожелается.

Далее на примере селекта переделаем наш paramEdit на multiTV
На странице товара вместо
[*size:shk_widget=`select:size:desc_page:first_selected`*]

Вставляем вызов multiTV с нужными классами, чтобы все работало на стандартном js шопкипера.

[[multiTV?
&tvName=`params`
&docid=`[*id*]`
&outerTpl=`@CODE:<select class="addparam" onchange="jQuery.additOpt(this)" name="params__[*id*]">((wrapper))</select>`
&rowTpl=`price-row`
&display=`all`
]]

Чанк price-row
<option value="[[if? &is=`[+iteration+]-1` &math=`on`]]__[+price+]" [[if? &is=`[+iteration+]-1:=:0` &then=`selected="selected"` &math=`on`]]>[+size+]</option>

теперь все работает из коробки с использованием multiTV, что дает нам гораздо больше гибкости, чем paramEdit


Единственный важный момент в данном способе в конфиге multiTV у Вас должны быть обязательно название полей size и price.

Уведомление о заказах в интернет- магазине на мобильный

Приветствую всех!
На днях дорабатывал свой модуль интернет-магазина TSVshop и думал о том, как лучше всего уведомлять менеджера магазина о новых заказах. Конечно, уведомление на электронный адрес — это обязательно. Но что, если человек не так часто сидит за компом? Лучший вариант — дублировать уведомления на мобильный.

Как сделать это без лишнего кодописания (ударение на букву А :) )? Вот придумал простейший и быстрый способ это сделать без единой строчки кода, без подключения разных смс-агрегаторов, без всяких плагинов-шмагинов.


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

Yandex Map Custom TV

Для хранения в TV координат точки на яндекс-карте.
Скачивать здесь: github.com/Pathologic/YandexMapCustomTV
Требует DocLister c гитхаба (:



Выводится как-то так:

<script src="//api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
var myMap;
var coords = [ [*coords*] ];
if (coords.length) {
    ymaps.ready(init);
}
function init () {
    myMap = new ymaps.Map('map', {
        center: coords,
        zoom: 15
    });
    placemark = new ymaps.Placemark(coords, {
        hintContent: "Точка на карте",
        balloonContentBody: "<b>Бла-бла-бла</b>"
    }, {
        preset: 'islands#darkOrangeIcon'
    });
    myMap.geoObjects.add(placemark);
}
</script>

Крошки для админа

Как-то попался запутанный сайт и стало напрягать, что открыв ресурс для редактирования или нажав «создать дочерний» не видно, кто же собственно «папа» :) Так, по быстрому родился плагин adminNav на событие OnDocFormRender, который отображает путь к нашему ресурсу.


/**
 * adminNav
 *
 * Крошки для админа
 *
 * @author      webber (web-ber12@yandex.ru)
 * @category    plugin
 * @version     0.1
 * @license     http://www.gnu.org/copyleft/gpl.html GNU Public License (GPL)
 * @internal    @events OnDocFormRender
 * @internal    @properties &use_menutitle=Подставлять menutitle;text;0
 * @internal    @installset base, sample
 * @internal    @modx_category Manager and Admin
 */

$e = &$modx->Event;
if ($e->name == 'OnDocFormRender') {
	$id = $e->params['id'];
	$out = '<b>' . $modx->config['site_name'] . '</b>';
	$tmp = array();
	if ($id) {
		//редактируем известный документ
		$tmp = $modx->getParentIds($id);
	} else if (isset($_GET['pid'])) {
		//знаем только родителя и это не корень сайта
		$id = (int)$_GET['pid'];
		$tmp = $modx->getParentIds($id);
		array_unshift($tmp, $id);
	} else {
		//родитель - корень сайта
		$id = 0;
		
	}
	$tmp = array_reverse($tmp);
	$parents = implode(',', $tmp);
	if (!empty($parents)) {
		$orderBy = " FIND_IN_SET(id, '" . $parents . "') ";
		$q = $modx->db->query("SELECT id, " . ($use_menutitle == '1' ? " IF(menutitle='', pagetitle, menutitle) as " : "") . " pagetitle FROM " . $modx->getFullTableName("site_content") . " WHERE id IN (" . $parents . ") ORDER BY " . $orderBy);
		while ($row = $modx->db->getRow($q)) {
			$out .= " → <a href='index.php?a=27&id=" . $row['id'] . "'>" . htmlentities($row['pagetitle'], ENT_QUOTES, $modx->config['modx_charset']) . "</a>"; 
		}
	}
	
$out = '
<script type="text/javascript">
	$j(document).ready(function(){
		var content = "' . $out . '";
		$j("#create_edit h1").append("<div style=\"font-size:11px;\">" + content + "</div>");
	})
</script>
';
$e->output($out);
}


На выходе должно получится примерно так



Примечание:
1. требует установленного managermanager (сейчас он стоит у всех по умолчанию)
2. должен вызываться после вызова managermanager в «порядок вызова плагинов при наступлении события».

Возможно уже есть подобные решения, но я что-то не нашел.

как убрать перенаправление в MODX Revolution 2.2.6-pl (traditional)

у меня на сайте стоит перенаправление, как убрать?!
дело в том что хотел сайт сканировать через айболит или манул и т.п.
но перенаправляет в дом страницу
заранее спс всем

EvoGallery: защита оригинальных картинок

UPD: Сам по себе этот пост устарел, как и сама EvoGallery, но в комментариях обсуждается похожая, более актуальная тема защиты оригиналов для SimpleGallery.




Хочу поделиться способом защиты оригиналов картинок в милой сердцу EvoGallery.

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

Несмотря на то, что появилась прекрасная SimpleGallery, для несложных проектов по-прежнему использую ЭвоГаллери — сила привычки велика. Думаю, и для многих других эта галерея по-прежнему актуальна.

Если картинок на сайте немного, я предпочитаю хранить оригиналы прямо «на месте», то есть в папке с именем original внутри альбома ресурса. Мало ли, клиенту придёт счастливая мысль поменять размеры превьюшек или сменить ватермарк.

Но есть одно но… чего стоят тогда все мои водяные знаки, если любой хитрый посетитель с минимумом знаний может запросто скачать оригиналы из этой папки? Да даже интуитивно может догадаться — название папки original говорит само за себя.

Вот и пришла мысль задать это имя самому. Для этого:

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

Base_url для нескольких доменов одного сайта

Решение для тех, кто устал бороться с несколькими доменами одного сайта и не знает, что с этим делать (возможно, что такие есть))))

1. Создаем сниппет siteUrl следующего содержания

<?php
return MODX_SITE_URL;
?>


2. В хидере сайта заменяем
<base href="[(site_url)]">
на
<base href="[!siteUrl!]">
. В результате избавляемся от «непонятных» перекидываний то на домен с www, то на домен без www, то на тестовый домен (это я еще не говорю про те сайты, которые изначально крутятся одновременно на нескольких доменах.

Все дело в том, что [(site_url)] кэшируется один раз и на разных страницах в зависимости от «точки входа» может быть разным — отсюда и проблемы с переходами туда/сюда (в критических случаях, практически всегда — вплоть до сброса корзины шопкипера на страницах с www и без него). Также очень актуально для ajax, когда мы «неожиданно» получаем «кроссдоменные» запросы, которые не работают :)

Решение конечно элементарнейшее, но после очередного вопроса решил написать о нем на видном месте :)

[REVO] Кейс: Профайлы преподавателей, или getResources слишком долгий

Под моим надзором находится сайт онлайн-школы. И есть на этом сайте страничка с профайлами преподавателей. Фактически она представляет собой опубликованный родительский ресурс с неопубликованными ресурсами для каждого из преподавателей. Вся информация о преподавателе расположена в «телевизорах» (TV).
На сайте профайл представляет собой ссылку в виде Фото+Имя и всплывающее окошко с более подробной информацией и формой записи на обучение. Все профайлы подцеплялись при помощи getResources и выводились списком.
К тому же есть пара переключателей, которые генерировали список Ajax-запросом без перезагрузки страницы – это «Язык» и «Носитель языка/Русскоязычный преподаватель».
Собственно, это была предыстория.

Профайлов не так уж много – 20-25, однако скорость генерации списка с помощью getResources заставляла меня плакать навзрыд – 5-12с. И чем больше, я знакомился с его документацией, тем меньше я верил в его нормальную работоспособность.


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