Uladzislau

Uladzislau

С нами с 13 мая 2020; Место в рейтинге пользователей: #3305

Ищем PHP-программиста (MODx/нативный php)

30 70 000
В Московскую веб-студию АБВ сайт требуется на удаленную работу (полный рабочий день 6-8 часов) MODX-программист с опытом работы 1-3 года.
Нужно знать и уметь пользоваться:
minishop2;
msearch;
msImportExport;
pdotools и др. компонентами с modstore.pro.
Андрей
03 июня 2021, 16:32
modx.pro
1
446
+1

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 069
+1