pcheliakov 29 октября 2013 0 8
Здравствуйте. Есть обычный обработчик 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']);
	}
?>
8 комментариев
Fi1osof1
Fi1osof 29 октября 2013г в 22:39 #
Здравствуйте.

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-у еще и объект текущего ресурса нужен, без него он тоже будет разваливаться.

Вообще этот вопрос скорее всего будет довольно сложным, и скорее всего зря вы на него замахнулись. Здесь довольно много подводных камней. Я вас не научу программировать, а за решением этой задачки возможно вы потратите не один час.
p
pcheliakov 29 октября 2013г в 22:49 #
Так ведь текущий объект я получаю
$modx -> resource = $modx -> getObject('modResource', $id);

Это в коде выше есть. Значит как то можно прикрутить и modRequest? Или я ошибаюсь?
И как же про выдержку о global $modx;? Может получится малой кровью обойтись?
Fi1osof1
Fi1osof 29 октября 2013г в 22:57 #
У вас нет объекта $modx->request, то есть modRequest.
modRequest != modResource

modRequest — это совершенно другой объект, обрабатывающий запросы. Я вам дал наводку как это решать, уже для вас большую часть работы сделал. Хотите понимать что это такое и с чем его кушать — индивидуальные уроки по скайпу 1000 рублей/час. Или самостоятельно поизучайте php ООП. Учитывая то, что вы по всей видимости даже области видимости пропустили, то еще раз повторюсь — вы не на ту задачу замахнулись. Мы тут конечно помогаем чем можем, но не тогда, когда разрыв между задачей и знаниями огромный. Или объявляйте заказ на разработку модуля, или оплачивайте уроки, или учитесь самостоятельно. Здесь халявы нет.
А то получается, что научились баранку крутить, и уже хотите в гонках F1 выиграть.
p
pcheliakov 30 октября 2013г в 11:15 #
Вообщем сделал так. Работает, но выводит не отработанные тэги.
[[+first]][[+prev]]1 2 3
    >>
    Last

Так впринципе правильно?
<?php
header('Content-Type: text/html; charset=utf-8');

require_once '../../config.core.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';
require_once MODX_CORE_PATH.'/model/modx/modrequest.class.php'; //нужен для getPage

$modx = new modX();

// Включаем обработку ошибок
$modx -> getService('error','error.modError');
$modx -> setLogLevel(modX::LOG_LEVEL_INFO);
$modx -> setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

$modx -> initialize('web');

$id = $_POST['id'];

$modx -> resource = $modx -> getObject('modResource', $id);
$modx -> request = new modRequest($modx); //передаём объект $modx в класс modRequest
	
	//запуск getPage
	$params['parents'] = $id;
	$params['tpl'] = 'ajaxResources';
	$params['includeTVs'] = 1;
	$params['processTVs'] = 1;
	$params['showHidden'] = 1;
	$params['element'] = 'getResources';
	$params['limit'] = 1;
	$params['total'] = 3;
	$params['pageNavVar'] = 'paging';
	
	$res = $modx -> runSnippet('getPage', $params);
	
	echo "$res<ul class='pager'>{$modx -> getPlaceholder('paging')}</ul>";
Fi1osof1
Fi1osof 30 октября 2013г в 15:29 #
В общих чертах да. Не отрабатывает, потому что вы просто создали modRequest-объект, но не использовали его для обработки ответа (что в вашем случае и не получится).
Надо просто перед отправкой ответ обработать нормально парсером.
github.com/modxcms/revolution/blob/develop/core/model/modx/modresponse.class.php#L83

/* collect any uncached element tags in the content and process them */
$this->modx->getParser();
$maxIterations= intval($this->modx->getOption('parser_max_iterations', $options, 10));
$this->modx->parser->processElementTags('', $this->modx->resource->_output, true, false, '[[', ']]', array(), $maxIterations);
$this->modx->parser->processElementTags('', $this->modx->resource->_output, true, true, '[[', ']]', array(), $maxIterations);

Fi1osof1
Fi1osof 30 октября 2013г в 15:30 #
И еще раз: все-таки правильней в вашем случае делать это через документ с пустым шаблоном. Нагрузки на сервер не на много будет больше, точнее, практически никак не больше.
p
pcheliakov 30 октября 2013г в 19:35 #
switch($action){
		case 'paging':

		$res .= "<ul class=\"work-thumbs\">".$modx -> runSnippet('getPage@paging', $params)."</ul>";
		break;
	}

	$str = $modx -> getPlaceholder('paging');

	//обработка парсером пагинации
	$modx -> getParser();
	$maxIterations = intval($modx -> getOption('parser_max_iterations', NULL, 10));
	$modx -> parser -> processElementTags('', $str , true, false, '', array(), $maxIterations);
	$modx -> parser -> processElementTags('', $str, true, true, '', array(), $maxIterations);

	return "$res<ul class='pager'>{$str}</ul><p>Всего записей: {$modx -> getPlaceholder('pageCount')}</p>";

Спасибо за помощь! Без Вас ничего бы не сделал. Оказалось не так всё сложно. И узнал для себя новое! Это черновик, потом перепишу.
Fi1osof1
Fi1osof 30 октября 2013г в 22:26 #
Не все так сложно, когда есть кому подсказать.
Пожалуйста.
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.