Каким образом Сниппет должен понимать &limit?

Здравствуйте!
Пытаюсь сделать многостраничность со своей базой.
На выходе должна быть таблица с данными.
Создал компонент со своей базой, из которой нужно будет получать строки по запросу:
habrahabr.ru/post/126635/

Для начала, хочется понять принцип работы:
1. Как я понимаю, при помощи modx, нужно сделать sql запрос к базе, получить весь результат (?) и затем pdopage сам разделит эту кучу данных на несколько массивов, в количестве = количеству страниц. — сомнительно т.к. если база будет большая, процесс ведь затянется?
2. Или же запрос имеет параметр LIMIT OFFSET? (судя по статьям, так же не отличается скоростью выполнения)

Теперь, самое интересное. Подскажите пожалуйста, какие-нибудь статьи о том, как заставить Сниппет с запросом понимать этот злополучный параметр &limit?
Спрашиваю потому, что я видел разные примеры, ковырял разные исходники, того же самого вывода пользователей в up2, но так и не нашел в скриптах упоминания о limit и page. Может я что-то упустил?

Открыл userprofile2, попытался что-то сделать по аналогии, ничего не получилось. Далеко мне еще до понимания чужого кода. :(
Дмитрий
20 июня 2015, 19:02
modx.pro
2
2 447
0

Комментарии: 24

Максим Кузнецов
21 июня 2015, 07:32
+1
Любой сниппет может принять любые входящие значения вида &params_N=`x`, но то, как они используются (и вообще, будут ли) напрямую зависит от кода приложения. Если вы пишите свой сниппет выборки, то вы можете указать в коде строки вида:
if empty($a) {
	$a = 1;
}
if empty($b) {
	$b = 0;
}
...->limit($a, $b);
— и, соответственно, если в вызове будут присутвовать свойства &a=`5` &b=`10` — они будут перекрывать их.

Что же конкретно до сниппетов pdoTools — у них есть как параметр &limit, так и параметр &offset.

Подводя итоги: если вы хотите при помощи своего сниппета реализовать выборку и вывести все через pdoTools, то вам нужно получить список ресурсов своим сниппетом и внутри него запустить pdoTools с параметром &resources. Как-то вот так:

$limit = число;
		$offset = число
		$query = $modx->newQuery('modResource');
		$query->where(array(список_условий_для_выборки_вашего_сниппета));
		$query->select(array('modResource.id'));
		$query->limit($limit, $offset);

		if ($query->prepare() && $query->stmt->execute()) {
			//тут получаем и формируем циклом массив в строку $resources, перечисляющую id ресурсов выборки
		}

		$pdoOptions = array();
		$pdoOptions['limit'] = значение_лимита_для_пдо;
		$pdoOptions['offcet'] = значение_оффсета_для_пдо; //в теории, эти строки не слишком нужны, т.к. уже можно ограничить до нужного размера результат при получении из бд
		$pdoOptions['resources'] = $resources;

		return $modx->runSnippet('pdoPage', $pdoOptions);
    Сергей Шлоков
    21 июня 2015, 10:19
    +1
    В данном примере пагинации не будет. Чтобы она была, в первой части не нужно запрос ограничивать лимитом. Лимит нужен для pdoPage.
    И еще… Для запроса по таблице с ресурсами (класс modResource) можно напрямую вызвать сниппет pdoPage с параметрами limit и offset, потому как он автоматом вызывает сниппет pdoResources. Если нужны записи из какой-то другой таблицы, то в своем сниппете делаем запрос по нужной таблице, а сам сниппет передаем в pdoPage параметром element. И не надо изобретать никаких велосипедов.
    [[!pdoPage?
    	&element=`Ваш сниппет`
    	&limit = `10`
      Максим Кузнецов
      21 июня 2015, 10:44
      +1
      … вы правда считаете чистый запрос на api — велосипедом?)

      limit для pdoPage = кол-во результатов на страницу.
      limit для сниппета = ограничение кол-во результатов, которые нужно разбить на страницы. (Пример: ТОП-100 популярных ресурсов, выводимых по 10 на страницу.)

      Что же до element — через api, думаю, выйдет быстрее, да и не придется городить массу переменных непосредственно в вызове pdoPage.
        Сергей Шлоков
        21 июня 2015, 11:05
        +1
        … вы правда считаете чистый запрос на api — велосипедом?)
        Интересная интерпретация. Т.е. если придумывать то, что уже придумано, на чистом api, то это уже не велосипед. Прикольно.
        limit для pdoPage = кол-во результатов на страницу.
        limit для сниппета = ограничение кол-во результатов, которые нужно разбить на страницы. (Пример: ТОП-100 популярных ресурсов, выводимых по 10 на страницу.)
        Согласен. Мне показалось, что там один и тот же лимит.
        Что же до element — через api, думаю, выйдет быстрее, да и не придется городить массу переменных непосредственно в вызове pdoPage.
        Какая масса переменных? pdoResources вызывается по умолчанию. Т.е. все только упрощается. Если запрос по своей табличке, то передаешь только сниппет через element.
          Максим Кузнецов
          21 июня 2015, 11:21
          +1
          По поводу массе переменных — имелся ввиду пример, при котором сам сниппет, который передается в элемент — имеет массу своих входных переменных, которые нужно объявить в его вызове.

          Что же до велосипеда… Ну, в целом — да, ваша правда.
          Но в рамках pdoResources (при всех его преимуществах с позиции скорости и удобовводимости данных): на мой взгляд, говорить, что кто-то уже придумал запросы к базе данных и, поэтому, любые собственные запросы к бд — велосипед, это — перебор..)
            Сергей Шлоков
            21 июня 2015, 11:25
            +3
            Ну в такой интерпретации и MODX велосипед. :)
        Дмитрий
        21 июня 2015, 14:51
        0
        Пытался так сделать, и наконец-то что-то начало получаться!
        Моя ошибка в том, что я считал что передавать нужно обычный массив со значениями. Что затем, pdoPage подставит значения в нужный чанк, где это нужно. Ведь это быстрее? Чем загружать уйму лишнего HTML кода? Это мне казалось логичным, т.к. нечто подобное видел в прочих сниппетах, аля регистрация и т.д.

        В действительности же, нужно передавать массив, состоящий из чанков заполненными данными. Какой же у меня был фейспалм… Я снова заблуждаюсь?


        Вопрос. Из-за Ajax передачи значений переменных сниппету, думаю, что желательно запускать pdoPage прямо внутри сниппета. Такое возможно?
          Сергей Шлоков
          21 июня 2015, 15:03
          +1
          Не совсем понимаю о чем речь. Через ajax можно запускать и свой сниппет и pdoPage и сниппет в сниппете. Ограничений нет. Просто я не до конца понимаю контекст вопроса.
            Максим Кузнецов
            21 июня 2015, 15:16
            +1
            docs.modx.pro/components/pdotools/ — на всякий случай.

            По поводу ajaxa — делаю нечто похожее тут, можно запускать где-то внизу страницы сниппет с условием:
            <?php
            	if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest' || empty($_POST['action'])) {
            		return;
            	}
            	
            	if ($_POST['action'] == "название экшна в аяксе") {
            		//ваши вызовы и операции
            	}
            
            	if (!empty($result)) {
            		die(json_encode($result));
            	}
            — и отправлять аякс-запрос на ту же страницу, где вы и находитесь. После чего скриптами вставлять результат в нужное место.
            Подробнее — тут (основы).
        Сергей Шлоков
        21 июня 2015, 11:06
        +1
        1. Как я понимаю, при помощи modx, нужно сделать sql запрос к базе, получить весь результат (?) и затем pdopage сам разделит эту кучу данных на несколько массивов, в количестве = количеству страниц. — сомнительно т.к. если база будет большая, процесс ведь затянется?
        Ничего не затянется. Тут тысячи записей и все работает быстро.
          Дмитрий
          21 июня 2015, 16:23
          0
          Я так много на быдлокодил, что уже путаюсь при попытке встраивания чего-то стороннего. Пожалуй, откажусь от идеи использовать pdoPage. Потом, когда-нибудь, когда это не будет столь критично по срокам для самого себя.

          Когда писал этот топик совсем отчаялся сделать красиво с pdo. И поэтому решил забить на него, и практически разобрался со своим же кодом. Пагинация работает. Осталось продумать алгоритм для вывода страниц like pdoPage.

          Простите, за потраченное время. То, что «почти получилось», на деле отказалось работать, видимо я снова что-то упустил. Уже нет сил плавать в чем-то непонятном. И схватиться не за что. Читал про pdoTools на docs.modx.pro/, но так ине понял как это работает. Видимо читатель должен знать какие-то основы, которые я даже не знаю как гуглить. Надо взять в привычку изучать ВСЮ документацию, вероятно тогда и проблем не будет. ;)

          Но если интересно, то вот мой быдлокод, приятного чтива xD):
          Ссылка на страницу
          Ресурс «Все объявления»:
          [[!result_tables_new_all?
            &context=`[[*context_key]]`
            &action=buy
            &item_type=all
            &status_filter=online
          ]]
          Сниппет «result_tables_new_all», который используется на разных страницах, с немного разными данными:
          <?php
          error_reporting(E_ALL | E_STRICT);
          ini_set('display_errors', 1);
          
          //id пользователя который запускает сниппет
          $user = $modx->getUser();
          $real_id = $user->get('id');
          
          if(!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
          	$context = $modx->context->key;
          	$action = $_POST['action'];
          	$item_type = $_POST['item_type'];
          	$filter_mod_count = $_POST['filter_mod_count'];
          	$status_filter = $_POST['status'];
          	$ajax = 1;
          	if($_POST['from_profile'] == 1){
          		$user_name = $_POST['user_name'];
          		$user_id = $_POST['user_id'];
          		$user_edit = 1;
          		$from_profile = $_POST['from_profile'];
          	}
          }
          //Добавим Unixtime для треба онлайна
          $mysqli = $modx->runSnippet('mysql');
          	switch($action){
          		case 'buy':
          			$TABLE = '`darvo_a_buy`';
          			break;
          			
          		case 'sell':
          			$TABLE = '`darvo_a_sell`';
          			break;
          	}
          	//Проверка статуса Онлайн
          	$status = Array();
          	switch($status_filter){
          		case 'offline':
          			$WHERE = '';
          			$status['color'] = 'red';
          			$status['status'] = 'Offline';
          			break;
          		case 'online':
          			$WHERE = 'WHERE `unixtime`>= unix_timestamp() - 60';
          			$status['color'] = 'greenyellow';
          			$status['status'] = 'Online';
          			break;
          	}
          	
          	$JOIN_UNIXTIME = 'LEFT JOIN `darvo_online_users` ON  '.$TABLE.'.`user_id` = `darvo_online_users`.`id`';
          	$JOIN_USERNAME = 'LEFT JOIN `modx_user_attributes` ON '.$TABLE.'.`user_id` = `modx_user_attributes`.`id`';
          	$JOIN = $JOIN_UNIXTIME.' '.$JOIN_USERNAME;
          	$SELECT = $TABLE.".`id`,".$TABLE.".`user_id`,".$TABLE.".`item_type`,".$TABLE.".`item_id`,".$TABLE.".`item_count`,".$TABLE.".`item_price`,`darvo_online_users`.`unixtime`,`modx_user_attributes`.`fullname`";
          	
          	$page = $_GET['page'];
          	if (!preg_match('/^[0-9]+$/', $page)){
          	   $page = 1;
          	}
          	
          	$limit = 10;
          	if($page>1){
          		$current_page = $page*$limit;
          	}else{
          		$current_page = 1;
          	}
          	$OFFSET = 'LIMIT '.$current_page.','.$limit;
          
          	//если запрос идет из пользовательского профиля
          	if($from_profile == 1){
          		if($item_type=='all'){
          			$result = $mysqli->query("SELECT * FROM ".$TABLE." ".$JOIN." ".$WHERE." AND `user_id` = ".$user_id." ORDER BY `id` DESC");
          		}else{
          			$result = $mysqli->query("SELECT * FROM ".$TABLE." ".$JOIN." ".$WHERE." AND `user_id` = ".$user_id." AND `item_type`='".$item_type."' ORDER BY `id` DESC");
          		}
          	}else{
          		if($item_type=='all'){
          			$result = $mysqli->query("SELECT ".$SELECT." FROM ".$TABLE." ".$JOIN." ".$WHERE." ORDER BY `id` DESC ".$OFFSET);
          			$result_count = $mysqli->query("SELECT COUNT(*) AS 'count' FROM ".$TABLE." ".$JOIN." ".$WHERE);
          		}else{
          			$result = $mysqli->query("SELECT ".$SELECT." FROM ".$TABLE." ".$JOIN." ".$WHERE." AND `item_type`='".$item_type."' ORDER BY `id` DESC ".$OFFSET);
          			$result_count = $mysqli->query("SELECT COUNT(*) AS 'count' FROM ".$TABLE." ".$JOIN." ".$WHERE." AND `item_type`='".$item_type."'");
          		}
          	}
          	
          //Общее количество строк
          	if ($result_count->num_rows > 0) {
          		while($row = $result_count->fetch_assoc()) {
          			$sumrows[] = $row;
          		}
          	}
          	$sum_rows = $sumrows[0]['count'];
          	$sum_pages = ceil($sum_rows/$limit);
          
          	$pages = $modx->GetChunk('pages',Array(
          		'1'=>intval($page-2),
          		'2'=>intval($page-1),
          		'3'=>intval($page),
          		'4'=>intval($page+1),
          		'5'=>intval($page+2),
          	));
          	//return $pages;
          	
          	if ($result->num_rows > 0) {
          		while($row = $result->fetch_assoc()) {
          			$founds[] = $row;
          		}
          	}
          	
          //return mysqli_error($mysqli);
          $SearchResultTableItems = '';
          $number = 1;
          foreach($founds as $found){
          	if($from_profile != 1){
          		$user_name = $found['fullname'];
          		$user_id = $found['user_id'];
          	}
          		
          	$result = $mysqli->query("SELECT `img_".$context."`, `title_".$context."`, `count` FROM `darvo_mods_wiki` WHERE `id`= '".$found['item_id']."'");
          	if ($result->num_rows > 0) {
          		while($row = $result->fetch_assoc()) {
          			$item = $row;
          		}
          	}
          	
          	$item_maxcount = $item['count'];
          	$item_count = $found['item_count'];
          	
          	switch($filter_mod_count){
          		case 'full':
          			if($item_count != $item_maxcount){ goto end_f; }
          			break;
          		case 'null':
          			if($item_count != 0){ goto end_f; }
          			break;
          		default:
          			break;
          	}
          	$item_type = $found['item_type'];
          
          	//объявления с открытой ценой
          		$item_price = $found['item_price'];
          		if($found['item_price']==0){
          			$item_price = 'ваша цена';
          		}
          		
          	//Выведем кнопку удалить, если:
          		if(($from_profile == 1)and($real_id == $user_id)){
          			$btn_chat = $modx->GetChunk('btn_del',Array(
          				'del_id' => $found['id']
          			));
          		}else{
          			$btn_chat = $modx->GetChunk('btn_chat',Array(
          				'item_type' => $item_type,
          				'item_price' => $found['item_price'],
          				'action' => $action,
          			));
          		}
          	
          	$SearchResultTableItems .= $modx->getChunk('result_table_items', Array(
          		'action' => $action,
          		'item_type' => $item_type,
          		'status' => $status['status'],
          		'status_color' => $status['color'],
          		'user_id' => $user_id,
          		'user_name' => $user_name,
          		'item_id' => $found['item_id'],//для линка на страницу информации
          		'item_count' => $item_count,
          		'item_price' => $item_price,
          		'item_img' => $item['img_'.$context],
          		'item_name' => $item['title_'.$context],
          		'item_maxcount' => $item_maxcount,
          		'part_name' => $part_name['img_'.$context],
          		'act_msg' => $act_msg,
          		'btn_chat' => $btn_chat,
          		'btn_del' => $btn_del,
          		'number' => $number,
          		'all' => 1,
          	));
          
          $number++;
          end_f:
          }
          
          return_res:
          $result = $mysqli->query("SELECT `title_".$context."` FROM `darvo_mods_wiki` WHERE `id`= '".$item_id."'");
          if ($result->num_rows > 0) {
          	while($row = $result->fetch_assoc()) {
          		$item = $row;
          	}
          }
          
          $SearchResultTableWrapper = $modx->getChunk('result_table_items_wrap', Array(
          	'action' => $action,
          	'item_name' => $item['title_'.$context],
          	'SearchResultTableItems' => $SearchResultTableItems,
          	'all' => 1,
          	'ajax' => $ajax,
          	'user_name' => $user_name,
          	'user_id' => $user_id,
          	'user_edit' => $user_edit,
          	'from_profile' => $from_profile,
          ));
          
          mysqli_close($mysqli);
          return $SearchResultTableWrapper;
          Чанк «result_table_items» данные таблицы:
          <tr class="[[!+status]]">
          <!--<td>[[$icons-sell]]</td>-->
          <td class="hidden-xs hidden-sm col-sm-1 col-md-1 text-center"><label>[[+number]]</label></td>
          <td class="col-xs-3 col-sm-5 col-md-3 text-left">[[+item_type:is=`mod`:then=`[[+item_count]]/[[+item_maxcount]]`:else=``]] <a href="item/[[+item_id]]/">[[+item_name]]</a></td>
          <td class="col-xs-1 col-sm-1 col-md-1 text-center [[+action:is=`trade`:then=`hidden`:else=``]]">[[+item_price]]</td>
          <td class="col-xs-2 col-sm-2 col-md-2 text-center"><a href="/users/[[+user_id]]/" title="[[-+region]]ru" style="color:[[!+status_color]]">[[+user_name]]</a></td>
          <td class="hidden-sm hidden-xs text-center">[[+btn_chat]]
          </td>
          </tr>
          Чанк «result_table_items_wrap» заголовок таблицы + фильтры:
          [[+ajax:is=`1`:then=``:else=`[[+all:is=`1`:then=`<div class="form-inline">
          <div class="form-group">
          <select id="action" class="searching form-control">
              <option value="buy">Куплю</option>
              <option value="sell">Продам</option>
          </select>
          </div>
          <div class="form-group">
          <select id="item_type" class="searching form-control">
              <option value="all">Все</option>
              <option value="mod">Только Моды</option>
              <option value="pack">Только Паки</option>
              <option value="item">Только Прайм части</option>
          </select>
          </div>
          <div class="form-group">
          <select id="status" class="searching form-control">
              <option value="online">Только Online</option>
              <option value="all">Все объявления</option>
          </select>
          </div>
          </div>
          <div id="search_result" style="position:relative">`:else=``]]`]]
          <table id="myTable1" class="myTable table table-hover table-striped">
          	<thead>
          		<tr>
          			<th class="hidden-xs hidden-sm col-sm-1 col-md-1 text-center"><label>№</label></td>
          			<th class="col-xs-3 col-sm-5 col-md-3 text-left"><label>Предмет</label></th>
          			<th class="col-xs-1 col-sm-1 col-md-1 text-center">
          			<label class="hidden-sm hidden-xs">Стоимость</label><label><img src="img/favicon.ico"></label>
          			</th>
          			<th class="col-xs-1 col-sm-1 col-md-1 text-center [[+item_type_to:is=`mod`:then=``:else=`hidden`]]">
          			<label>Ранг</label>
          			</th>
          			<th class="col-xs-2 col-sm-2 col-md-2 text-center"><label>Игрок</label></th>
          			<th class="col-xs-2 col-sm-1 text-center hidden"><label>Статус</label></th>
          			<th class="hidden-sm hidden-xs col-md-1 text-center"><label>Связь</label></th>
          		</tr>
          	</thead>
          	[[+SearchResultTableItems]]
          	</table>
          [[+ajax:is=`1`:then=``:else=`[[+all:is=`1`:then=`</div>
          <script>
          $(document).ready(function(){
          	$('.searching').change(function(){
          		search_items($('#action').val(),$('#item_type').val(),$('#status').val());
          		//console.log($('#item_type').val()+','+$('#action').val());
          		return false;
          	});
          [[+from_profile:is=`1`:then=`$('.del').click(function(){
          		act = 'del_'+$('#action').val();
          		var $btn = $(this);
          		console.log($btn.closest('tr'));
          			$.ajax({
          				headers: {'X-Requested-With': 'XMLHttpRequest'},
          				method: "POST",
          				url: "[[~307]]",
          				datatype: "json",
          				data: { 'action': act, 'action_id': $btn.attr('alt') },
          				beforeSend: function() {
          					$('#search_result').append('<div id="loading" style="position: absolute;  top: 0px;  left: 0px;  width: 100%;  height: 100%;  background-color: rgba(255,255,255,0.5);"><div style="margin: 0 auto;  background: url(img/misc/ajaxloader.gif?1) no-repeat; background-size: contain; width: 128px;  height: 128px;"></div></div>');
          				}
          			})
          			.done( function( data ) {
          				$('#loading').remove();
          				if(data == 'err'){
          					alert('Что-то пошло не так. Обратитесь к администратору.');
          				}else{
          					$btn.closest("tr").addClass('hide');
          				}
          			})
          			.fail( function( data ) {
          				alert('Что-то пошло не так. Обратитесь к администратору.');
          			});
          		});`:else=``]]
          });
          
          function search_items(action,item_type,status){
          	$.ajax({
          		headers: {'X-Requested-With': 'XMLHttpRequest'},
          		method: "POST",
          		url: '[[~320]]',
          		datatype: "html",
          		data: {action: action, item_type: item_type, status: status, context: '[[*context_key]]', user_name: '[[+user_name]]', from_profile: '[[+from_profile]]', user_id: '[[+user_id]]'},
          		beforeSend: function(){
          			$('#search_result').append('<div id="loading" style="position: absolute;  top: 0px;  left: 0px;  width: 100%;  height: 100%;  background-color: rgba(255,255,255,0.5);"><div style="margin: 0 auto;  background: url(img/misc/ajaxloader.gif?1) no-repeat; background-size: contain; width: 128px;  height: 128px;"></div></div>');
          		}
          	})
          	.done( function(data) {
          		$('#search_result').html(data);
          		
          		var client = new ZeroClipboard($(".btn-copy"), {
          		  moviePath: "//uzerbar.ru/plugins/zclip/ZeroClipboard.swf"
          		});
          
          		client.on("load", function(client1) {  
          		  client.on("complete", function(client, args) {
          			$('.btn-copy').hide(); // скрываем для наглядности кнопку
          		  });
          		});
          [[+from_profile:is=`1`:then=`$('.del').unbind();
          $('.del').click(function(){
          		act = 'del_'+$('#action').val();
          		var $btn = $(this);
          		console.log($btn.closest('tr'));
          			$.ajax({
          				headers: {'X-Requested-With': 'XMLHttpRequest'},
          				method: "POST",
          				url: "[[~307]]",
          				datatype: "json",
          				data: { 'action': act, 'action_id': $btn.attr('alt') },
          				beforeSend: function() {
          					$('#search_result').append('<div id="loading" style="position: absolute;  top: 0px;  left: 0px;  width: 100%;  height: 100%;  background-color: rgba(255,255,255,0.5);"><div style="margin: 0 auto;  background: url(img/misc/ajaxloader.gif?1) no-repeat; background-size: contain; width: 128px;  height: 128px;"></div></div>');
          				}
          			})
          			.done( function( data ) {
          				$('#loading').remove();
          				if(data == 'err'){
          					alert('Что-то пошло не так. Обратитесь к администратору.');
          				}else{
          					$btn.closest("tr").addClass('hide');
          				}
          			})
          			.fail( function( data ) {
          				alert('Что-то пошло не так. Обратитесь к администратору.');
          			});
          		});`:else=``]]
          	})
          	.fail( function() {
          		alert('Что-то пошло не так. Обратитесь к администратору.');
          	});
          }
          </script>`:else=``]]`]]
            Максим Кузнецов
            21 июня 2015, 17:22
            +1
            Если не трудно — объясни простым языком, какой функционал вы хотите реализовать и какой результат обернуть в pdoTools?
              Дмитрий
              22 июня 2015, 08:52
              0
              К сожалению, все делает один человек.
              Что реализовано:
              1. Пользователь выбирает из mysql таблицы предмет любого типа, и выставляет его на покупку либо продажу.
              2. Данные с id пользователя, id-предмета, его характеристиками (они могут быть разные, скажем уровень раскачки предмета) и ценой идут в таблицу buy либо sell.
              3. Допустим 100 пользователей закинуло в эти базы свои заявки, по 20-30 заявок каждый. Итого 2000-3000 заявок.

              Что обернуть в pdoTools:
              4. Показ сразу всех заявок на странице «Все заявки». На данный момент, я ограничил запрос к выборке buy и sell до 30, иначе, загружается слишком много данных на одну страницу. Настолько, что страница махом отжирает 200мб оперативки, и пользоваться сайтом становится проблематично.
              Поэтому нужна многостраничность, т.е. нужен постраничный вывод строк таблицы.

              PS:
              Почти закончил решение без pdoTools, аля костыль, но понимаю что это не дело. Опробовав однажды запрос по модели, почувствовал такооое облегчение.
              Мордынский Николай
              22 июня 2015, 10:24
              +1
              Мануал от перво источника www.markhamstra.com/xpdo/2011/preparing-custom-snippets-for-getpage/ ^^
                Илья Уткин
                22 июня 2015, 11:42
                +1
                Вот эти строчки надо переделать:
                $limit = 10;
                if($page>1){
                	$current_page = $page*$limit;
                }else{
                	$current_page = 1;
                }
                $OFFSET = 'LIMIT '.$current_page.','.$limit;

                как-то так:
                $limit = $scriptProperties['limit'];
                $OFFSET = 'LIMIT '.$scriptProperties['offset'].','.$limit;

                И в самом конце сниппета, перед return добавить строчку:
                $modx->setPlaceholder('page.total', $result_count);
                  Дмитрий
                  22 июня 2015, 16:31
                  0
                  Не знаю, как и в прошлый раз получаю вместо строк Array
                    Илья Уткин
                    22 июня 2015, 16:37
                    +1
                    То есть, без pdoPage выводит как надо, а с pdoPage получается Array?
                      Дмитрий
                      22 июня 2015, 18:11
                      0
                      Без pdoPage выводит собранный чанк целиком.
                      Перед тем, как задействовать pdoPage меняю:
                      $SearchResultTableItems = '';
                      ...
                      $SearchResultTableItems .= $modx->getChunk('ads_items', Array(
                      на
                      $SearchResultTableItems = Array();
                      ...
                      $SearchResultTableItems[] = $modx->getChunk('ads_items', Array(
                      и вывожу не
                      return $SearchResultTableWrapper
                      а
                      return $SearchResultTableItems;
                      Иначе ведь, pdoPage не поймет как нужно разделить цельный html код на страницы?
                        Илья Уткин
                        22 июня 2015, 18:13
                        +1
                        вы глубоко заблуждаетесь))) поймет и еще как))
                          Дмитрий
                          22 июня 2015, 18:29
                          0
                          Да, не заметил, что речь о выборке с оффсетом.
                            Дмитрий
                            22 июня 2015, 18:39
                            0
                            Однако, вы правы. Теперь я примерно понял как работает pdoPage. Он в считает страницы и выводит саму пагинацию с кнопочками, а контент разумеется обрабатывает мой же сниппет. :)
                              Дмитрий
                              22 июня 2015, 19:08
                              0
                              Огромное спасибо! Вот так вроде бы работает:
                              Линк: warframe.trade/testpages.html
                              $limit = $scriptProperties['limit'];
                              if ($page==1) $scriptProperties['offset'] = 0; // иначе не показывает первую страницу
                              $OFFSET = 'LIMIT '.$scriptProperties['offset'].','.$limit;
                              ...
                              if ($result_count->num_rows > 0) {
                              	while($row = $result_count->fetch_assoc()) {
                              		$sumrows[] = $row;
                              	}
                              }
                              $sum_rows = $sumrows[0]['count'];
                              ...
                              $number = $scriptProperties['offset']+1;
                              ...
                              $modx->setPlaceholder('page.total', $sum_rows);
                              return $SearchResultTableWrapper;
                              Наверное откажусь от аякса, это не рентабельно + геморно. По крайней мере сделать Get на этой же странице, кажется гораздо проще.

                                Дмитрий
                                22 июня 2015, 19:15
                                0
                                Например, я делаю аякс запрос на ресурс со сниппетом. Ресурс должен быть без шаблона, иначе вместе с данными загрузится шаблон. (эдакая матрешка, шаблон в шаблоне). Допустим, содержимое ресурса следующее:
                                [[!pdoPage?
                                    &element=`ads_all_pages_pdo`
                                    &context=`[[*context_key]]`
                                    &action=sell
                                    &item_type=all
                                    &status_filter=online
                                    &limit=`10`
                                ]]
                                <div class="pagination">
                                [[!+page.nav]]
                                </div>
                                Значит при выводе данных, странички будут с линком на ресурс который был вызван.
                                т.е. при переходе на другую страницу, я автоматом получу страницу с данными но без шаблона. :D
                                  Илья Уткин
                                  22 июня 2015, 21:08
                                  0
                                  У pdoPage есть параметр, кажется, &ajax=`1` — он включает автоматический алгоритм, который все сделает за вас — не нужно ресурса с пустым шаблоном, правильно формируются ссылки и пр.
                      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                      24