Вывод даты msTimeStamp полей MiniShop2: new, favorite, popular...

И снова, всем привет! Попросили меня на днях сделать вывод дат msTimeStamp, чего по какой то причине нет из коробки… Потратив некоторое время, получилось решение в виде сниппета, за помощь в написании которого, выражаю большую благодарность Степану Гончарову!



Итак, начнём:

1) Создаём сниппет msTimeStamp:
<?php
$id = $modx->getOption('id', $scriptProperties, $modx->resource->id);
$field = $modx->getOption('field', $scriptProperties);
$tpl = $modx->getOption('tpl', $scriptProperties, 'msTimeStampTpl');
if ($modx->getObject('msProduct', $id )->get($field) == null) {
    return false;  
}
$date = $modx->getObject('msTimeStampProduct', ['product_id' => $id, 'field' => $field]);
if($date == null) {
    return $modx->lexicon('ms2_product_'.$field);
}
if($date->get('valid_until') == null) {
    return $modx->lexicon('ms2_product_'.$date->get('field'));
}
return $modx->getChunk($tpl, ['field' => $modx->lexicon('ms2_product_'.$date->get('field')), 'date' => $modx->runSnippet('RusDate', ['input' => strtotime($date->get('valid_until')), 'options' => '%j %month %Yг.']),]);

2) Создаём стандартный чанк вывода msTimeStampTpl:
<p>[[+field]] до: [[+date]]</p>

3) Вызываем сниппет где нужно показать дату:

На странице товара
[[msTimeStamp?field=`new`]]

В карточке товара
[[msTimeStamp?id=`[[+id]]`&field=`new`]]

Так же, можно сделать свой чанк и указать в сниппете параметром tpl, в чанке используется всего 2 плейсхолдера: field — выбранное поле, и date — дата.

И тут надо отметить, что дата у меня обрабатывается ещё одним сниппетом-русификатором: RusDate от quasi-art.ru, за что им так же, отдельная благодарность!

И напоследок, если у поля new/favorite/popular не указана дата, сниппет будет возвращать только название поля. Название полей он берёт из словарей.

В данный момент ведётся активная работа над MiniShop3 силами сообщества и руками @Николай Савин, поэтому призываю всех неравнодушных поддержать эту работу финансово.
Денис Усманов
05 октября 2023, 17:01
modx.pro
3
782
+8

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

Дмитрий
16 октября 2023, 17:04
+2
Дополню пост. Возникла проблема при выводе даты на странице категории товаров. При использовании mFilter после фильтрации товаров дата «слетает». Сниппет переписан следующим образом:

<?php
$id = $modx->getOption('id', $scriptProperties, $modx->resource->id);
$field = $modx->getOption('field', $scriptProperties);
$tpl = $modx->getOption('tpl', $scriptProperties, 'msTimeStampTpl');
if ($modx->getObject('msProduct', $id )->get($field) == null) {
    return false;  
}

$tablePrefix = $modx->getOption('table_prefix');
$table = $tablePrefix.'mstimestamp_product';
$sql = "SELECT * FROM $table WHERE product_id = $id AND field = '$field'";
$statement = $modx->query($sql);
$date = $statement->fetch(PDO::FETCH_ASSOC);
if(!empty($date)){
    return $modx->getChunk($tpl, ['date' => $date['valid_until']]);
}
return false;

Также, вместо отображения даты, может быть удобнее вывести оставшееся количество дней. Я сделал это прямо в шаблоне на fenom:

{if $favorite}
{set $favoriteDate = '!msTimeStampDate' | snippet: ['id' => $id, 'field' => 'favorite']}

{if $favoriteDate != ''}
{set $nowDate = $date | date_format:"%s"}
{set $daysLeft = (($favoriteDate - $nowDate)/60/60/24) | number : 0 : '' : ''}

{if $daysLeft > 0}Ещё {$daysLeft | declension : 'день|дня|дней' : true}{else}Успейте сегодня!{/if}

{/if}
{/if}

Спасибо @Артур Шевченко за помощь и @Денис Усманов за данное полезное дополнение.

Критика и комментарии приветствуются.
    Maks
    02 мая 2024, 07:45
    0
    Что то не хочет выводить сколько осталось до конца акции. Выводит только Успейте сегодня!
    Maks
    02 мая 2024, 10:27
    0
    <?php
    $id = $modx->getOption('id', $scriptProperties, $modx->resource->id);
    $field = $modx->getOption('field', $scriptProperties);
    $tpl = $modx->getOption('tpl', $scriptProperties, 'msTimeStampTpl');
    if ($modx->getObject('msProduct', $id )->get($field) == null) {
        return false;  
    }
    
    $tablePrefix = $modx->getOption('table_prefix');
    $table = $tablePrefix.'mstimestamp_product';
    $sql = "SELECT * FROM $table WHERE product_id = $id AND field = '$field'";
    $statement = $modx->query($sql);
    $date = $statement->fetch(PDO::FETCH_ASSOC);
    if(!empty($date)){
        $validUntil = (int)$date['valid_until']; // Преобразуем строку в число
    
        $currentDate = time();
    
        if ($validUntil < $currentDate) {
            return false; // Акция уже завершена
        }
    
        $secondsLeft = $validUntil - $currentDate;
    
        $daysLeft = floor($secondsLeft / (60 * 60 * 24));
    
        $hoursLeft = floor(($secondsLeft % (60 * 60 * 24)) / (60 * 60));
    
        $minutesLeft = floor(($secondsLeft % (60 * 60)) / 60);
    
        $secondsLeft = $secondsLeft % 60;
    
        return $modx->getChunk($tpl, [
            'field' => $field,
            'date' => date('d.m.y', $validUntil),
            'daysLeft' => $daysLeft,
            'hoursLeft' => $hoursLeft,
            'minutesLeft' => $minutesLeft,
            'secondsLeft' => $secondsLeft
        ]);
    }
    return false;
    
    ?>
    Вот так сделал

    Чанк
    <p>
    Акция действует до: [[+date]] </p>
    <p>Осталось [[+daysLeft]] дней [[+hoursLeft]] часов [[+minutesLeft]] минут</p>
    На выходе получаем

    Акция действует до: 10.05.24
    Осталось 7 дней 16 часов 35 минут
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      3