Так ведь текущий объект я получаю $modx -> resource = $modx -> getObject('modResource', $id); Это в коде выше есть. Значит как то можно прикрутить и modRequest? Или я ошибаюсь? И как же про выдержку о global $modx;? Может получится малой кровью обойтись?
Здравствуйте. 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 и выскакивает ошибка <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. И не забывайте в таких случаях проверку на наличие передаваемого значения и обязательно с конвертацией типа данных, а то будет передано строковое значение (то есть переменная есть), а поиск будет не корректный.Что-то у тебя там жуткое :-) 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}'"); }
В продолжение темы… Переопределил 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Игорь, это вопрос, касающийся в принципе основ серверного администрирования сайтов. На это полно информации в интернете. Приложите побольше усилий на то, чтобы найти готовую информацию в сети, а не делайте из нас помощников поисковых систем, пожалуйста. У вас по умолчанию подмена на корень сайта. 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 Запросы на него попадают двумя способами: