Вопросы

Страницы вида: сайт/index.php/страница код 200OK

Настроены ЧПУ и корректно работают, НО:
Страницы вида: сайт/index.php/страница отдают всегда код 200 ОК (даже если такой страницы нет).
Помимо этого, всегда отображается главная страница, даже если страница существует, например есть страница сайт/оплата со своим контентом, по адресу сайт/index.php/оплата откроется главная и отдаст код 200 ОК.

В чем может быть проблема, и как ее решить?
MODX Revo 2.5.7 php7.1
Павел Степанов
22 августа 2017, 15:24
modx.pro
1
1 742
0

Вывод миниатюр на странице

Гуру подскажите, уже себе мозг вскрыл.

Нужно на произвольной странице вывести все изображения товаров категории. Если быть точнее то миниатюры 200х200

Делаю так
{'pdoResources' | snippet : [
    'tpl' => 'tpl.msGallery.image',
    'limit' => 0,
    'parents'=>'123',
]}
Чанк tpl.msGallery.image

[[!pdoResources?
	&class=`msProductFile`
	&where=`{"product_id":[[+id]], "parent":0}`
	&tpl=`@INLINE <img src="[[+url]]">`
	&sortby=`id`
	&sortdir=`asc`
]]
на странице выводятся все изображения, но мне нужно получить на выходе миниатюры 200х200, понимаю что нужно с помощью sql запроса получить путь, но как составить запрос, понять не могу.
Георгий Графов
22 августа 2017, 14:20
modx.pro
1 363
0

Не меняется контекст при смене URL

Здравствуйте! Помогите разобраться, хочу сделать смену контекста в зависимости от url, например

toyota.sto-good-service.ru включается контекст toyota

nissan.sto-good-service.ru/ включается контекст nissan
и тд
Сделал все по инструкции bezumkin.ru/sections/tips_and_tricks/1987/
Добавил автоподдомен в reg.ru но теперь у меня при входе на toyota.sto-good-service.ru Выдает 403 ошибку, в чем ошибся?

Код плагина:
<?php
if ($modx->event->name == 'OnHandleRequest') {
    if ($modx->context->get('key') == 'mgr') {return;}
    // сравнение текущего имени хоста и искомого
    if (strstr($_SERVER['HTTP_HOST'], 'toyota.sto-good-service.ru') != false) {
        $modx->switchContext('toyota');
        return;
    }
}
onHandleRequest галочка стоит
настройки контекста toyota:


Дружественные URL включены
htaccess:

# MODX supports Friendly URLs via this .htaccess file. You must serve web
# pages via Apache with mod_rewrite to use this functionality, and you must
# change the file name from ht.access to .htaccess.
#
# Make sure RewriteBase points to the directory where you installed MODX.
# E.g., "/modx" if your installation is in a "modx" subdirectory.
#
# You may choose to make your URLs non-case-sensitive by adding a NC directive
# to your rule: RewriteRule ^(.*)$ index.php?q=$1 [L,QSA,NC]

RewriteEngine On
RewriteBase /



# Rewrite www.domain.com -> domain.com -- used with SEO Strict URLs plugin
#RewriteCond %{HTTP_HOST} .
#RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
#RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
#
# or for the opposite domain.com -> www.domain.com use the following
# DO NOT USE BOTH
#
#RewriteCond %{HTTP_HOST} !^$
#RewriteCond %{HTTP_HOST} !^www\. [NC]
#RewriteCond %{HTTP_HOST} (.+)$
#RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L] .



# Rewrite secure requests properly to prevent SSL cert warnings, e.g. prevent 
# https://www.domain.com when your cert only allows https://secure.domain.com
#RewriteCond %{SERVER_PORT} !^443
#RewriteRule (.*) https://example-domain-please-change.com/$1 [R=301,L]



# The Friendly URLs part
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]



# Make sure .htc files are served with the proper MIME type, which is critical
# for XP SP2. Un-comment if your host allows htaccess MIME type overrides.

#AddType text/x-component .htc



# If your server is not already configured as such, the following directive
# should be uncommented in order to set PHP's register_globals option to OFF.
# This closes a major security hole that is abused by most XSS (cross-site
# scripting) attacks. For more information: http://php.net/register_globals
#
# To verify that this option has been set to OFF, open the Manager and choose
# Reports -> System Info and then click the phpinfo() link. Do a Find on Page
# for "register_globals". The Local Value should be OFF. If the Master Value
# is OFF then you do not need this directive here.
#
# IF REGISTER_GLOBALS DIRECTIVE CAUSES 500 INTERNAL SERVER ERRORS :
#
# Your server does not allow PHP directives to be set via .htaccess. In that
# case you must make this change in your php.ini file instead. If you are
# using a commercial web host, contact the administrators for assistance in
# doing this. Not all servers allow local php.ini files, and they should
# include all PHP configurations (not just this one), or you will effectively
# reset everything to PHP defaults. Consult www.php.net for more detailed
# information about setting PHP directives.

#php_flag register_globals Off



# For servers that support output compression, you should pick up a bit of
# speed by un-commenting the following lines.

#php_flag zlib.output_compression On
#php_value zlib.output_compression_level 5



# The following directives stop screen flicker in IE on CSS rollovers. If
# needed, un-comment the following rules. When they're in place, you may have
# to do a force-refresh in order to see changes in your designs.

#ExpiresActive On
#ExpiresByType image/gif A2592000
#ExpiresByType image/jpeg A2592000
#ExpiresByType image/png A2592000
#BrowserMatch "MSIE" brokenvary=1
#BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
#BrowserMatch "Opera" !brokenvary
#SetEnvIf brokenvary 1 force-no-vary

Нужно ли ставить что-то на поддоменах? например устанавливать cms? Или редиректы какие?
Вячеслав Варов
22 августа 2017, 13:00
modx.pro
1
1 351
0

Bootstrap miniShop

Где в Bootstrap можно найти то что отвечает за область видимости вводимых символов в форму заказа? У меня область для введения email обрезалась после того как сдвинул ячейки к краю экрана take.ms/8aKH7 хотя сами ячейки достаточно широкие. Или может быть где то есть руководство по тому как будстрап взаимодействует с MODX? А может эта настройка лежит где-то в чанке самого miniShop?
Василий
22 августа 2017, 10:49
modx.pro
1 040
-3

Запутался со вложенностью MIGX-полей

Добрый день.
Есть вызов сниппета getImageList для MIGX-поля pageSubtitleAndText
[[getImageList?
  &tvname=`pageSubtitleAndText`
  &tpl=`contentBlock`
]]
В чанке contentBlock есть ещё один вызов сниппета getImageList для MIGX-поля multiImage
[[getImageList? 
  &tvname=`multiImage`
  &tpl=`contentImage`
]]
И, наконец, чанк contentImage
<img src="[[+image:phpthumbof=`w=698`]]">
Ожидалось, что внутренний сниппет соберёт картинки, передаст их во внешний, который возьмёт остальные данные и создаст блок с контентом. На деле же картинки не выводятся. Что я делаю не так?
Валерий
22 августа 2017, 10:48
modx.pro
1 786
0

tpl.msProducts.row и количество товара

Добрый день, кто то сталкивался с задачей добавить в tpl.msProducts.row инпут с количеством товара? А то даже мыслей нет никаких как реализовать, заранее премного благодарен за любую помощь
Андрей
22 августа 2017, 10:35
modx.pro
2 336
0

$product.cost и обновление

Доброго времени суток, в корзине есть
<div class='price-total'>{$product.cost} руб.</div>
для каждого товара выводит отдельную цену умноженную на количество, но при изменении количества price-total меняется только после обновления страницы, я так предполагаю что надо его обернуть в какой то div c id, но вопрос в какой?
Андрей
22 августа 2017, 07:17
modx.pro
1
2 480
0

CurrencyRate для беларусов

Не знаю, понадобится ли это кому-то или нет, но мне вот уже пригодилось пару раз, а именно — немножко переписать CurrencyRate для Нацбанка Беларуси, например, чтобы указывать цену в долларах с автоматической конвертацией в белки (у нас в Беларуси это очень модно и востребовано, т.к цену все хотят писать в долларах, а по закону нельзя)

По этому пути заменяем содержимое скрипта core/components/currencyrate/model/currencyrate/currencyrate.class.php

вот этим
<?php

/**
 * The base class for currencyrate.
 */
class currencyrate
{
    /* @var modX $modx */
    public $modx;
    public $namespace = 'currencyrate';
    public $cache = null;
    public $active = false;
    public $config = array();

    protected $list = array();
    protected $rub = array(
        'numcode'  => 933,
        'charcode' => 'BYN',
        'name'     => 'Белорусский рубль',
        'rate'     => 0
    );
    public $currency;
    /* @var pdoTools $pdoTools */
    public $pdoTools;

    /**
     * @param modX  $modx
     * @param array $config
     */
    function __construct(modX &$modx, array $config = array())
    {
        $this->modx =& $modx;

        $this->namespace = $this->getOption('namespace', $config, 'currencyrate');
        $corePath = $this->modx->getOption('currencyrate_core_path', $config,
            $this->modx->getOption('core_path') . 'components/currencyrate/');
        $assetsUrl = $this->modx->getOption('currencyrate_assets_url', $config,
            $this->modx->getOption('assets_url') . 'components/currencyrate/');
        $connectorUrl = $assetsUrl . 'connector.php';

        $this->config = array_merge(array(
            'assetsUrl'    => $assetsUrl,
            'cssUrl'       => $assetsUrl . 'css/',
            'jsUrl'        => $assetsUrl . 'js/',
            'imagesUrl'    => $assetsUrl . 'images/',
            'connectorUrl' => $connectorUrl,

            'corePath'       => $corePath,
            'modelPath'      => $corePath . 'model/',
            'chunksPath'     => $corePath . 'elements/chunks/',
            'templatesPath'  => $corePath . 'elements/templates/',
            'chunkSuffix'    => '.chunk.tpl',
            'snippetsPath'   => $corePath . 'elements/snippets/',
            'processorsPath' => $corePath . 'processors/',

            'last_date' => $this->modx->getOption('currencyrate_last_date'),
            'currency'  => & $_COOKIE['currency'],

        ), $config);

        $this->modx->addPackage('currencyrate', $this->config['modelPath']);
        $this->modx->lexicon->load('currencyrate:default');
        $this->active = $this->modx->getOption('currencyrate_active', $config, false);
        $this->currency = &$this->config['currency'];
        if (empty($this->currency)) {
            $this->currency = $this->modx->getOption('currencyrate_currency', null, $this->rub['charcode']);
        }
    }

    /**
     * @param       $key
     * @param array $config
     * @param null  $default
     *
     * @return mixed|null
     */
    public function getOption($key, $config = array(), $default = null)
    {
        $option = $default;
        if (!empty($key) && is_string($key)) {
            if ($config != null && array_key_exists($key, $config)) {
                $option = $config[$key];
            } elseif (array_key_exists($key, $this->config)) {
                $option = $this->config[$key];
            } elseif (array_key_exists("{$this->namespace}.{$key}", $this->modx->config)) {
                $option = $this->modx->getOption("{$this->namespace}.{$key}");
            }
        }

        return $option;
    }

    /**
     * Initializes msOptionsPrice into different contexts.
     *
     * @param string $ctx The context to load. Defaults to web.
     * @param array  $scriptProperties array with additional parameters
     *
     * @return boolean
     */
    public function initialize($ctx = 'web', $scriptProperties = array())
    {
        $this->config = array_merge($this->config, $scriptProperties);
        if (!$this->pdoTools) {
            $this->loadPdoTools();
        }
        $this->pdoTools->setConfig($this->config);
        $this->config['ctx'] = $ctx;
        if (!empty($this->initialized[$ctx])) {
            return true;
        }
        switch ($ctx) {
            case 'mgr':
                break;
            default:
                if (!defined('MODX_API_MODE') || !MODX_API_MODE) {
                    $config = $this->makePlaceholders($this->config);
                    $css = !empty($this->config['front_css'])
                        ? $this->config['front_css']
                        : $this->modx->getOption('currencyrate_front_css');
                    if (!empty($css) && preg_match('/\.css/i', $css)) {
                        $this->modx->regClientCSS(str_replace($config['pl'], $config['vl'], $css));
                    }
                    $js = !empty($this->config['front_js'])
                        ? $this->config['front_js']
                        : $this->modx->getOption('currencyrate_front_js');
                    if (!empty($js) && preg_match('/\.js/i', $js)) {
                        $this->modx->regClientScript(str_replace($config['pl'], $config['vl'], $js));
                    }
                }
                $this->initialized[$ctx] = true;
                break;
        }

        return true;
    }

    /**
     * формируем массив валют
     *
     * @return bool
     */
    public function loadRate()
    {
        $xml = new DOMDocument();
        $url = $this->modx->getOption('currencyrate_url', '',
                'http://www.nbrb.by/Services/XmlExRates.aspx?ondate=') . date('m/d/Y');
        if (@$xml->load($url)) {
            $this->list = array();
            $root = $xml->documentElement;
            $items = $root->getElementsByTagName('Currency');

            foreach ($items as $item) {
                $numcode = $item->getElementsByTagName('NumCode')->item(0)->nodeValue;
                $charcode = $item->getElementsByTagName('CharCode')->item(0)->nodeValue;
                $nominal = $item->getElementsByTagName('Scale')->item(0)->nodeValue;
                $name = $item->getElementsByTagName('Name')->item(0)->nodeValue;
                $value = $item->getElementsByTagName('Rate')->item(0)->nodeValue;
                $value = floatval(str_replace(',', '.', $value));

                $this->list[] = array(
                    'numcode'  => $numcode,
                    'charcode' => $charcode,
                    'nominal'  => $nominal,
                    'name'     => $name,
                    'value'    => $value,
                );
            }
            if ($setting = $this->modx->getObject('modSystemSetting', 'currencyrate_last_date')) {
                $setting->set('value', date('Y-m-d H:i:s'));
                $setting->save();
            }

            return true;
        }
        else {
            $this->modx->log(1, print_r('[CR:Error] not cyrrency for url - ' . $url, 1));
        }

        return false;
    }

    /**
     * @return bool
     */
    public function rateIntoDb()
    {
        if ($this->loadRate()) {
            // add RUB
            if (!$itemFromDb = $this->modx->getObject('CRlist', array('numcode' => $this->rub['numcode']))) {
                $itemFromDb = $this->modx->newObject('CRlist');
                $itemFromDb->fromArray(array_merge(
                    $this->rub,
                    array(
                        'nominal'   => 1,
                        'value'     => 1,
                        'valuerate' => 1,
                        'rank'      => 0
                    )));
                if (!$itemFromDb->save()) {
                    $this->modx->log(1,
                        print_r('[CR:Error] save to db for charcode - ' . $itemFromDb->get('charcode'), 1));
                }
            }
            foreach ($this->list as $item) {
                if (!$itemFromDb = $this->modx->getObject('CRlist', array('numcode' => $item['numcode']))) {
                    $itemFromDb = $this->modx->newObject('CRlist');
                    $itemFromDb->set('rank', $this->modx->getCount('CRlist'));
                }
                $item['rate'] = $itemFromDb->get('rate');
                $item = $this->calcData($item);
                $itemFromDb->fromArray($item);
                if (!$itemFromDb->save()) {
                    $this->modx->log(1, print_r('[CR:Error] save to db for charcode - ' . $item['charcode'], 1));
                }
            }
            $this->cleanCache();

            return true;
        }
        $this->modx->log(1, print_r('[CR:Error] NO loadRate()', 1));

        return false;
    }

    /**
     * @param array $data
     *
     * @return array
     */
    public function calcData($data = array())
    {
        if (empty($data['nominal'])) {
            $data['nominal'] = 1;
        }
        $data['valuerate'] = round(($data['value'] / $data['nominal']), 4);
        $valuerate = $this->calcValueRate($data['valuerate'], $data['rate']);
        if ((float)$valuerate == (float)$data['valuerate']) {
            $data['rate'] = '';
        }
        $data['valuerate'] = $valuerate;
        $data['charcode'] = strtoupper($data['charcode']);
        if ($data['rate'] == '') {
            $data['rate'] = 0;
        }

        return $data;
    }

    /**
     * @param $value
     * @param $rate
     *
     * @return float
     */
    public function calcValueRate($value, $rate)
    {
        if (preg_match('/%$/', $rate)) {
            $rate = str_replace('%', '', $rate);
            $rate = $value / 100 * $rate;
        }
        $value += $rate;

        return round($value, 4);
    }

    /**
     * from
     * https://github.com/bezumkin/Tickets/blob/9c09152ae4a1cdae04fb31d2bc0fa57be5e0c7ea/core/components/tickets/model/tickets/tickets.class.php#L1120
     *
     * Loads an instance of pdoTools
     * @return boolean
     */
    public function loadPdoTools()
    {
        if (!is_object($this->pdoTools) || !($this->pdoTools instanceof pdoTools)) {
            /** @var pdoFetch $pdoFetch */
            $fqn = $this->modx->getOption('pdoFetch.class', null, 'pdotools.pdofetch', true);
            if ($pdoClass = $this->modx->loadClass($fqn, '', false, true)) {
                $this->pdoTools = new $pdoClass($this->modx, $this->config);
            } elseif ($pdoClass = $this->modx->loadClass($fqn, MODX_CORE_PATH . 'components/pdotools/model/', false,
                true)
            ) {
                $this->pdoTools = new $pdoClass($this->modx, $this->config);
            } else {
                $this->modx->log(modX::LOG_LEVEL_ERROR,
                    'Could not load pdoFetch from "MODX_CORE_PATH/components/pdotools/model/".');
            }
        }

        return !empty($this->pdoTools) && $this->pdoTools instanceof pdoTools;
    }

    /**
     * from
     * https://github.com/bezumkin/Tickets/blob/9c09152ae4a1cdae04fb31d2bc0fa57be5e0c7ea/core/components/tickets/model/tickets/tickets.class.php#L1147
     *
     * Process and return the output from a Chunk by name.
     *
     * @param string  $name The name of the chunk.
     * @param array   $properties An associative array of properties to process the Chunk with, treated as placeholders
     *     within the scope of the Element.
     * @param boolean $fastMode If false, all MODX tags in chunk will be processed.
     *
     * @return string The processed output of the Chunk.
     */
    public function getChunk($name, array $properties = array(), $fastMode = false)
    {
        if (!$this->modx->parser) {
            $this->modx->getParser();
        }
        if (!$this->pdoTools) {
            $this->loadPdoTools();
        }

        return $this->pdoTools->getChunk($name, $properties, $fastMode);
    }

    /**
     * Method for transform array to placeholders
     *
     * @var array  $array With keys and values
     * @var string $prefix Prefix for array keys
     *
     * @return array $array Two nested arrays with placeholders and values
     */
    public function makePlaceholders(array $array = array(), $prefix = '')
    {
        if (!$this->pdoTools) {
            $this->loadPdoTools();
        }

        return $this->pdoTools->makePlaceholders($array, $prefix);
    }

    /**
     * @param string $message
     * @param array  $data
     * @param array  $placeholders
     *
     * @return array|string
     */
    public function error($message = '', $data = array(), $placeholders = array())
    {
        $response = array(
            'success' => false,
            'message' => $this->modx->lexicon($message, $placeholders),
            'data'    => $data,
        );

        return $this->config['json_response']
            ? $this->modx->toJSON($response)
            : $response;
    }

    /**
     * @param string $message
     * @param array  $data
     * @param array  $placeholders
     *
     * @return array|string
     */
    public function success($message = '', $data = array(), $placeholders = array())
    {
        $response = array(
            'success' => true,
            'message' => $this->modx->lexicon($message, $placeholders),
            'data'    => $data,
        );

        return $this->config['json_response']
            ? $this->modx->toJSON($response)
            : $response;
    }

    /**
     * from
     * https://github.com/Mark-H/ClientConfig/blob/master/core/components/clientconfig/model/clientconfig/clientconfig.class.php#L75
     *
     * Grab settings (from cache if possible) as key => value pairs.
     * @return array|mixed
     */
    public function getList()
    {
        /* Attempt to get from cache */
        $cacheOptions = array(xPDO::OPT_CACHE_KEY => 'crlist');
        $list = $this->modx->getCacheManager()->get('crlist', $cacheOptions);
        if (empty($list) && $this->modx->getCount('CRlist') > 0) {
            $collection = $this->modx->getCollection('CRlist');
            $list = array();
            /* @var CRlist $setting */
            foreach ($collection as $value) {
                $list[$value->get('charcode')] = $value->get('valuerate');
            }
            /* Write to cache again */
            $this->modx->cacheManager->set('crlist', $list, 0, $cacheOptions);
        }

        return (is_array($list)) ? $list : array();
    }

    /**
     * Function for formatting price
     *
     * @param string $price
     * @param string $format
     * @param bool   $no_zeros
     *
     * @return mixed|string
     */
    public function formatPrice($price = '0', $format = '[2, ".", " "]', $no_zeros = true)
    {
        $pf = $this->modx->fromJSON($format);
        if (is_array($pf)) {
            $price = number_format($price, $pf[0], $pf[1], $pf[2]);
        }
        if ($no_zeros) {
            if (preg_match('/\..*$/', $price, $matches)) {
                $tmp = rtrim($matches[0], '.0');
                $price = str_replace($matches[0], $tmp, $price);
            }
        }

        return $price;
    }

    /**
     * clean cache
     */
    public function cleanCache()
    {
        $cacheOptions = array(xPDO::OPT_CACHE_KEY => 'crlist');
        $this->modx->cacheManager->clean($cacheOptions);
        $this->modx->log(modX::LOG_LEVEL_INFO, '[CR:Info] Clearing the cache. Path: crlist');
    }

    /*
     *
     * Events
     *
     */

    /**
     * @param $sp
     */
    public function OnHandleRequest($sp)
    {
        $list = $this->getList();
        $this->modx->setPlaceholders($list, '+');
    }

    /**
     * @param $sp
     */
    public function OnBeforeCacheUpdate($sp)
    {
        $this->cleanCache();
    }

}
В системных настройках меняем currencyrate_url на www.nbrb.by/Services/XmlExRates.aspx?ondate=

Может есть вариант «ровнее», но вроде и это работает=)
pompa94
22 августа 2017, 07:00
modx.pro
1
1 407
+1

Перевод из EURO в BYN

Доброго времени суток, у меня на сайте есть перевод валюты, я сделал его так сделал системную настройку range и там указываю курс, вывожу его так [[+price:mpy=`[[++range]]`]], всё работает, только при добавлении товара в корзину, не подтягивается новая цена, подскажите как решить это проблему.
Дима
21 августа 2017, 20:18
modx.pro
1 416
0

Есть ли аналоги [[++site_url]]?

Есть ли аналоги [[++site_url]]?
При использовании плагина debugParser, выяснил что повторное использование плейсхолдера ++site_url приводит к увеличению времени генерации странички.
Roman
21 августа 2017, 14:45
modx.pro
2 885
0