Основной причиной выпуска этой версии было исправление бага с количеством отправителей почтового сообщения класса Mailer. А чтобы два раза не вставать, добавлен ещё и функционал для работы со строками. Для этого добавлено 2 функции — string() и str_concat().

string()

Данная функция позволяет выполнять манипуляции со строкой цепочкой методов.

$string = string('Some String')
                               ->toLower()                 // some string
                               ->replaceAll(' ', '_')      // some_string
                               ->replace('some', 'new')    // new_string
                               ->first(4)                  // new_
                               ->sha1(10)                  // cdabae2ca0
                               ->undo()                    // Some String
                               ->wrap('<div>','</div>')    // <div>Some String</div>
                               ->erase(0, 5)               // Some String</div>
                               ->length();                 // 17
							
echo $string->origin(); // Some String
echo $string;           // Some String</div>

Используемые методы можно посмотреть в документации (чуть позже) или непосредственно в классе.

str_concat()

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

$dolar = 'dolar';
str_concat('Lorem', ' ipsum ', $dolar);  // Lorem ipsum dolar
16 апреля 2018, 14:13   562     15

Комментарии ()

  1. Семён 23 апреля 2018, 20:26 # 0
    Сегодня заметил странную штуку, пытался обновить все превью товаров через консольный скрипт и из документации miniShop2 и при запуске постоянно получаю ошибку парсинга в modHelpers в файле functions.php
    Сначала вообще не понял причём тут мой файлик в корне сайта и modHelpers, а потом вспомнил, что функционал компонента доступен везде, а значит инициализируется где-то очень рано и может что-то переопределяет важное, ошибки в самом файле функий не нашёл, Сергей, может Вы подскажете в чём может быть причина?
    Удаляю компонент, всё прекрасно работает, ставлю заново, снова ошибка и только при запуске скриптов из консоли сервера.
    1. Сергей Шлоков 23 апреля 2018, 21:12 # 0
      Удалять не обязательно. Достаточно отключить плагин.

      А что за скрипт и в какой строке ошибка? Скорее всего в скрипте определяется одноимённая функция.
      1. Семён 23 апреля 2018, 21:20 # 0
        Вот сам скрипт
        <?php
        define('MODX_API_MODE', true);
        require 'index.php'; // Этот файл лежит в корне сайта
        
        $modx->getService('error','error.modError');
        $modx->setLogLevel(modX::LOG_LEVEL_ERROR);
        $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
        
        // Проходимся по всем товарам
        $products = $modx->getIterator('msProduct', array('class_key' => 'msProduct'));
        foreach ($products as $product) {
            // Получаем оригиналы их картинок
            $files = $product->getMany('Files', array('parent' => 0));
            foreach ($files as $file) {
                // Затем получаем их преью
                $children = $file->getMany('Children');
                foreach ($children as $child) {
                    // Удаляем эти превью, вместе с файлами
                    $child->remove();
                }
                // И генерируем новые
                $file->generateThumbnails();
        
                // Если это первый файл в галерее - обновляем ссылку на превью товара
                /** @var msProductData $data */
                if ($file->get('rank') == 0 && $data = $product->getOne('Data')) {
                    $thumb = $file->getFirstThumbnail();
                    $data->set('thumb', $thumb['url']);
                    $data->save();
                }
            }
        }
        
        echo microtime(true) - $modx->startTime;
        
        Ошибка возникает в строке 349, ну по крайней мере так в консоли написано
        1. Сергей Шлоков 23 апреля 2018, 21:36 # 0
          Вроде всё нормально. Наверно придётся дебажить — поочерёдно комментировать куски кода и проверять.
    2. d.proallex 03 мая 2018, 08:51 # 0
      Подскажите, как использовать функцию set() для коллекции пользователей users() :s
      users()->profile()->where(['Profile.blocked'=>1])->set('phone',777)->save(); 
      
      users()->profile()->where(['Profile.blocked'=>1])	  
      	->each(function($user, $idx) {
           user($user['id'])->profile()->set('phone',777)->save();
             });
      Ничего не работает.
      1. Сергей Шлоков 03 мая 2018, 09:18 # 0
        Насколько я понимаю, вы относитесь к той группе людей, которые считают, что инструкции написаны для совсем бестолковых. Не читайте всю документацию. Прочтите хотя бы только про метод set(). Это первое.
        Второе. Метод set() апдейтит таблицу users. Так как именно она является первой в цепочке. И не совсем понятно, зачем использовать её в качестве посредника. Запрашивайте сразу профиль
        collection('modUserProfile')->where(['blocked'=>1])->set('phone',777);
        
        П.С. Имейте ввиду, что в целях оптимизации запросы ограничены 100 записями. Чтобы убрать это ограничение, нужно добавить метод limit(0). В следующей версии я скорее всего оберу это ограничение.
        1. d.proallex 03 мая 2018, 09:34 # 0
          За ссылку спасибо. В поиске её не найти. Остальное прочитано, только всё равно ровным счетом ничего не происходит. Вариантов перепробовано уже много в том числе и этот, поэтому и решил спросить.
          1. Сергей Шлоков 03 мая 2018, 09:46 # 0
            Ссылка на менеджер коллекции есть на каждой странице документации. А то и не одна.

            В предыдущем комментарии после копипаста забыл исправить ваш вызов метода set(). Прочитайте сами, какие параметры он принимает.
            1. d.proallex 03 мая 2018, 10:01 # 0
              Так работает
              collection('modUserProfile')->where(['blocked'=>1])->set(['phone'=>777]);
          2. d.proallex 03 мая 2018, 10:59 # 0
            А как можно заставить set() работать с полями профиля в конструкции с users()?
            1. Сергей Шлоков 03 мая 2018, 18:07 # 0
              Ну попробуйте же почитать документацию.
              1. d.proallex 03 мая 2018, 19:17 # 0
                Почему вы считаете, что я её не читал? Почему не приходит в голову, что она просто непонятна? Я изначально спрашивал «как использовать функцию set() для коллекции пользователей users()» потому-что «не понятно», и получил ответы про то, что не спрашивал.
                Исходя из того, что есть в документации должно быть
                users()->profile()->where(['Profile.blocked'=>1])	  
                	->each(function($user, $idx) {
                     user()->set(['phone'=>777]);
                       });
                но нет
                ->set(['Profile.phone'=>777]);
                тоже ничего не дает.
                В обычном плагине давно бы написал
                $profile->set('phone',777);
                и закончил бы на этом.
                1. Сергей Шлоков 03 мая 2018, 19:33 # 0
                  Почему вы считаете, что я её не читал?
                  Ну потому, что если бы это было так, то в описании метода set() Вы бы увидели пример для ресурсов
                  // Обновляем pagetitle у дочерних элементов категории 10.
                  return resources()
                              ->where(['id:IN'=>children(10)])
                              ->set(function($object, $modx) { 
                                      if ($object->pagetitle == 'Первый документ') return false; // пропускаем итерацию
                                      $object->pagetitle = $object->pagetitle . ' new'; // изменяем заголовок
                                  });
                  
                  и сделали по аналогии для пользователей
                  users()->profile()->where(['Profile.blocked'=>1])->set(function($user, $modx) { 
                       $user->Profile->set('phone', 777);
                  });
                  
                  Но данная конструкция не оптимальна. Вы делаете запрос по таблице пользователей, затем джойните с таблицей профилей, ограничиваете по таблице профилей, а потом пытаетесь обновить таблицу профилей. Т.е. зачитываете таблицу пользователей, а работаете только с таблицей профилей. Вопрос — зачем в этой конструкции нужна таблица пользователей? Именно на это я обратил Ваше внимание. Если Вас не устраивает моё замечание, просто проигнорируйте его и делайте как считаете нужным.
                  1. d.proallex 03 мая 2018, 21:58 # 0
                    Спасибо. Я использую users(), потому что это не весь сниппет, а малая его часть и именно с профилем в нем возник вопрос. Я не сомневаюсь, что если нужна работа только внутри профилей лучше использовать
                    collection('modUserProfile')
                    и ваше пояснение было познавательным и кому-то будет полезным.
                    ps я даже сейчас, смотря на пример для ресурсов и на решение, аналогию прослеживаю с трудом. Очень по разному видимо мозг устроен. Спасибо еще раз.
                  2. Сергей Шлоков 03 мая 2018, 19:37 # 0
                    но нет
                    ->set(['Profile.phone'=>777]);
                    тоже ничего не дает.
                    Я выше объяснил, почему это не работает. Функция users() работает с таблицей пользователей, а у неё нет поля phone.

          Вы должны авторизоваться, чтобы оставлять комментарии.

          Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.