Так ведь текущий объект я получаю $modx -> resource = $modx -> getObject('modResource', $id); Это в коде выше есть. Значит как то можно прикрутить и modRequest? Или я ошибаюсь? И как же про выдержку о global $modx;? Может получится малой кровью обойтись?

Топик: Ajax getPage

Здравствуйте. Fatal error:  Call to a member function getParameters() on a non-object in M:\OpenServer\domains\localhost\API\core\cache\includes\elements\modsnippet\1.include.cache.php on line 75 Вам в ошибке четко указано где и почему она лезет. Смотреть надо сам getPage, а не ваш код. github.com/opengeek/getPage/blob/master/core/components/getpage/snippet.getpage.php#L70 У вас нет объекта $modx->request, то есть modRequest. Сделайте лучше чистый документ с пустым шаблоном, и в него уже вставьте вызов своего сниппета, так как getPage-у еще и объект текущего ресурса нужен, без него он тоже будет разваливаться. Вообще этот вопрос скорее всего будет довольно сложным, и скорее всего зря вы на него замахнулись. Здесь довольно много подводных камней. Я вас не научу программировать, а за решением этой задачки возможно вы потратите не один час.

Топик: Ajax getPage

Здравствуйте. Есть обычный обработчик ajax запросов. Там вызывается сниппет getPage и выскакивает ошибка <b>Fatal error</b>: Call to a member function getParameters() on a non-object in <b>M:\OpenServer\domains\localhost\API\core\cache\includes\elements\modsnippet\1.include.cache.php</b> on line <b>75</b> Нарыл в руководстве Боба Рэя ответ Обычно это означает, что объект $modx не доступен в данном месте вашего кода. Если это код внутри функции, вам следует передать данный объект как: global $modx; в начале функции для того, чтобы дать PHP знать, что вы хотите использовать объект $modx извне функции, вместо создания нового. Если это не сработало, иногда нужно передать $modx в функцию в качестве аргумента. Вот мой код, куда это вставить? Пробовал в самом начале — не работает. <?php header('Content-Type: text/html; charset=utf-8');

function getData($action, $id){ // global $modx; $res;

$mtime = microtime();
$mtime = explode(" ", $mtime);
$mtime = $mtime[1] + $mtime[0];
$tstart = $mtime;

/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
if(!defined('MODX_API_MODE')){
	define('MODX_API_MODE', true);
}

$modx_cache_disabled = true;

// подключаем настройки и определим базовый путь для MODX
require_once '../../config.core.php';

if(!defined('MODX_CORE_PATH')) define('MODX_CORE_PATH', $_SERVER['DOCUMENT_ROOT'].'/core/');

// подключаем класс modX
if(!include_once (MODX_CORE_PATH . "model/modx/modx.class.php")){
	$errorMessage = 'Site temporarily unavailable';
	include(MODX_CORE_PATH . 'error/unavailable.include.php');
	header('HTTP/1.1 503 Service Unavailable');
	echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>";
	exit();
}

// вывод данных из буфера
ob_start();

if(empty($options) || !is_array($options)) $options = array();
$modx = new modX('',$options);
if(!is_object($modx) || !($modx instanceof modX)){
	ob_end_flush();
	$errorMessage = '<a href="setup/">MODx not installed. Install now?</a>';
	include(MODX_CORE_PATH . 'error/unavailable.include.php');
	header('HTTP/1.1 503 Service Unavailable');
	echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>";
	exit();
}

$modx -> startTime = $tstart;
$modx -> setLogLevel(modX::LOG_LEVEL_ERROR);
$modx -> setLogTarget('FILE');
$modx -> setDebug(E_ALL & ~E_NOTICE);
$modx -> initialize('web');

$modx -> resource = $modx -> getObject('modResource', $id); //ОЧЕНЬ ВАЖНЫЯ СТРОКА (ПОЛУЧАЕМ ССЫЛКУ НА ТЕКУЩИЙ ОБЪЕКТ ИЗ AJAX ВЫЗОВА)
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */

// Вызов нужного метода
switch($action){
	case 'paging':
		$params['parents'] = $id;
		$params['tpl'] = 'ajaxResources';
		$params['includeTVs'] = 1;
		$params['processTVs'] = 1;
		$params['showHidden'] = 1;
		$params['element'] = 'getResources';
		$params['limit'] = 1;
		$res = $modx -> runSnippet('getPage', $params);
	break;
}

if(!empty($res)) {
  return $res;
}

}

// Откликаться будет ТОЛЬКО на ajax запросы
if($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest'){
	return;
}

// сниппет будет обрабатывать не один вид запросов, поэтому работать будем по запрашиваемому действию
$action = $_GET['action'];

// Если в массиве POST нет действия - выход
if (empty($action)){
	return;
}
else{
	echo getData($action,(int) $_POST['id']);
}

?>

Все, вопрос решенный. Правильный код: Процессор. <?php /* Получаем новинки */

require_once dirname(dirname(FILE)).'/getdata.class.php';

class modWebCatalogProductsModelGetdataProcessor extends modWebCatalogProductsGetdataProcessor{

public function initialize(){
    
    if(!(int)$this->getProperty('model')){
        return 'Не была указана марка';
    }
    
    return parent::initialize();
}

public function prepareCountQuery(xPDOQuery & $query){
    $query = parent::prepareCountQuery($query);  
    
    if($model = (int)$this->getProperty('model')){
        $query->innerJoin('modTemplateVarResource',  
        'model', "model.contentid = {$this->classKey}.id AND 
         model.tmplvarid = 10 AND model.value='{$model}'");
    }
    
    return $query;
}

} return 'modWebCatalogProductsModelGetdataProcessor'; Шаблон: {assign var=params value=[ "model" => $modx->resource->id, "limit" => 9, "getPage" => true, 'cache' => true ]} {processor action="web/catalog/products/model/getdata" ns="modxsite" params=$params assign=result}

<div style="overflow:hidden;"> {if $result.success && count($result.object)} {foreach $result.object as $object} {assign var=image value=$object.image|default:$object.imageDefault} <div class="goodItem left"> <img src='{snippet name="phpthumbon" params="input=`{$image}`&options=`w=238&h=170&zc=1`"}' width="238" height="170"> <h2>{$object.pagetitle}</h2> <p>{$object.introtext}</p> <span class="block">{$object.sm_price|number_format:0:",":" "} грн.</span> <a class="block" href="{$object.uri}">Подробнее</a> </div> {/foreach} {else} <h2 class="notGoods">Категория пуста</h2> {/if} </div> [[+page.nav]] Передавать следовало именно ID. И не забывайте в таких случаях проверку на наличие передаваемого значения и обязательно с конвертацией типа данных, а то будет передано строковое значение (то есть переменная есть), а поиск будет не корректный.
Топик: поиск по tv

Что-то у тебя там жуткое :-) 1. У тебя в TV содержится текстовый заголовок цели? Не лучше ли id документа содержать? Да и скорее всего он и содержится, и надо именно id передавать. (шли доступы в личку, старый пароль не проходит). 2. Два рада $this->getProperty('model') использовать — не комильфо. Лучше так: if($model = $this->getProperty('model')){ $c->innerJoin('modTemplateVarResource', 'model', "model.contentid = {$this->classKey}.id AND model.tmplvarid = 10 AND model.value='{model}'"); }

Топик: поиск по tv

В продолжение темы… Переопределил modWebCatalogProductsGetdataProcessor <?php require_once dirname(dirname(FILE)).'/getdata.class.php'; class modWebCatalogProductsModelGetdataProcessor extends modWebCatalogProductsGetdataProcessor{

public function initialize(){
    
    $this->setDefaultProperties(array(
        'model'   => false,
    ));
    
    return parent::initialize();
}

public function prepareQueryBeforeCount(xPDOQuery $c) {
    $c = parent::prepareQueryBeforeCount($c);
    
    $c->innerJoin('ShopmodxProduct', 'Product');
    
    if($this->getProperty('model')){
        $c->innerJoin('modTemplateVarResource',  'model', 
		"model.contentid = {$this->classKey}.id AND model.tmplvarid = 10 
		AND model.value='$this->getProperty('model')'");
    }
    
    return $c;
}

} return 'modWebCatalogProductsModelGetdataProcessor'; и вывод {assign var=params value=[ "model" => $modx->resource->pagetitle ]} {processor action="web/catalog/products/model/getdata" ns="modxsite" params=$params assign=result}

<div style="overflow:hidden;"> {if $result.success && count($result.object)} {foreach $result.object as $object} {assign var=image value=$object.image|default:$object.imageDefault} <div class="goodItem left"> <img src='{snippet name="phpthumbon" params="input=`{$image}`&options=`w=238&h=170&zc=1`"}' width="238" height="170"> <h2>{$object.pagetitle}</h2> <p>{$object.introtext}</p> <span class="block">{$object.sm_price|number_format:0:" ,":" "} грн.</span> <a class="block" href="{$object.uri}">Подробнее</a> </div> {/foreach} {else} <h2 class="notGoods">Категория пуста</h2> {/if} </div> [[+page.nav]] но не тут то было 333806.tehotdel.web.hosting-test.net/models/audi.html
Топик: поиск по tv

Игорь, это вопрос, касающийся в принципе основ серверного администрирования сайтов. На это полно информации в интернете. Приложите побольше усилий на то, чтобы найти готовую информацию в сети, а не делайте из нас помощников поисковых систем, пожалуйста. У вас по умолчанию подмена на корень сайта. github.com/modxcms/revolution/blob/develop/ht.access#L12 А сайт вы положили не в корень. Вот и догадайтесь, что с этим сделать.

К сожалению, двери и слинги — это не стандартные проекты. В дверях боле менее по уму все сделано, но там и кодинг более сложный был и бОльшая часть необходимого не была включена в сборку. А на слингах в принципе в наследство досталась не правильная структура, в результате чего пришлось хардкодить, что не есть хорошо. Пока что придется все делать по простой модели: один товар — один размер — одна цена. То есть даже если три галстука, которые отличаются только цветом, то надо заводить отдельно три товара-галстука, у каждого свой цвет, своя цена. А цвет, размер и прочее — это заводится в TV-параметрах. В общем, пока эта сборка больше ориентирована на простые магазины. Более сложный функционал будет только позже.

а как правильно RewriteBase делать, плиз выложите строчку примера

В продолжение вот этого вопроса: modxclub.ru/blog/voprosy-spetsyalistov/257.html Сейчас это еще не реализовано в официальной сборке, но покажу на примере слингов. Сразу скажу, что действий не мало надо сделать. И еще: для обеспечения обратной совместимости хоть какой-то, придется дополнительно напрячься с переопределением классов. Единственное что могу сказать положительное, это то, что версия 2.1.0 как раз и вышла с дополнениями, которые писались под этот функционал. Конечно, это не самое лучшее решение, и более правильный функционал появится позже в самой сборке, но если надо срочно, что чтож, значит надо делать. Итак, поехали. Готовим параметры и базу данных 1. Создаем необходимые TV-параметры Надо создать TV-шки этих параметров, меняющихся в товарах. В нашем случае это size и color. При этом надо в этих полях не конечное значение указать, а именно перечислить имеющиеся варианты. К примеру, у вас галстук с размерами L,X,XL и цветами Красный, Синий, Зеленый. В самом товаре надо будет выбрать все возможные значения, которые соответствуют наличию товара. Лучше всего заводить TV-поле типа Мульти-список, в котором в возможных вариантах сразу прописать все возможные варианты. Вот так: ? Или вот так: ? В нашем случае не принципиально, но все-таки числовые ID-шники всегда предпочтительней. В таблице заполненных данных TV-полей у вас будут примерно такие данные: M||XXL||L. То есть по разделителю || можно будет понять, что по этому товару есть размеры M,XXL,L. Получить массив размеров можно будет через explode('||', $value); 2. Редактируем таблицу Заказ-Товар Надо отредактировать вручную таблицу modx_billing_order_products (через phpMyAdmin или типа того): 2.1 Добавить колонки этих параметров (повторюсь, в нашем случае это size и color). Тип данных сами определите, но ни в коем случае эти колонки не должны быть nullable, и нельзя вставлять значения null. 2.2 Надо подправить индексы — удалить уникальный ключ order_id-product_id и создать уникальный ключ со своими параметрами. В нашем случае это order_id-product_id-size-color. 2.3 Подправить map-файл класса OrderProduct. Надо в него добавить описание ваших колонок. Лучше всего для этого использовать CMPGenerator. На всякий случай ревизия: gist.github.com/Fi1osof/f0372195175ade7a72fb/revisions Суть этого действия в том, чтобы получить возможность в одном заказе иметь несколько товаров с одним и тем же id, только с разными параметрами. 3. Правим шаблоны Все, на этом этапе мы уже имеем возможность добавлять товары с различными параметрами. Теперь нам просто надо в форме вывести чекбоксы или выпадающие списки с размерами и цветами, и эти данные отправить на процессор добавления товара в корзину. С шаблоном ничего показывать не буду — это обычная задача на уровне шаблона добавить поля в форму. Эти данные автоматически будут передаваться в запросе. Нам остается только на сервере поймать эти данные и учесть в добавлении товара. И вот тут начинаются трудности побольше… Переопределяем процессоры Для начала немного общей теории по добавлению товаров в корзину. При добавлении товаров в корзину, запрос идет на процессор orders/products/add. Но если товара нет в заказе, то его надо добавить к заказу новой строчкой. А если уже есть, то тогда запись надо обновить. Это уже два разных действия и два совершенно разных процессора: один — create-процессор, создающий новую запись, а второй — update-процессор, обновляющий существующую запись. Как это работает? Есть add-процессор modMgrOrdersProductsAddProcessor. В нем в методе process выполняется поиск товара через метод findExistingObject() github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/billing/processors/mgr/orders/products/add.class.php#L37 и в зависимости от результата выполняется тот или иной конечный процессор. Вот наша задача здесь — это изменить принцип поиска товара в корзине. То есть здесь выполняется поиск по ключу order_id-product_id github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/billing/processors/mgr/orders/products/add.class.php#L94 а нам надо сделать поиск по ключу order_id-product_id-size-color (или order_id-product_id-size, как это конкретно в моем примере). Вот для этого нам надо переопределить add-процессор и перенаправлять запросы на него. 3. Добавляем свой add-процессор. Создаем свой add-процессор в вашей папке процессоров (у меня это site/web/basket/orders/products/add в неймспейсе modxsite), и в нем переопределяем метод поиска записи товара в заказе: gist.github.com/Fi1osof/642525c6ed5de4b38698#file-gistfile1-php-L28 Собственно здесь все. Если запрос на добавление товара будет отправляться на этот процессор, то товар будет искаться с учетом заданных параметров. Только не отправляйте поиск объекта дальше в родительский процессор, а то он получит первый же попавшийся товар с этим id, только без учета дополнительных параметров. 4. Переопределяем action-процессор. Вот теперь надо сделать главное — это перенаправить запросы с клиента на этот новый add-процессор. В целом, это относительно простая задача. У нас есть в баскете общий action-процессор: github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/processors/basket/web/public/action.class.php Вот такой у меня переопределяющий action-процессор: gist.github.com/Fi1osof/86d19bd9e5299756de55#file-gistfile1-php-L15 Запросы на него попадают двумя способами:

  1. Ajax — через коннектор. github.com/Fi1osof/ShopModxBox/blob/master/assets/components/basket/connectors/connector.php#L22
  2. Не Ajax — через плагин. github.com/Fi1osof/ShopModxBox/blob/master/core/components/basket/elements/plugins/basket.plugin.php#L14 То есть надо подправить путь на свой action-процессор в коннекторе (настройка будет добавлена позже), а в плагине в параметрах плагина изменить параметры basket_processor и basket_namespace (именно настройки плагина в админке, а не исходный код плагина). Ну, в общих чертах все. Процессор вывода товаров корзины получит все записи товаров с их данными: github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/core/components/basket/processors/basket/mgr/orders/products/getdata.class.php#L69 Останется только одна небольшая задача: в админке в модуле управления заказами не будет колонки вывода размена и цен, поэтому либо ориентироваться на данные из писем, либо править JS-ы этого модуля. github.com/Fi1osof/ShopModxBox/blob/17791a616ccb43245dfdac5f6defb81a2c90b815/manager/components/shopmodxgroupedit/js/widgets/grid.js Вот моя ревизия на слингах: gist.github.com/Fi1osof/380d7b0587c61738b967/revisions В целом там совсем не много. Вот и все. Более удобный функционал для подобных задачах появится в самых ближайших версиях движка.