Андрей

Андрей

Был в сети 25 июня 2026, 01:11
Заказы принимаю
Максим Кузнецов
Максим Кузнецов
3
+2
Вообще, для сео это совсем не критично, т.к:
— если вам необходимо добавить страницы пользователей в sitemap, то это можно сделать в рамках pdoUsers
— если вам необходимы динамичные заголовки и мета-теги, то можно сделать примерно так:

1. В плагине создаем плейсхолдер user_id

2. В мета-тегах проверяем его наличие:
{block 'meta'}
	{var $user_id = $_modx->getPlaceholder('user_id')} 

	{if $user_id | length > 0}
		{var $user_name = $_modx->getPlaceholder('user_name')}
		{var $pagetitle = $user_name ~ ' / Профиль пользователя'}
	
		<title>{$pagetitle ~' :: '~ $_modx->config.site_name}</title>
		...
	{else}
		{parent}
		//обычный набор мета-тегов
	{/if}
{/block}
— надеюсь логика понятна..)

Что же до примера со вторым вариантом, то примерно вот так:

1. Создание страницы пользователя (тикетом)
<?php
	if ($modx->event->name == 'OnUserActivate') {
		if ($user) {
			if ($profile = $user->getOne('Profile')) {
				$user_id = $user->get('id');
				$fullname = $profile->get('fullname');

				/* Можно распределять пользователей в зависимости от их группы */
				if ($user->isMember('Users')) {
					//указываем родителя и шаблон
					$parent = 21;
					$template = 28;
				}
	
				if (isset($parent)) {	
					//Дополнительно может потребоваться проверка на то, создана ли уже страница для пользователя 
					//(на случай, если у вас возможна повторная активация-деактивация пользотвалея 
					$page = $modx->getObject('modResource', array(
						'parent' => $parent,
						'createdby' => $user_id
					));
		
					if (!$page) {
						/* Формируем uri по айди пользователя */
						$parent_alias = $modx->getObject('modDocument', $parent)->get('alias');
						$parent_alias .= '/' . $user_id;
					
						$ticket = $modx->newObject('modDocument');
					
						$ticket->set('parent', $parent);
						$ticket->set('template', $template);
						$ticket->set('class_key', 'Ticket');
						$ticket->set('show_in_tree', 0);
						$ticket->set('published', 1);
						$ticket->set('author', $user_id);
						$ticket->set('createdby', $user_id);
						$ticket->set('pagetitle', $fullname);
						$ticket->set('uri_override', 1);
						$ticket->set('uri', $parent_alias);
						$ticket->set('alias', $user_id);

						$ticket->save();
					}
				}
			}
		}
	}

2. Синхронизируем данные (в одну сторону — от пользователя к странице). Соответственно, если есть потребность редактировать поля пользователя из админки через его страницу, потребуется еще один плагин.
<?php
	if ($modx->event->name == 'OnUserFormSave' && $mode != 'new') {
		if ($user) {
			if ($profile = $user->getOne('Profile')) {
				$user_id = $user->get('id');

				if ($user->isMember('Users')) {
					$parent = 21;
				}
				
				if (isset($parent)) {
					//Ищем страницу пользователя
					$page = $modx->getObject('modResource', array(
						'parent' => $parent,
						'createdby' => $user_id
					));
					
					if ($page) {
						$extended = $profile->get('extended');
						
						//Обновляем дефолтное поле страницы
						$page->set('pagetitle', $profile->get('fullname'));
						
						//Обновляем тв-поле
						if (isset($extended['phone'])) {
							$page->setTVValue('user_phone', $extended['phone']);
						}

						//Дополнить требуемыми полями по вкусу %)
					
						$page->save();
					}
				}
			}
		}
	}
Володя
Володя
6
+3
пример вывода всех тегов
<!-- tags -->
{set $tags = $_modx->runSnippet('pdoResources',[
'class' => 'msProductOption',
'sortby' => 'value',
'sortdir' => 'ASC',
'where' => json_encode([
'key' => 'tags',
'value:!='=> 'undefined'
]),
'select' => 'DISTINCT(msProductOption.value) as id, "tag" as class_key',
'limit' => 0,
'return' => 'json'
])}
{set $tags = $tags | fromJSON}
{if count($tags)}
	<ul class="uk-float-right uk-navbar-nav tm-header-tags">
		<li data-uk-dropdown="" aria-haspopup="true" aria-expanded="false">
			<a>{'msfbshop_tags' | lexicon}</a>
			<div aria-hidden="true" class="uk-dropdown uk-dropdown-navbar uk-dropdown-bottom">
				<ul class="uk-nav uk-nav-navbar">
				{foreach $tags as $row}
					<a href="{$row.link}">{$row.id}</a>
				{/foreach}
				</ul>
			</div>
		</li>
	</ul>
{/if}
Алексей Ерохин
Алексей Ерохин
6
0
$options = array();
$translit = $modx->getOption('friendly_alias_translit', $options, 'russian');
$translitClass = $modx->getOption('friendly_alias_translit_class', $options, 'translit.modTransliterate');
$translitClassPath = $modx->getOption('friendly_alias_translit_class_path', $options, $modx->getOption('core_path', $options, MODX_CORE_PATH) . 'components/');
$modx->getService('translit', $translitClass, $translitClassPath, $options);
$transliteratedtext = $modx->translit->translate($text, $translit);
Prihod
Prihod
1
0
ставлю и в настройках компонента и в настройках на сервере одинаковую задачу, которая должна запускаться в одно и то же время. правильно?
Нет
в крон ты ставишь выполнения каждую секунду скрипта ..../core/components/msimportexport/cron.php 1> /dev/null 2>&1
А в настройках компонента импорта по cron для конкретной задачи уже выставляешь время когда нужно выполнить ее
Владимир
Владимир
2
+1
Странно что не пишет ни кто об использовании пользовательских заголовков которые можно указать в типах содержимого.
Создал новый тип содержимого (contenttype) с пустым расширением файла (без .html) и указал
Cache-Control: max-age=3600, must-revalidate
на вкладке

и кеширование в браузере можно выставить нужное.
Максим Кузнецов
Максим Кузнецов
6
+4
Дмитрий Кондаков
Дмитрий Кондаков
3
+1
Создаете плагин на событие msieOnCompleteImportProduct:
<?php
/** @var modX $modx */
switch ($modx->event->name) {
	case 'msieOnCompleteImportProduct':

		// Получаем id всех импортированных товаров
		$currentIDs = explode(",", $modx->event->params['data']);

		// Получаем id ВСЕХ товаров в магазине
		$q = $modx->newQuery('msProduct', array('parent' => 7, 'template' => 8)); // тут свои условия
		$q->prepare();
		$q->stmt->execute();
		$oldIDs = $q->stmt->fetchAll(PDO::FETCH_COLUMN, 0);

		// Вычисляем id товаров которые есть на сайте, но нет в файле импорта
		$oldIDs = array_diff($oldIDs, $currentIDs);

		if ($toRemoveIDs) {
		  foreach ($toRemoveIDs as $cur) {
		    // и тут делаем с ними что угодно
		  }
		}
	break;
}
PS. на всякий случай сделайте бэкап БД перед тестированием плагина
Дмитрий Мансуров
Дмитрий Мансуров
4
0
Спустя несколько лет вопрос все еще актуален поэтому напишу краткую инструкцию
Редактируем файлы
core/components/minishop2/model/minishop2/mscarthandler.class.php
Ищем
$count = inval($count);

(у меня это строка 153)
Меняем на
$count = floatval($count);
Файл:
core/components/minishop2/model/minishop2/mysql/msorderproduct.map.inc.php
Ищем
'count' => 
    array (
      'dbtype' => 'int',
      'precision' => '10',
      'phptype' => 'integer',
      'attributes' => 'unsigned',
      'null' => true,
      'default' => 1,
    ),
меняем на
'count' => 
    array (
      'dbtype' => 'decimal',
      'precision' => '10,2',
      'phptype' => 'float',
      'null' => true,
      'default' => 1,
    ),
Файл:
core/components/minishop2/model/schema/minishop2.mysql.schema.xml
Ищем
<field key="count" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="true" default="1"/>
меняем на
<field key="count" dbtype="decimal" precision="10,2" phptype="float"  null="true" default="1"/>