А какой вы тип ставите?

Забыл сказать, и style.css ещё. Но там легко будет сравнить, по сервису который я привёл в прошлом посте

Ну там многие вещи изменились. Проще всего сравнить файлы через вот этот сервис.
А файлы поменялись:
1. product.tpl - страница товара,
2. show_complekts.tpl - показ комплектаций и
3. jquery.changeoffer.js.

Получить авторизованного пользователя можно так:

$user = \RS\Application\Auth::getCurrentUser()

Для работы с БД я на этой странице постарался описать.

Здравствуйте.
Итак нам нужно изменить количество товара. Сведения о количестве товаров хранятся в разрезе складов и комплектаций. По умолчанию к товару создаётся 1 комплектация где хранятся сведения о количестве данного товара. Если комплектаций больше, то соотвественно для каждой комплектации хранится своё количество товара на складе.
Поэтому нужно:
1. Подгрузить товар.
2. Вызвать у него заполнение количества комплектаций и остатков их.
3. Составить новый массив комплектаций с изменениями по количству на складе, привоив их товару.
4. Обновить товар.

Вот как это выглядит:

$product_id = 27452; //id товара
  
  $plus_value = 2; //Количество на которое увеличися товар
  
  //Подгрузим сам товар
  $product = new \Catalog\Model\Orm\Product($product_id);
  
  //Заполняем сведения об остатках на складах товара и имеющихся комплектациях, значения появятся в ключе offers
  $product->fillOffersStock();
  
  //Получим склад по умолчанию через запрос к БД использую ORM Request
  $warehouse = \RS\Orm\Request::make()
        ->from(new \Catalog\Model\Orm\WareHouse())
        ->where(array(
            'site_id' => \RS\Site\Manager::getSiteId(), //На текущем сайте
            'default_house' => 1 //Флаг по умолчанию включён
        ))
        ->object();
        
  //Получаем все комплектации
  $offers = $product['offers']; 
  
  //Эти строки показывают общую картину что подгрузили и как это выглядит. Комлектации находятся в ключе offers      
  echo "<pre>";
  var_dump('warehouse', $warehouse);
  var_dump('product', $offers);
  echo "</pre>"; 
  
  //Пробежимся по комплектациям и изменим количество, задав новые значения комплектациями
  $new_offers = array();
  foreach ($offers['items'] as $k=>$item){
     //Т.к. товар это объект \Catalog\Model\Orm\Product, то обращение к нему как к массиву происходит так, иначе Notice 
     $stock_num                   = $item['stock_num'];
     $stock_num[$warehouse['id']] = $stock_num[$warehouse['id']]+$plus_value;
    
     $item['stock_num'] = $stock_num;
     
     $new_offers[$k] = $item;
  }
  
  $product['offers'] = $new_offers;
  
  //Вызываем обновление у товара. В функции afterWrite класса \Catalog\Model\Orm\Product произойдёт обновление
  $product->update();

Получить значение из POST можно так к контроллере:

$this->request('product_id',TYPE_INTEGER,0); //Получение переменной из $_REQUEST, product_id где ожидается что это число.

Строка:

use \Product\Model\Orm\Product

Все го лишь отвечает за, то что вы можете вместо

\Product\Model\Orm\Product::loadByWhere();

Сделать так

Product::loadByWhere()

Т.е. использовать сокращённый alias

2,482

(3 ответов, оставленных в Вопросы по работе с системой)

семь бед - один reset)

Насколько я понял, нужно у нескольких товаров отобразить нужный нам лейбл. В данном случае это "Хит".
Это можно сделать так:
1. Товары присвоить спец. категории "Хит"(создав её).
2. У спец. категории "Хит" загрузить картинку(зависит от шаблона, см. ниже) и указать значение в поле "Псевдоним" если поле пустое, например нажав на кнопку со стрелками. Например записать значение "hit"(без ковычек).
3. Нужно отредактировать нужный Вам шаблон.
В шаблоне все сводится к тому, что в шаблоне у объекта товара нужно вызвать метод inDir, который проверяет принадлежит ли данный товар нужной категории.

{$product->inDir('Псевдоним категории')}

В нашем случае это:

{$product->inDir('hit')} //Проверяем принадлежит ли товар категории с псевдонимом - hit

Если например рассматривать тему оформления "fashion" , а именно шаблон

/templates/moduleview/catalog/list_products.tpl - список товаров

В нём есть строчка:

{if $product->inDir('new')}<i class="new"></i>{/if}

Т.е. если товар принадлежит категории с псевдонимом - new, то эта строка будет добавлена.
Если нам нужно добавить ещё и "Хит". То делаем так.

{if $product->inDir('new')}<i class="new"></i>{/if}
{if $product->inDir('hit')}<i class="hit"></i>{/if}

После чего можно добавить класс в style.css, который будет делать бэкграунд с картикой.

.products li .image .hit{
    position:absolute;
    width:102px;
    height:20px;
    top:9px;
    left:1px;
    background: url(../img/КАКАЯ-ТО КАРТИНКА ХИТА продаж) no-repeat;
}


Ну или просто дописать что это хит.

В начале я также упоминал о том, что и у категории можно указывать картинку. В случае описанном выше этого делать не нужно, т.к. браться картинка будет из css файла.
Чтобы это использовать в нашем шаблоне категорию надо предварительно подгрузить и проверять у неё наличие фото.

Вот как это может выглядеть:

{foreach from=$product->getMySpecDir() item=spec}
{if $spec.image}
    <img src="{$spec->__image->getUrl(62,62, 'xy')}">
{/if}
{/foreach}

Подсмотреть можно в теме по умолчанию в файле /modules/catalog/view/list_products.tpl

И далее правите вёрстку под Вашу тему по вкусу.

Дело в стилях. 100%.
Даже это видно из скриншотов. Стили, которые вы просто скопировали перемешались с уже существующими в системе стилями.
Для отображения фильтров в шаблона из которых вы переделываете используется jquery плагин formstyler, который как раз и стилизует все галочки, делая их <span> и отслеживает нажатие.
Проинспектируйте с помощью firefox и можете сами всё увидеть.
Что касается вашего случая(первая картинка). Вам надо эти галочки скрыть. Например поместив их в скрытый контейнер <div>. Т.к. цвет это обыкновенная ссылка, то вам надо будет просто отловить нажатие на эту ссылку с помощью javascript и затем вызывать у checkbox событие change. Например, если вы используете jquery, то это может выглядеть примерно так.

<script type="text/javascript">
  $(document).ready(function(){ //Когда DOM готов
       $(".block-colors a").on('click',function(){ //Нажатие на ссылку с цветами 
           var parent = $(this).closest('li'); //Обращаемся к лижайшему <li>, он будет родителем от которого искать детей
           var chk = $("input[type='checkbox']",parent); //получили нашу галку
           chk.prop('checked',!chk.prop('checked')); //Сменим состояние галки
           chk.change(); //Сгенерируем событие, что галка изменилась.
       });
  });
</script>

Примерно так.
Вообщем надо немного покопать. Если Вы не сможете самостоятельно выполнить, то лучше обратится к более сильному программисту, либо к нам в платную поддержку. Там небольшие и не долгие изменения.

Прошу прощения! Всё верно.

Я подправил первый пост. Сейчас правильно.
Отсутствовала запись:

use \RS\Orm\Type as OrmType;

После указания namespace

Ну что? Получается?

Ну тут скорее всего 2 вещи возможны на мой взгляд.
1. max_execution_time надо увеличить на сервере. Обычно это 30 секунд. Возможно просто у Вас сервер не успевает отработать за 30 секунд. Поставьте там ему минут 5 хотя бы.
2. Проверьте права на запись и владельца storage/tmp/siteupdate/backup. Она должна быть 755. Владелец файлов и папок - пользователь, от которого работает PHP. PHP должен работать как CGI.

Это сделано, чтобы отформатировать текст, т.к. он там приведён в чистом тексте и в таком случае учитываются все отступы. Плюс это позволяет на почтовых ящиках, которые режут стили, сохранить форматирование.
Т.е. чтобы у всех пользователей отображалось одинаково. У админа не важно, поэтому и сделали без pre с использованием тегов.

Вы можете при желании перекрыть шаблон письма, своим скопированным шаблоном и убрать тег <pre>

Например если у вас шаблон:

/modules/shop/view/notice/touser_checkout.tpl

заменить на:

/templates/ВАША ТЕМА/moduleview/shop/notice/touser_checkout.tpl

И всё

Sergey T. пишет:

А вы не могли бы поподробней описать в какую часть filters.tpl добавить или заменить ваш код? Я не очень силен в программировании.

Так я же в первом посте привёл код filters.tpl.

Смотрите туда где начинается.

{if $prop.title == 'Цвет'}

В фильтрах просто перебираются фильтры подготовленные от блок контроллера фильтров (/modules/catalog/controller/block/sidefilters.inc.php), и там где идёт список перебираются доступные характеристики.
Я в коде проверяю имя этой характеристики. Если это цвет, то тогда применяю код, который выводит эти блоки с задним фоном. Также обратите внимание на начало этого кода, а именно:

{*Подгружаем цвета*}
{modulegetvars name="\Colors\Controller\BlockValues" var="colors"}
{*Подгружаем цвета*}

Т.е. мы переменной $colors возвращаем массив из заполненных нами цветов в админке из блок контроллера \Colors\Controller\BlockValues.

Вывести значения этой переменной можно так:

<pre>
{var_dump($colors)}
</pre>

А дальше просто смотрите алгоритм.
Попробуйте, если что ещё подскажу.

Как добавить поле товару или любому другому объекту ORM(таблица в базе) в ReadyScript?

Иногда народ интересуется как быстро добавить поле к товару. Например нужна какая-либо дополнительная галочка, или ещё текстовое поле, или картинка для загрузки. В нашей системе всё просто.
Если у Вас есть модуль дополнительный свой можно сделать в нём дополнительные действия, но я буду рассматривать ситуацию когда дополнительного модуля у вас нет и Вы первый раз программируете для RS.
Всё просто.
Рассмотрим ситуацию, когда нам нужно добавить галочку в карточку товара.


Создаём свою папочку в modules с именем Вашего модуля на латинском языке. Например - custom.

Обратите внимание, что в Вашем классе namespace должен соответствовать имени папки в которой лежит. В нашем случае это custom.

Создаём внутри custom папку config. И добавляем в config файл file.inc.php .
Этот файл отвечает за конфигурацию Вашего модуля.
Вставляем туда следующее содержимое:

<?php
namespace Custom\Config;
use \RS\Orm\Type;

/**
* Конфигурационный файл модуля
*/
class File extends \RS\Orm\ConfigObject
{
    
      
}

И сохраняем его.
Теперь создаём файл со сведениями о модуле, которые отвечаю за имя и описание модуля. А именно файл с именем module.xml в той же папке. Вот его содержимое

<?xml version="1.0" encoding="utf-8"?>
<config>
    <defaultValues>    
        <name multilanguage="true">Имя Вашего дополнительного модуля</name>
        <description multilanguage="true">Модуль с дополнительным функционалом</description>        
        <version>1.0.0.0</version>
        <author>ВАШЕ авторские имя</author>        
    </defaultValues>
</config>

Далее в этой же папке config создаём другой файл с именем handlers.inc.php
Этот файл отвечает за добавление полей, навешивания на события, прописывания роутов и др. Подробнее листайте документацию для разработчиков.

Следующий шаг, это то что нам нужно в этом файле указать хук который будет перехвачен при инициализации объекта товара(строка записи из таблицы переводится в ORM объект).
Расширение объекта ORM(таблицы) товара производится через хуки.
Идём на страницу с описанием хуков системы. Читаем и спускаемся ниже к таблице где перечислены Все хуки системы.

В нашем случаем нам нужен хук:
orm.init.КОРОТКОЕ_ИМЯ_ORM_ОБЪЕКТА 

где КОРОТКОЕ_ИМЯ_ORM_ОБЪЕКТА будет равно catalog-product
Т.к. файл с ORM объектом у нас находится в

/modules/catalog/model/orm/product.inc.php

то короткое имя у нас будет:

catalog-product (название папки модуля на латинице-имя файла ORM объекта)

Полное же имя хука будет orm.init.catalog-product

Почему так? Поймёте из документации по хукам!

В файл handlers вставляем следующее содержимое, для добавления поля с именем is_root в таблицу БД:

<?php
namespace Custom\Config;
use \RS\Orm\Type as OrmType;

class Handlers extends \RS\Event\HandlerAbstract
{
    /**
    * Функция инициализирует регистрацию действий
    */
    function init()
    {
        $this->bind('orm.init.catalog-product'); //Сообщаем что у нас появился хук расширяющий товар
    }
    
    /**
    * Расширяем объект товара
    * Обратите внимание на название хука и этой функции . и - не используются 
    *
    * @param array $list
    */
    public static function ormInitCatalogProduct(\Catalog\Model\Orm\Product $orm_product)
    {
         //Расширяем поля
        $orm_product->getPropertyIterator()->append(array(
            t('Основные'), //Вкладка на которую будет добавлено поле, поля в массиве ниже будут приписаны к этой вкладке в конец
            'is_root' => new OrmType\Integer(array( //Название поля в таблице БД и его тип
                'description' => 'Корневой элемент?', //Подпись к полю
                 'maxLength' => 1, //Длинна поля
                'default' => 0, //Значение по умолчанию
                'CheckBoxView' => array(1,0) //Отвечает за отображение в качестве флага(галочки)
            ))
        ));
    }
}

Посмотреть какие ещё поля бывают и какие у них свойства можно загляну в любой другой ORM объект. Или посмотреть типы ORM объектов в папке:
/core/rs/orm/type
В массиве все методы у этих обхектов начинающиеся с setИмяМетода можно указать в массиве как 'ИмяМетода'
Например:

Почти у всех есть метод
setDescription, а в массиве параметров это будет просто

'description' => 'Корневой элемент?'

Т.е. приставка set убирается.
Доступные методы можно подсветить для себя в не олдскульном редакторе через конструкцию такого типа

new OrmType\Integer::set(ctrl+пробел) и Вам выпадет список из доступных параметров для типа Integer поля.

Собственно всё!

Теперь у нас появилось поле is_root у товара.
Осталось добавить это поле в таблицу. Можно это сделать через базу, но не нужно:)
Достаточно лишь в адмике зайти в Управление ->Настройки системы и нажать Исправить структуру БД(справа).
Всё, поле добавлено. Можно пользоваться.
В шаблонах это поле будет доступно например так:

Поле корневой элемент? - {$product.is_root}

Рассмотрим ещё варианты:

Строка

'is_root' => new OrmType\String(array(
       'description' => t('Строка'),
)),

Текст

'is_root' => new OrmType\Text(array(
       'description' => t('Текст'),
)),

Текст с редактором

'is_root' => new OrmType\RichText(array(
       'description' => t('Текст с редактором'),
       'maxLength' => 1000
)),

Число

'is_root' => new OrmType\Integer(array(
       'description' => t('Число'),
       'maxLength' => 11
)),

Картинка

'is_root' => new OrmType\Image(array(
       'maxLength' => '255',
       'max_file_size' => 10000000,
       'allow_file_types' => array('image/pjpeg', 'image/jpeg', 'image/png', 'image/gif'),
       'description' => 'Картинка',
)),

Файл

'is_root' => new OrmType\File(array(
       'description' => t('Файл'),
)),

Выпадающий список

Тут всё несколько сложнее. Нужно понять, что список можно получить 2-мя способами.
1. Из Апи системы. Т.е. вызывается метод, который получает массив значений . Ключи массива будут как значения, значения будут как значения.
Поумолчанию в системе все апи являются наследниками

\RS\Module\AbstractModel\TreeList или
\RS\Module\AbstractModel\EntityList

Автоматически в этих апи есть метод staticSelectList, который получает все нужные нам значения.

//Например, получение регионов доставки
'is_root' => new OrmType\Integer(array(
       'description' => t('Регион'),
       'list' => array(array('\Shop\Model\RegionApi','staticSelectList'))
)),

2. значения из прямо заданного списка:

//Например, получение регионов доставки
'is_root' => new OrmType\String(array(
       'description' => t('Регион'),
       'listFromArray' => array(
            0 => 'Вариант 1',
            'var2' => 'Вариант 2',
            'var3' => 'Вариант 3',
            //и т.д.
       )

)),

Пробуйте!

Читаем статью про темы оформления, чтобы понять как это работает Своя тема оформления

Здравствуйте, довольно часто встречаю в поддержке вопрос:
Как сделать, чтобы курсы валюты обновлялись автоматом на сайте?
На самом деле всё очень просто.
Вам надо создать в корне файл, например с именем:

update_course.php

И вставить туда следующее содержимое:

<?php
    require('setup.inc.php'); //Конфиг который активирует все функции

    $currency_api = new \Catalog\Model\CurrencyApi(); //API валют на сайте
    $currency_api->getCBRFCourseWithUpdate(false);
    echo "<p>OK</p>";

А далее добавьте этот скрипт в свой cron на сервере с желаемой частотой запроса адреса.

Или если вы используете мультисайтовость, то можно сделать так:

<?php
    require('setup.inc.php');//Конфиг который активирует все функции
    
    
    $request = new \RS\Http\Request(); //Класс работы с HTTP запросами
    $site_id = $request->get('site_id',TYPE_INTEGER,false); //Ждём в запросе GET параметр 'site_id' в котором укажем id сайта, если параметр не передан, то смотрится текущий по имени домена, за счёт значения по умолчанию (false)
    
    $currency_api = new \Catalog\Model\CurrencyApi(); //API валют на сайте
    $currency_api->getCBRFCourseWithUpdate($site_id);
    echo "<p>OK</p>";

А далее добавьте этот скрипт в свой cron на сервере с желаемой частотой запроса адреса и параметра. Например, через cron wget

Ну пока не планируется такого изменения.

Напишите заявку здесь. Мы рассмотрим.

Можно. Оставьте пожелание на вот этой странице подачи заявки на улучшение функционала

Адреса приписываются к каждому отдельному пользователю. Ну пока такой возможности нет. Мы обсудим эту проблему с коллегами. А пока можно только через таблицу _order_address

Инструкции конкретно для каждой оплаты нет, но есть общее руководство разработчика, а также материалы для создания собственного модуля, который Вам позволит это сделать. Ответили Вам в приватном сообщении. Сделаю лишь общую выдержку:
http://readyscript.ru/dev-manual/ - общее руководство разработчика.
http://readyscript.ru/text-blog/razraba … nyy-modul/ - разработка модулей
http://readyscript.ru/text-blog/Kak-pra … adyScript/ - расширение функционала
http://readyscript.ru/text-blog/block-c … adyscript/ - разработка блок контроллера (позволяет изучить общий принцип)

Ну код всё равно придётся смотреть.
Перво наперво надо обязательно ознакомится с хуками http://readyscript.ru/dev-manual/dev_hooks.html.
Вам нужен хук. payment.gettypes. Вот на него необходимо подвеситься для того, чтобы добавить свой способ оплаты.
В \shop\config\handlers.inc.php где в методе paymentGetTypes подключатся методы оплаты.
Вам надо используя хук добавить в массив классов оплаты свой класс с помощью paymentGetTypes.
Например так:

В вашем файле модуля \modules\ваша папка модуля\config\handlers.inc.php

Сделать так

<?php
namespace Ваше пространство имен\Config;

/**
* Класс предназначен для объявления событий, которые будет прослушивать данный модуль и обработчиков этих событий.
*/
class Handlers extends \RS\Event\HandlerAbstract
{
    function init()
    {
        $this
            ->bind('payment.gettypes');
    }

    public static function paymentGetTypes($list)
   {
      $list[] = new \Ваше пространство имен\Model\PaymentType\ВашКласс();
      return $list;
   }
}

А дальше уже добавить Ваш класс с внутренней обработкой. Скорее всего Вам лучше будет его переделать из класса Robokassa или Assist.

Файлы классов здесь:
\modules\shop\model\paymenttype\robokassa.inc.php

\modules\shop\model\paymenttype\assist.inc.php

2,498

(1 ответов, оставленных в Вопросы по работе с системой)

Ну посмотрите через firebug какой шрифт у вас совпал, или перебил текущий при включении режима правки и примените часть этого стиля.

2,499

(7 ответов, оставленных в Вопросы по работе с системой)

Добавили поддержку этой функции. Обновляйтесь, пожалуйста. После обновления идите в раздел "Каталог товаров". Справа вверху будет кнопка Импорт/Экспорт, выберите там "Импорт изображений из ZIP-архива".

Вячеслав пишет:
Александр пишет:

Вы можете адаптировать как этот модуль под себя, так и использовать стандартные многомерные комплектации с их скриптами. Например так. Выводить характеристики нужные вам. При клике Вы просто обрабатываете данные характеристики собирая значения (Например размер и цвет). Выпадающие списки в многомерных комплектациях вы скрываете. После выбора размеров, в выпадающих списках меняете значение в зависимости от того что выбрано. Например как это было недавно сделано вот здесь http://medpodium-ru.1gb.ru/catalog/bluzony/

Большое спасибо за ответ. С многомерными комплектациями я что-то протупил, с ними еще не разбирался.
PS: только не совсем понял как скрыть выпадающие списки.

Сделайте в стилях им display:none; Вот и всё.