Виртуальные вкладки для страницы пользователя!

Приветствую сообщество!

Вопрос собственно в следующем!
Как бы мне сделать вкладки как на здесь на modx.pro для одного юзера! (заметки, комменты, избранное)
П.С.
Говорить о том, что «надо сначала воспользоваться поиском» не надо, пишу это как раз потому, что воспользовался!

Понимаю есть ааахренеть сколько мануалов и примеров, например здесь:
https://modx.pro/howto/7909-page-users-on-modxpro/
но тем не менее пример у меня не работает, даже не хочет работать элементарно страница пользователя!
Сама страница пользователя у меня тем не менее есть и организована так:

<?php
// обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
if ($modx->event->name != 'OnPageNotFound') {
    return false;
}
// на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
$alias = $modx->context->getOption('request_param_alias', 'q');
// проверяем, что такая переменная есть, иначе и обрабатывать нечего
if (!isset($_REQUEST[$alias])) {
    return false;
}
// наш запрос, который нужно разобрать и обработать
$request = $_REQUEST[$alias];
// разбиваем ссылку на составляющие,
// как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
$chunks = explode('/', $request);
// на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
if (!$users = $modx->getObject('modResource', ['id' => 571])) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
    return false;
}
// а теперь обрабатываем нам запрос. 
switch ($chunks[0]) {
    // сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
    case $users->get('alias'):
        // еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
        if (!$usersSection = $modx->findResource($chunks[0])) {
            return false;
        }
        // у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера 
        $userAlias = str_replace('.html', '', $chunks[1]);
        // еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
        if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
            $modx->sendRedirect($chunks[0] . '/' . $userAlias);
        }
        // пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
        // тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик 
        // 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
        if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
            $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
        }
        // пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
        /** @var modUserProfile $profile */
        $profile = $user->getOne('Profile');
        $extended = $profile->get('extended');
        // прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
        $modx->setPlaceholders($user, 'user.');
        $modx->setPlaceholders($profile, 'user.');
        $modx->setPlaceholders($extended, 'user.');

		// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
        // поэтому в таком случае тоже 404 возвращаем. Но можно удалить
        // profile private, we should return not found error
        // if (isset($extended['private']) && $extended['private'] == 1) {
        //     $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
        // }

        // ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
        $modx->sendForward($usersSection);
        break;
}
Сделана по этому примеру:
https://modx.pro/help/9820/

Прошу помощи! Но так, чтобы не пришлось менять вид чанков и политики вызова данных пользователя на фронт! Заранее спасибо за любою помощь!
Andrey
16 мая 2017, 21:07
modx.pro
1
3 549
0

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

Andrey
18 мая 2017, 02:19
0
все очень плохо :(
    Andrey
    18 мая 2017, 02:20
    0
    Ладно, я понял… В пределах разумного сколько это будет стоить?
      Максим Кузнецов
      18 мая 2017, 03:14
      +2
      Можно сделать вот так:

      После
      $chunks = explode('/', $request);

      Прописываем:
      if (end($chunks) == '') {
      	array_pop($chunks);
      }
      
      //Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
      if (count($chunks) >= 2) {
      	switch ($chunks) {
      			
      		//Cама страница пользователей
      		case 'users':
      			//проверяем существование пользователя
      			if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
      				$user = $modx->getObject('modUser', array('username' => $chunks[1]));
      
      				if ($user && $user->get('active') == 1) {
      					$user_name = $user->get('username');
      						
      					//Приводим юзернейм к правильному регистру
      					if ($chunks[1] != $user_name) {
      						$chunks[1] = $user_name;
      						$modx->sendRedirect(implode('/', $chunks));
      					}
      					
      					//выставляем плейсхолдеры	
      					$user_id = $user->get('id');
      					$modx->setPlaceholder('user_id', $user_id);
      					$modx->setPlaceholder('user_name', $user_name);
      	
      					//Страница профиля
      					if (count($chunks) == 2) {
      							
      					}
      					
      					//Подразделы
      					elseif (count($chunks) == 3) {
      						switch ($chunks[2]) {
      								
      							//Сообщения пользователя
      							case 'posts':
      									
      								break;
      									
      							//Комментарии пользователя
      							case 'comments':
      									
      								break;
      								
      							//Избранное пользователя	
      							case 'favorites':
      									
      								break;
      						}
      					}
      						
      					$modx->sendForward(айди_страницы_users);
      				}
      
      			}
      					
      			break;
      				
      		
      	}
      }
      	
      //иначе редиректим

      — в местах, где определяется «вкладка» дописать необходимые плейсхолдеры по вкусу и готово.

      Если что-то не получится — могу выслать куда-нибудь готовый код плагина.
        Andrey
        18 мая 2017, 19:17
        0
        хм… Спасибо тебе добрый человек! Сегодня буду пробовать!
          Andrey
          26 мая 2017, 20:32
          0
          Еще раз приветствую! Действительно работает! Вроде бы вкладки определяет + я допилил автономности и динамичности, но вот есть небольшая проблема… Как теперь на этих вкладках вызывать то, что мне надо? Если вас не затруднит распишите пожалуйста! :D

          Пробовал вот такую бурду:
          [[*alias:is=`posts`:then=`Контент с Публикациями`]]
          [[*alias:is=`comments`:then=`Контент с  Коментами`]]
          [[*alias:is=`favorites`:then=`Контент с  Избранным`]]
          При этом использовал небольшой динамиский фрагмент шаблона, где по факту должно было происходить переключение контента! Но чет пошло не по плану :(

          Вот полный код плагина:

          <?php
          // обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
          if ($modx->event->name != 'OnPageNotFound') {
              return false;
          }
          // на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
          $alias = $modx->context->getOption('request_param_alias', 'q');
          // проверяем, что такая переменная есть, иначе и обрабатывать нечего
          if (!isset($_REQUEST[$alias])) {
              return false;
          }
          // наш запрос, который нужно разобрать и обработать
          $request = $_REQUEST[$alias];
          // разбиваем ссылку на составляющие,
          // как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
          $chunks = explode('/', $request);
          
          if (end($chunks) == '') {
          	array_pop($chunks);
          }
          
          //Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
          if (count($chunks) >= 2) {
          	switch ($chunks) {
          			
          		//Cама страница пользователей
          		case 'users':
          			//проверяем существование пользователя
          			if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
          				$user = $modx->getObject('modUser', array('username' => $chunks[1]));
          
          				if ($user && $user->get('active') == 1) {
          					$user_name = $user->get('username');
          						
          					//Приводим юзернейм к правильному регистру
          					if ($chunks[1] != $user_name) {
          						$chunks[1] = $user_name;
          						$modx->sendRedirect(implode('/', $chunks));
          					}
          					
          					//выставляем плейсхолдеры	
          					$user_id = $user->get('id');
          					$modx->setPlaceholder('user_id', $user_id);
          					$modx->setPlaceholder('user_name', $user_name);
          	
          					//Страница профиля
          					if (count($chunks) == 2) {
          							
          					}
          					
          					//Подразделы
          					elseif (count($chunks) == 3) {
          						switch ($chunks[2]) {
          								
          							//Сообщения пользователя
          							case 'posts':
          									
          								break;
          									
          							//Комментарии пользователя
          							case 'comments':
          									
          								break;
          								
          							//Избранное пользователя	
          							case 'favorites':
          									
          								break;
          						}
          					}
          						
          					$modx->sendForward(айди_страницы_users);
          				}
          
          			}
          					
          			break;
          				
          		
          	}
          }
          	
          //иначе редиректим
          
          // на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
          if (!$users = $modx->getObject('modResource', ['alias' => users])) {
              $modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
              return false;
          }
          // а теперь обрабатываем нам запрос. 
          switch ($chunks[0]) {
              // сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
              case $users->get('alias'):
                  // еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
                  if (!$usersSection = $modx->findResource($chunks[0])) {
                      return false;
                  }
                  // у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера 
                  $userAlias = str_replace('.html', '', $chunks[1]);
                  // еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
                  if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
                      $modx->sendRedirect($chunks[0] . '/' . $userAlias);
                  }
                  // пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
                  // тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик 
                  // 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
                  if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
                      $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
                  }
                  // пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
                  /** @var modUserProfile $profile */
                  $profile = $user->getOne('Profile');
                  $extended = $profile->get('extended');
                  // прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
                  $modx->setPlaceholders($user, 'user.');
                  $modx->setPlaceholders($profile, 'user.');
                  $modx->setPlaceholders($extended, 'user.');
          
          		// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
                  // поэтому в таком случае тоже 404 возвращаем. Но можно удалить
                  // profile private, we should return not found error
                  // if (isset($extended['private']) && $extended['private'] == 1) {
                  //     $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
                  // }
          
                  // ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
                  $modx->sendForward($usersSection);
                  break;
          }
            Максим Кузнецов
            26 мая 2017, 20:39
            +1
            Оперируйте контентом, выстраивая условия в шаблоне, который определен для ресурса, на который произошла замена.

            Например:
            1. Есть страница /users/ (список всех пользователей), со своим шаблоном, отображающий, допустим, всех пользователей.
            2. В плагине, при совпадении шаблона адресного запроса, идет переадресация на /users/ методом sendForward + выставляются плейсхолдеры (допустим, user_id)
            3. В шаблоне «списка всех пользователей» проверяем наличие этого плейсхолдеры и, исходя из результата, подставляем нужные данные:

            [[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]

            Используя феном, можно так вообще кастомизировать виртуальную страницу без потери результативности, вплоть до сео. Вот, например, как реализована страница пользователя у меня:

            {extends 'template:1'}
            
            {var $user_id = $_modx->getPlaceholder('user_id')}
            
            
            {block 'meta'}
            	{if $user_id}
            		{var $user_name = $_modx->getPlaceholder('user_name')}
            		{var $pagetitle = $user_name ~ ' / Профиль пользователя'}
            		{var $avatar = 1 | user: 'photo'}
            	
            		<title>{$pagetitle ~' :: '~ $_modx->config.site_name}</title>
            		<meta property="og:title" content="{$pagetitle}" /> 
            		<meta name="twitter:title" content="{$pagetitle}" />
            		
            		{set $canonical_url = $_modx->resource.id | url : ['scheme' => 'full'] ~ $user_name ~ '/'}
            		
            		<link rel="canonical" href="{$canonical_url}" />
            		<meta property="og:url" content="{$canonical_url}" /> 
            
            		<meta name="twitter:image" content="{$avatar ?: '/assets/images/users/default/120x120.png'}" />
            		<meta property="og:image" content="{$avatar ?: '/assets/images/users/default/120x120.png'}" />
            		
            		<meta property="og:type" content="profile" />
            	{else}
            		{parent}
            	{/if}
            {/block}
            
            
            
            {block 'main'}
            	{parent}
            
            	{if $user_id}
            		//оформляем страницу пользователя
            	{else}
            		//оформляем общую страницу всех пользователей
            	{/if}
            {/block}
              Andrey
              26 мая 2017, 20:51
              0
              [[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]
              вот так сейчас у меня и реализовано! Но это только одна виртуальная страничка, а вот ваш вариант интересный, но феном пока даже с коментами плохо понимаю, потому как это почти пхп, а я в нем мягко говоря не шарю!

              Вот момента когда происходит вот это:

              {if $user}
              	//оформляем страницу пользователя
              {else}
              	//оформляем общую страницу всех пользователей
              {/if}
              как впихнуть еще три виртуальные страницы Публикации, Коменты, Избранное в эту часть:

              {if $user}
              	//оформляем страницу пользователя
              {else}
              ведь с учетом работы плагина получается, что страница списка пользователей расположена по адресу:
              www.sitename/users
              а страница пользователя по адресу:
              www.sitename/users/[[!+user.id]]
              а вот виртуальные вкладки, например публикации:
              www.sitename/users/[[!+user.id]]/posts
              вот первые два варианта уживаются так как вы и написали, собственно у меня так и было еще давно:
              [[+user_id:is=``:then=`обычная страница "списка всех пользователей"`:else=`формируем страницу профиля`]]
              А вот как теперь сделать так, чтобы прийти к контенту на виртуальной странице:
              www.sitename/users/[[!+user.id]]/posts
                Максим Кузнецов
                26 мая 2017, 20:59
                +1
                Ну, в принципе, можно сделать так (но я рекомендую все же обучиться fenom'y, т.к. с ним создавать сайты становится на порядок интереснее):

                — качаете какое-нибудь дополнение аля switch
                — в плагине, в зависимости от совпадения, передаете плейсхолдер user_page_type
                — создаете чанк с оформлением под каждый «тип» страницы (основная, список пользователей, комментарии, избранное)
                — далее, в шаблоне списка пользователей:

                [[[[!switch? 
                	&get=`[[+user_page_type]]` 
                	&c1=`main`
                	&do1=`$имя_основного_чанка_профиля_пользователя`
                	&c2=`comments`
                	&do2=`$имя_чанка_комментариев_пользователя`
                	
                	&default=`$имя_чанка_общей_страницы_пользователей`
                ]]]]
                (пояснение по поводу структуры чанков)
                  Andrey
                  26 мая 2017, 21:07
                  0
                  Нууу я так то обучаюсь потихоньку. Просто учусь пока на готовых примерах, разбираю их на запчасти, а потом собираю. Поэтому если не сложно не могли бы вы написать, как бы выглядел вызов фенома, чтобы прийти к выводу того, что мне надо! Если конечно это не трудно и это не выглядит как километр кода, чтобы вас не напрягать! Заранее спасибо!
                    Максим Кузнецов
                    26 мая 2017, 21:13
                    +1
                    {var $user_page_type = $_modx->getPlaceholder('user_page_type')}
                    
                    {switch $user_page_type}
                    	{case 'main'}
                    		...
                    	{case 'comments'}
                    		...
                    	{case default}
                    		...
                    {/switch}
                      Andrey
                      26 мая 2017, 21:52
                      0
                      мде, в общем чет нифига не работает по всякому. + виртуальные вкладки мне кажется тоже не работают, а если быть точнее то я не знаю как проверить!

                      Дело в том, что первый раз установив плагин я обрадовался, т.к. по запросу например страницы:
                      mysite.ru/users/2/posts
                      он вроде бы сделал редирект и страница просто обновилась на странице пользователя, я подумал, что и должно быть, что вроде бы как надо теперь кастомизировать алиас для этих страничек! Да вот не тут то было, оказалось, что он так реагирует на все алиасы:
                      http://mysite.ru/users/2/wadwfw
                      http://mysite.ru/users/2/awdafw
                      http://mysite.ru/users/2/sgsgse
                      У меня вот вопрос, а ресурсы надо в админке создавать с этими алиасами? Может в этом дело :D
                        Максим Кузнецов
                        26 мая 2017, 21:57
                        +1
                        Нужен только ресурс /users/, по айди которого плагин будет реализовывать sendForward.
                          Andrey
                          26 мая 2017, 22:00
                          0
                          вот это я лопух…
                          $modx->sendForward(айди_страницы_users);
                          забыл то назначить ID…
                          вот теперь вы понимаете почему я не очень люблю феном и пхп, много закорючек!
                          а вот вопрос, как это можно к динамичности привести? Чтобы он не по айди вычислял страницу а по алиасу?
                          Максим Кузнецов
                          26 мая 2017, 22:05
                          +1
                          $resource = $modx->getObject('modResource', array(   
                          	'alias' => 'ваш алиас'
                          ));   
                          $modx->sendForward($resource->get('id'));

                          Но это лишние запросы к бд, т.е. итоговая скорость обработки будет ниже.
                          Andrey
                          26 мая 2017, 22:33
                          0
                          Вы не поверите! Но чет не фурычит опять никак! Даже по прямой ссылке ничего не выдает!
                          Вот плагин сбахал, тот что выше с вашими модификациями, на страницу чтобы вывести контент уже до банального образа дошел:
                          [[*alias:is=`posts`:then=`Контент с Публикациями`]]
                          пробовал так же и вот этот вариант:
                          {var $user_page_type = $_modx->getPlaceholder('user_page_type')}
                          
                          {switch $user_page_type}
                          	{case 'main'}
                          		000
                          	{case 'posts'}
                          		111
                          	{case default}
                          		000
                          {/switch}
                          при чем когда загружаю странцу пользователя то вот это условие {case default} или {case 'main'} выполняется, т.е.
                          на странице по адресу:
                          http://mysite.ru/users/[[!+user.id]]
                          выдает контент 000
                          А когда я пытаюсь перейти на другой алиас, напимер сюда
                          http://mysite.ru/users/[[!+user.id]]/posts
                          то условие {case 'posts'} не срабатывает и один фиг отображается то, что было на стартовой странице пользователя!
                          У меня вот вопрос, может плагин корявый и где то что то конфликтует? Или же его надо доконструировать, что бы начало работать это условие:
                          {var $user_page_type = $_modx->getPlaceholder('user_page_type')}
                          
                          {switch $user_page_type}
                          	{case 'main'}
                          		000
                          	{case 'posts'}
                          		111
                          	{case default}
                          		000
                          {/switch}
                          Но вот тогда почему не работает это:
                          [[*alias:is=`posts`:then=`Контент с Публикациями`]]
                          чет я запутался вообще!

                          Максим Кузнецов
                          26 мая 2017, 22:36
                          +1
                          [[*alias]] = поле ресурса. У вас оно все время будет полем от страницы «списка пользователей», которой вы подменяете ответ сервера.

                          Если вам нужно получить плейсхолдер, используйте [[+value]]
                          Andrey
                          26 мая 2017, 22:48
                          0
                          та мне без разницы че надо получить, мне просто рабочий готовый вариант нужен, уже пол года ищу решение :D

                          Вот вы говорите [[+value]]! Да действительно, я чет тупанул, т.к. для [[*alias]] значение будет одно, потому как стоит символ "*" но вот как тогда должен выглядеть вызов, чтобы сработало то условие, которое мне нужно, а еще лучше расскажите подробнее как бы мне сделать, чтобы заработало это, вроде бы оно легче и быстрее:
                          {var $user_page_type = $_modx->getPlaceholder('user_page_type')}
                          
                          {switch $user_page_type}
                          	{case 'main'}
                          		000
                          	{case 'posts'}
                          		111
                          	{case default}
                          		000
                          {/switch}
                          Просто скажите может в плагине надо что то докалякать, чтобы это заработало? Потому как просто вставкой в шаблон это не работает, а всегда возвращает значение {case default} или {case 'main'}
                          Максим Кузнецов
                          26 мая 2017, 22:52
                          +1
                          Для работы этого кода, вам нужно:
                          — установить дополнение pdoTools
                          — включить для него системную настройку pdotools_fenom_parser

                          Но, без базовых знаний js у вас могут возникнуть побочные проблемы, в случае, если у вас в шаблонах или чанках где-то присутствуют {}.

                          Да, к слову. Вам будет не лишним принудительно отключить кэширование для страницы списка пользователей:
                          редактирование ресурса -> закладка настройки -> убрать галочку у
                          пункта «Кэшируемый»
                        Максим Кузнецов
                        26 мая 2017, 22:50
                        +1
                        Да вот не тут то было, оказалось, что он так реагирует на все алиасы:
                        mysite.ru/users/2/wadwfw
                        mysite.ru/users/2/awdafw
                        mysite.ru/users/2/sgsgse
                        — упс, а это уже моя недоработка, извиняюсь. В том участке кода, где реализуется $modx->sendForward, вам нужно прописать доп. условие, чтобы подмена страницы срабатывала только в диапазоне подходящих вам кейсов.
                        В противном случае не делать ничего, чтобы в случае неподходящего запроса пользователя перехватывал роутер 404 ошибки.
                          Andrey
                          26 мая 2017, 22:54
                          0
                          :D
                          Блин! А что именно допилить надо?
                          И кстати все что вы выше написали у меня установлено и включено, все же кое что у меня на феноме работает :D
                          Максим Кузнецов
                          26 мая 2017, 22:57
                          +1
                          Ну, можете изменить участок кода на такой:
                          //Страница профиля
                          if (count($chunks) == 2) {
                          	//...
                          	$modx->sendForward(айди_страницы_users);
                          }
                          
                          //Подразделы
                          elseif (count($chunks) == 3) {
                          	switch ($chunks[2]) {
                          			
                          		//Сообщения пользователя
                          		case 'posts':
                          				//...
                          				$modx->sendForward(айди_страницы_users);
                          			break;
                          				
                          		//Комментарии пользователя
                          		case 'comments':
                          				//...
                          				$modx->sendForward(айди_страницы_users);
                          			break;
                          			
                          		//Избранное пользователя	
                          		case 'favorites':
                          				//...
                          				$modx->sendForward(айди_страницы_users);
                          			break;
                          	}
                          }
                          — нужно пояснить, что изменилось?
                          Andrey
                          26 мая 2017, 23:03
                          0
                          Понял! Ща опробуем!
                          Andrey
                          26 мая 2017, 23:16
                          0
                          итак вот собственно сам плагин:

                          <?php
                          // обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
                          if ($modx->event->name != 'OnPageNotFound') {
                              return false;
                          }
                          // на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
                          $alias = $modx->context->getOption('request_param_alias', 'q');
                          // проверяем, что такая переменная есть, иначе и обрабатывать нечего
                          if (!isset($_REQUEST[$alias])) {
                              return false;
                          }
                          // наш запрос, который нужно разобрать и обработать
                          $request = $_REQUEST[$alias];
                          // разбиваем ссылку на составляющие,
                          // как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
                          $chunks = explode('/', $request);
                          
                          if (end($chunks) == '') {
                          	array_pop($chunks);
                          }
                          
                          //Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
                          if (count($chunks) >= 2) {
                          	switch ($chunks) {
                          			
                          		//Cама страница пользователей
                          		case 'users':
                          			//проверяем существование пользователя
                          			if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
                          				$user = $modx->getObject('modUser', array('username' => $chunks[1]));
                          
                          				if ($user && $user->get('active') == 1) {
                          					$user_name = $user->get('username');
                          						
                          					//Приводим юзернейм к правильному регистру
                          					if ($chunks[1] != $user_name) {
                          						$chunks[1] = $user_name;
                          						$modx->sendRedirect(implode('/', $chunks));
                          					}
                          					
                          					//выставляем плейсхолдеры	
                          					$user_id = $user->get('id');
                          					$modx->setPlaceholder('user_id', $user_id);
                          					$modx->setPlaceholder('user_name', $user_name);
                          	
                          					//Страница профиля
                          					if (count($chunks) == 2) {
                          							
                          					}
                          						
                          					$resource = $modx->getObject('modResource', array(   
                                              	'alias' => 'users'
                                              ));   
                                              $modx->sendForward($resource->get('id'));
                          				}
                          
                          			}
                          					
                          			break;
                          				
                          		
                          	}
                          }
                          
                          //Подразделы
                          elseif (count($chunks) == 3) {
                          	switch ($chunks[2]) {
                          			
                          		//Сообщения пользователя
                          		case 'posts':
                          				//...
                          				$resource = $modx->getObject('modResource', array(   
                                              	'alias' => 'users'
                                              ));   
                                          $modx->sendForward($resource->get('id'));
                          			break;
                          				
                          		//Комментарии пользователя
                          		case 'comments':
                          				//...
                          				$resource = $modx->getObject('modResource', array(   
                                              	'alias' => 'users'
                                              ));   
                                          $modx->sendForward($resource->get('id'));
                          			break;
                          			
                          		//Избранное пользователя	
                          		case 'favorites':
                          				//...
                          				$resource = $modx->getObject('modResource', array(   
                                              	'alias' => 'users'
                                              ));   
                                          $modx->sendForward($resource->get('id'));
                          			break;
                          	}
                          }
                          и либо я чет не понял, но теперь на страницы пользователя вообще не заходит, потому как я стер свой плагин вот этот, скоторым хотя бы страница пользователя отображалась:

                          switch ($chunks[0]) {
                            // на всякий случай проверяем, что у нас есть корневой ресурс для пользователей, страница users
                          if (!$users = $modx->getObject('modResource', ['alias' => users])) {
                              $modx->log(modX::LOG_LEVEL_ERROR, 'Entry point resource for users not found.');
                              return false;
                          }
                          // а теперь обрабатываем нам запрос. 
                          switch ($chunks[0]) {
                              // сверяем первую часть ссылки с алиасом нашего ресурса для пользователей, должны совпадать
                              case $users->get('alias'):
                                  // еще одна проверка существования ресурса (наверное можно удалить, взял пример из реального проекта)
                                  if (!$usersSection = $modx->findResource($chunks[0])) {
                                      return false;
                                  }
                                  // у меня ссылки генерились с html, поэтому я вырезаю расширение перед поиском самого юзера 
                                  $userAlias = str_replace('.html', '', $chunks[1]);
                                  // еще одна проверка + убираем концевые слеши и редиректим на нормальную ссылку
                                  if ($chunks[1] != $userAlias || (isset($chunks[2]) && $chunks[2] == '')) {
                                      $modx->sendRedirect($chunks[0] . '/' . $userAlias);
                                  }
                                  // пробуем найти пользователя по username из запроса, если не нашли, то посылаем 404 заголовок
                                  // тут важно вручную послать страницу 404, иначе, если вернем просто ошибку, то у нас опять запустится обработчик 
                                  // 404 ошибки, опять запустится наш плагин, опять тут будет ошибка и привет бесконечный круг и ААААА! Ничего не работает!!!!!
                                  if (!$user = $modx->getObject('modUser', ['id' => $userAlias])) {
                                      $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
                                  }
                                  // пользоввателя нашли, теперь подгружаем его данные (профайл, расширенные поля и тд)
                                  /** @var modUserProfile $profile */
                                  $profile = $user->getOne('Profile');
                                  $extended = $profile->get('extended');
                                  // прописываем все наши данные в плейсхолдеры, чтобы потом на странице их вывести
                                  $modx->setPlaceholders($user, 'user.');
                                  $modx->setPlaceholders($profile, 'user.');
                                  $modx->setPlaceholders($extended, 'user.');
                          
                          		// тут у меня еще момент, что пользователь может указать, что у него профиль приватный и его никому показывать нельзя,
                                  // поэтому в таком случае тоже 404 возвращаем. Но можно удалить
                                  // profile private, we should return not found error
                                  // if (isset($extended['private']) && $extended['private'] == 1) {
                                  //     $modx->sendForward($this->getOption('error_page'), $this->getOption('error_page_header', null, 'HTTP/1.0 404 Not Found'));
                                  // }
                          
                                  // ну и отправляем нашу страницу с шаблоном профиля пользователя, где уже выводим всю его подноготную
                                  $modx->sendForward($usersSection);
                                  break;
                          }
                          Максим Кузнецов
                          26 мая 2017, 23:25
                          +1
                          Да, более того, вы не туда вставили условия.

                          Посмотрите мой исходный пример и сравните со своим — у вас вначале происходит условие:

                          if (count($chunks) >= 2) {
                          	//...
                          }

                          а после вы пытаетесь проверить на это:
                          elseif (count($chunks) == 3) {
                          	//..
                          }

                          — в моем же примере второе условие было ВНУТРИ первого.
                          Andrey
                          26 мая 2017, 23:40
                          0
                          кокейси, вот собственно как я понял он должен выглядеть вот так:
                          <?php
                          // обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
                          if ($modx->event->name != 'OnPageNotFound') {
                              return false;
                          }
                          // на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
                          $alias = $modx->context->getOption('request_param_alias', 'q');
                          // проверяем, что такая переменная есть, иначе и обрабатывать нечего
                          if (!isset($_REQUEST[$alias])) {
                              return false;
                          }
                          // наш запрос, который нужно разобрать и обработать
                          $request = $_REQUEST[$alias];
                          // разбиваем ссылку на составляющие,
                          // как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
                          $chunks = explode('/', $request);
                          
                          if (end($chunks) == '') {
                          	array_pop($chunks);
                          }
                          
                          //Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
                          if (count($chunks) >= 2) {
                          	switch ($chunks) {
                          			
                          		//Cама страница пользователей
                          		case 'users':
                          			//проверяем существование пользователя
                          			if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
                          				$user = $modx->getObject('modUser', array('username' => $chunks[1]));
                          
                          				if ($user && $user->get('active') == 1) {
                          					$user_name = $user->get('username');
                          						
                          					//Приводим юзернейм к правильному регистру
                          					if ($chunks[1] != $user_name) {
                          						$chunks[1] = $user_name;
                          						$modx->sendRedirect(implode('/', $chunks));
                          					}
                          					
                          					//выставляем плейсхолдеры	
                          					$user_id = $user->get('id');
                          					$modx->setPlaceholder('user_id', $user_id);
                          					$modx->setPlaceholder('user_name', $user_name);
                          	
                          					//Страница профиля
                          					if (count($chunks) == 2) {
                          							
                          					}
                          					
                          					//Подразделы
                                              elseif (count($chunks) == 3) {
                                              	switch ($chunks[2]) {
                                              			
                                              		//Сообщения пользователя
                                              		case 'posts':
                                              				//...
                                              				$resource = $modx->getObject('modResource', array(   
                                                              	'alias' => 'users'
                                                              ));   
                                                              $modx->sendForward($resource->get('id'));
                                              			break;
                                              				
                                              		//Комментарии пользователя
                                              		case 'comments':
                                              				//...
                                              				$resource = $modx->getObject('modResource', array(   
                                                              	'alias' => 'users'
                                                              ));   
                                                              $modx->sendForward($resource->get('id'));
                                              			break;
                                              			
                                              		//Избранное пользователя	
                                              		case 'favorites':
                                              				//...
                                              				$resource = $modx->getObject('modResource', array(   
                                                              	'alias' => 'users'
                                                              ));   
                                                              $modx->sendForward($resource->get('id'));
                                              			break;
                                              	}
                                              }
                          						
                          					$resource = $modx->getObject('modResource', array(   
                                              	'alias' => 'users'
                                                  ));   
                                              $modx->sendForward($resource->get('id'));
                          				}
                          
                          			}
                          					
                          			break;
                          				
                          		
                          	}
                          }
                          но один фиг, это ломает мой вызов и перестает работать страница пользователя, т.е. выдает 404 и по ID и по Username
                          конечно может я что то не так делаю в плане адресной строки:

                          вызывают так (мой username — K.STARK)
                          http://cwonline.ru/users/K.STARK
                          http://cwonline.ru/users/k.stark
                          http://cwonline.ru/users/kstark
                          не робит по всякому! Я уже запутался и вас запутал, и забадал! Вот думаю, может вы вышлите мне готовый вариант как у вас сделано и я попробую у себя интегрировать? Просто тот плагин что был до этого у меня для тсраницы пользователя был достаточно просто для понимания, ваще без заморочек. Поставил, плейсхолдеры с префикосм нафигачил и дело с концом! А тут… чет туплю сильно… но очень хочу разобраться!

                          Хоть плюсиками вас поддержу! :D
                          Andrey
                          27 мая 2017, 02:09
                          0
                          нашел ошибку у себя в том плагине, который вы предложили, но тем не менее чет ничего не работает :(

                          Выглядит он как вы описали:
                          <?php
                          // обрабатываем только события OnPageNotFound, на случай, если отметили галкой и другие в настройках плагина
                          if ($modx->event->name != 'OnPageNotFound') {
                              return false;
                          }
                          // на случай, если у нас настройки кто-то менял, получаем значение переменной, через которую передаются ссылки в modx от веб-сервера
                          $alias = $modx->context->getOption('request_param_alias', 'q');
                          // проверяем, что такая переменная есть, иначе и обрабатывать нечего
                          if (!isset($_REQUEST[$alias])) {
                              return false;
                          }
                          // наш запрос, который нужно разобрать и обработать
                          $request = $_REQUEST[$alias];
                          // разбиваем ссылку на составляющие,
                          // как правило, будет что-то вроде users/username, на выходе будет массив с этими значениями
                          $chunks = explode('/', $request);
                          
                          if (end($chunks) == '') {
                          	array_pop($chunks);
                          }
                          
                          //Проверяем, что есть минимум 2 части ссылки (/users/ и /username/)
                          if (count($chunks) == 2) {
                          	switch ($chunks) {
                          			
                          		//Cама страница пользователей
                          		case 'users':
                          			//проверяем существование пользователя
                          			if (!empty($chunks[1]) && $modx->getCount('modUser', array('username' => $chunks[1]))) {
                          				$user = $modx->getObject('modUser', array('username' => $chunks[1]));
                          
                          				if ($user && $user->get('active') == 1) {
                          					$user_name = $user->get('username');
                          						
                          					//Приводим юзернейм к правильному регистру
                          					if ($chunks[1] != $user_name) {
                          						$chunks[1] = $user_name;
                          						$modx->sendRedirect(implode('/', $chunks));
                          					}
                          					
                          					//выставляем плейсхолдеры	
                          					$user_id = $user->get('id');
                          					$modx->setPlaceholder('user_id', $user_id);
                          					$modx->setPlaceholder('user_name', $user_name);
                          	
                          					//Страница профиля
                                              if (count($chunks) == 2) {
                                              	//...
                                              	$modx->sendForward(1226);
                                              }
                          					
                          					//Подразделы
                                              elseif (count($chunks) == 3) {
                                              	switch ($chunks[2]) {
                                              			
                                              		//Сообщения пользователя
                                              		case 'posts':
                                              				//...
                                              				$modx->sendForward(1226);
                                              			break;
                                              				
                                              		//Комментарии пользователя
                                              		case 'comments':
                                              				//...
                                              				$modx->sendForward(1226);
                                              			break;
                                              			
                                              		//Избранное пользователя	
                                              		case 'favorites':
                                              				//...
                                              				$modx->sendForward(1226);
                                              			break;
                                              	}
                                              }
                          						
                          					$modx->sendForward(1226);
                          				}
                          
                          			}
                          					
                          			break;
                          				
                          		
                          	}
                          }
                          	
                          //иначе редиректим
                          При чем не работает даже страница пользователя
      Andrei D.
      27 мая 2017, 12:43
      0
      Для профилей в виде www.website.com/sampleusername/posts:
      На каждую страницу пользователя создается отдельный ресурс, в котором ловятся плейсхолдеры
      <?php
      if ($modx->event->name != 'OnPageNotFound') {return false;}
      $alias = $modx->context->getOption('request_param_alias');
      if (!isset($_REQUEST[$alias])) {return false;}
      
      $request = $_REQUEST[$alias];
      $tmp = explode('/', $request);
      
      if (count($tmp) >= 1) {
      	$section = 1;//id главной страницы профиля
      	$name = str_replace('.html', '', $tmp[0]);
      	if ($tmp[0] != $name || (isset($tmp[1]) && $tmp[1] == '')) {
      		$modx->sendRedirect('/' . $name);
      	}
      	
      	switch($tmp[1]) {
      		case 'posts':
      			$section = 2;//id страницы постов
      			break;
      		//
      		case 'comments':
      			$section = 3;//id страницы комментариев
      			break;
      		//
      		case 'favourites':
      			$section = 4;//id страницы избранного
      			break;
      		//
      		default:
      		    $section = 1;
      			break;
      	}
      	
      	if ($user = $modx->getObject('modUser', array('username' => $name))) {
      		$id = $user->get('id');
      		$joined = $user->get('createdon');
      		$profile = $user->getOne('Profile');
              	//
              	$modx->setPlaceholders(array(
                  		'id'  => $user->get('id'),
                  		'username' => $name,
                  		'fullname' => $profile->get('fullname'),
                  		'joined' => $user->get('createdon'),
              	),'user_');
      		//
      	} else {
      	   $section = 5;//id страницы 404
          	}
          $modx->sendForward($section);
          
      }
      p.s. табуляция тут спадает(
        Максим Кузнецов
        27 мая 2017, 12:57
        +1
        $section = 5;//id страницы 404
        — это лучше убрать, а в sendForward добавить проверку заполненности $section, в противном случае не выполнять ничего.
        Если выполнять $modx->sendForward(айди_страницы_404), то будет отдаваться некорректный код ответа, ну и последующие плагины на OnPageNotFound не будут корректно обрабатываться.
          Andrei D.
          27 мая 2017, 13:23
          +1
          согласен, на скорую руку добавил
          Andrey
          27 мая 2017, 12:59
          0
          та не, мне бы сбахать, чтобы все динамично было…
          Чтобы не создавать дохрена ресурсов и не привязывать перехват алиасов к конкретному ресурсу по его индентификатору!

          Потому как у меня несколько контекстов и на каждом присутствует данная модель списка и страниц пользователя и поэтому бабахать дофига ресурсов и на каждый конекст плагин, чет не очень хочется, перспективы хреновые, потому черт ногу сломит!

          И тем не менее, спасибо!
            Andrei D.
            27 мая 2017, 13:21
            +1
            передавай тогда уникальный идентификатор в плейсхолдер, например,
            case 'comments':
            $page_type = 'comments';

            $modx->setPlaceholder('page_type', $page_type);
            и на общей странице через fenom выводи нужный контент

            p.s. уходи от контекстов, если сайт только разрабатывается. для двух языков еще нормально, но потом будет каша из огромного количества ресурсов + по дизайну сложно что-то экстра конкретное сделать для страницы с определенным ID (3 языка = перечисление трёх id и т.д.)
              Andrey
              27 мая 2017, 14:57
              0
              та ушел бы, если бы мозгов хватило :D

              А то что вы предлагаете уже пробовал выше, говорю ж не работает :(
                Andrey
                27 мая 2017, 23:51
                0
                просто понимаете какое дело, я как уже писал вышел практически полностью не шарю в пхп и даже написать плагин для меня было бы довольно таки сложно, поэтому если вам не трудно, не могли бы вы поделиться рабочим примером и с хотя бы небольшим описанием того, как на странице вывести феномом страницу пользователя! Я уже очень долго бьюсь, но так и не нашел решения, которое бы работало у меня… Благо хотя бы нашелся плагин который работает и вызывает страницу пользователя. Вот я прям очень хочу под него интегрировать виртуальные вкладки. Просто пока не один из перечисленных примеров не помог, а может и написан с мааааленькой ошибкой, которую я не найду, поскольку нифига не шарю в пхп :(
                  Andrei D.
                  28 мая 2017, 12:19
                  +1
                  Как в моем комменте выше, если вы не хотите (извиняюсь, что переходил на «ты» – увидел тёзку, расслабился)) создавать отдельные ресурсы для каждой из виртуальных страниц, но у вас есть одна общая страница, то нужно передавать любой идентификатор на неё.

                  Если плагин и все страницы (username/posts, username/comments и т.д.) работают +
                  если установлен pdoTools и в настройках сайта значения: pdotools_fenom_default, pdotools_fenom_modx, pdotools_fenom_parser,pdotools_fenom_php = ДА, то с помощью Fenom это будет примерно так:

                  {if $page_type == 'comments'}
                  [[$чанк_комментов]] или контент
                  {elseif $page_type == 'favorites'}
                  [[$чанк_избранного]] или контент
                  {/if}

                  Шаблонизатор Fenom

                  или просто подставляете нужный чанк на странице одной строчкой:
                  [[$virtualpage_{$page_type}]]
                  или
                  [[$virtualpage_[[!+page_type]]]]
                    Andrey
                    29 мая 2017, 16:23
                    0
                    не, ну это все уже понятно! А я имею ввиду как плагин ваш должен выглядеть? С учетом всех всех изменений и чтобы удовлетворял условия:

                    1. Адрес страницы пользователя выглядит так: mysite.com/users/[[+идентификатор пользователя]]
                    2. В плагине учтены моменты с динамической. Ко всем алиасам со значением users применяется работа данного плагина, а так же формируются вкладки.
                    3. В плагине учтена динамика для вкладок. (См. выше)

                    Т.е.

                    Тема с плейсхолдерами конечно мне понятна, но как это технически организовывается? Добавляются ли значения в плагин или нет? Мне нужен просто готовый плагин с готовым вызовом, как это делается! Я ж говорю, дубина я совсем, если давать мне все по кусочкам, умею только разбирать и собираться обратно пока :(

                    Заранее спасибо!
                      Andrei D.
                      30 мая 2017, 05:05
                      +1
                      плагин примерно такой (не проверял):
                      <?php
                      if ($modx->event->name != 'OnPageNotFound') {return false;}
                      $alias = $modx->context->getOption('request_param_alias', 'q');
                      if (!isset($_REQUEST[$alias])) {return false;}
                      
                      $request = $_REQUEST[$alias];
                      $tmp = explode('/', $request);
                      if ($tmp[0] == 'users' && count($tmp) >= 2) {
                      	$section = 1; //id страницы профиля
                      	$name = str_replace('.html', '', $tmp[1]);
                      	if ($tmp[1] != $name || !isset($tmp[2])) {
                      		$modx->sendRedirect($tmp[0] . '/' . $name);
                      	}
                      
                      	switch($tmp[2]) {
                      		case 'posts':
                      			$page_type = 'posts';
                      			break;
                      		case 'comments':
                      			$page_type = 'comments';
                      			break;
                      		case 'favourites':
                      			$page_type = 'favourites';
                      			break;
                      		default:
                      			$page_type = 'main';
                      			break;
                      	}
                      	
                      	if ($user = $modx->getObject('modUser', array('username' => $name))) {
                      		$id = $user->get('id');
                      		$joined = $user->get('createdon');
                      		$profile = $user->getOne('Profile');
                      		$fullname = $profile->get('fullname');
                      		$photo = $profile->get('photo');
                      		//
                      		$modx->setPlaceholder('page_type', $page_type);
                      		$modx->setPlaceholders(array(
                      			'id'  => $id,
                      			'joined' => $joined,
                      			'username' => $name,
                      			'fullname' => $fullname,
                      			'photo' => $photo,
                      		),'user_');
                      		/////// может пригодиться
                      		$additional = $modx->getObject('TicketAuthor', $id);
                      		$modx->setPlaceholder('user_posts_count', $additional->tickets);
                      		$modx->setPlaceholder('user_comments_count', $additional->comments);
                      		$modx->setPlaceholder('user_favourites_count', $additional->stars_tickets);
                      		$modx->setPlaceholder('pagetitle', $fullname);
                      		/////// может пригодиться//
                      		$modx->sendForward($section);
                      	}
                      }

                      если fenom включен, то на странице профиля примерно так (наобум):
                      <ul class="tabs">
                      <li class="{if $page_type == 'main'}active{/if}"><a href="/users/{$user_username}">Профиль</a></li>
                      <li class="{if $page_type == 'posts'}active{/if}"><a href="/users/{$user_username}/posts">Посты<span class="count">{$user_posts_count}</span></a></li>
                      <li class="{if $page_type == 'comments'}active{/if}"><a href="/users/{$user_username}/comments">Комменты<span class="count">{$user_comments_count}</span></a></li>
                      <li class="{if $page_type == 'favourites'}active{/if}"><a href="/users/{$user_username}/favourites">Избранное<span class="count">{$user_favourites_count}</span></a></li>
                      </ul>
                      
                      <!--чанк-->[[$virtualpage_{$page_type}]]<!--чанк//-->
                      p.s. в чанке плейсхолдеры через [[!+плейсхолдер]], либо вызывать чанк через {$_modx->getChunk(…
                        Andrey
                        30 мая 2017, 11:33
                        0
                        нууу, вот:


                        :D
                          Максим Кузнецов
                          30 мая 2017, 11:42
                          +1
                          Скорее всего у вас проблемы с настройками htaccess или системными настройками суффикса html-документов.

                          Попробуйте в плагине выше заменить:
                          $name = str_replace('.html', '', $tmp[1]);
                          	if ($tmp[1] != $name || !isset($tmp[2])) {
                          		$modx->sendRedirect($tmp[0] . '/' . $name);
                          	}

                          На это:
                          $name = str_replace('.html', '', $tmp[1]);
                          	if (!isset($tmp[2])) {
                          		$modx->sendRedirect($tmp[0] . '/' . $name);
                          	}

                          А вообще, правильнее было бы убрать суффикс '.html' для документов.
                            Andrey
                            30 мая 2017, 11:50
                            0
                            убран! С самого начала пользования!
                          Andrey
                          30 мая 2017, 11:50
                          0
                          кажется понял! Вот это условие:
                          $section = 1; //id страницы профиля
                          как бы мне его заменить на динамическое определение страницы по алиасу:
                          users
                          :D
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              40