Подскажите как правильно вытащить содержимое TV в плагин

у меня есть плагин который косит слова из контента ресурса, НО
хочу реализовать возможность добавления таких слов в TV поле в migx
а вопрос состоит в том как этот список слов вызвать в плагине
вот сам плагин

<?php
switch ($modx->event->name) {
        case 'OnDocPublished':
        if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
         $content = $resource->get('content');
$words = array('<p>word1</p>,<p>word2</p>,<p>word3</p>');
        $pattern = '/(?:' . join('|', $words) . ')/i';
        $content = preg_replace($pattern, '', $content);
        $resource->set('content', $content);
        $resource->save();
        break;
        
        case ' OnBeforeDocFormSave':
     if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
       $content = $resource->get('content');
$words = array('<p>word1</p>,<p>word2</p>,<p>word3</p>');
        $pattern = '/(?:' . join('|', $words) . ')/i';
        $content = preg_replace($pattern, '', $content);
        $resource->set('content', $content);

        $resource->save();
        break;
       
    case 'OnDocFormSave':
      if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
 $content = $resource->get('content');
$words = array('<p>word1</p>,<p>word2</p>,<p>word3</p>');
        $pattern = '/(?:' . join('|', $words) . ')/i';
        $content = preg_replace($pattern, '', $content);
        $resource->set('content', $content);
     
        $resource->save();
        break;
      
}
Евгений
22 мая 2023, 23:19
modx.pro
848
0

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

Dan
Dan
23 мая 2023, 19:29
+2
Вместо migx я бы посоветовал лучше использовать tvSuperSelect, чтобы не мучаться каждый раз открытием модалки и вбиванием слова. При этом, если у некоторых ресурсов могут быть одинаковые слова, то вы сможете их выбрать из списка уже имеющихся.
Код получения слов ресурса в виде массива будет такой:
$res = $modx->getObject('modResource', $resource->id);
$words = json_decode($res->getTVValue('words'), true); //в getTVValue название своего TV
    Евгений
    23 мая 2023, 23:28
    0
    tv я думаю вбить в одном ресурсе и к нему обращаться будет проще
      Евгений
      24 мая 2023, 11:29
      0
      а как обратиться к TV определенного ресурса ))))
      например у него id=11 и TV со словами будет в нем
        Dan
        Dan
        24 мая 2023, 14:08
        +1
        Код тот же самый, просто замените в 1ой строчке моего кода, $resource->id на id вашего ресурса
        $res = $modx->getObject('modResource', id_ресурса);
        $words = json_decode($res->getTVValue('words'), true);
      Константин Ильин
      24 мая 2023, 14:34
      +1
      Сам код тоже можно улучшить, я так понимаю у вас там одни и те же действия, можно как функцию сделать, а так же switch позволяет вот так:
      <?php
      switch ($modx->event->name) {
              case 'OnDocPublished':
              case 'OnBeforeDocFormSave':
              case 'OnDocFormSave':
                  if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
                  $res = $modx->getObject('modResource', id_ресурса_где_вбиты_слова);
                  $words = $res->getTVValue('words'); // тут получить слова, распарсить строку, смотря что там вернет.
                  // еще проще в php файл записать эти слова и подключать через include
                  
                  $content = $resource->get('content');
                  $pattern = '/(?:' . join('|', $words) . ')/i';
                  $content = preg_replace($pattern, '', $content);
                  
                  $resource->set('content', $content);
                  $resource->save();
              break;
                    
      }
        Евгений
        24 мая 2023, 15:37
        0
        создал тв поле migx добавил слова testx testy в tv и в поле контент

        <?php
        switch ($modx->event->name) {
                case 'OnDocPublished':
                case 'OnBeforeDocFormSave':
                case 'OnDocFormSave':
                    if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
                    $res = $modx->getObject('modResource', 11);
                    $words = $res->getTVValue('words'); // тут получить слова, распарсить строку, смотря что там вернет.
                   
                    $content = $resource->get('content');
                    $pattern = '/(?:' . join('|', $words) . ')/i';
                    $content = preg_replace($pattern, '', $content);
                    
                    $resource->set('content', $content);
                    $resource->save();
                break;
                      
        }
        но увы не подчищает
        может разделитель в параметрах вывода TV или чтото в коде не так? как найти причину непонятно
          Dan
          Dan
          24 мая 2023, 16:36
          0
          Потому что migx хранит в json. При этом, в migx у вас видимо всего одно поле для ввода слова, допустим его ключ word, тогда при декодировании вы получите не массив слов, а массив элементов этого migx, т.е. двумерный массив.
          Значит вам нужно будет еще пробежаться по нему и получить все слова.
          $words = array();
          $res = $modx->getObject('modResource', 11);
          $temp = json_decode($res->getTVValue('words'), true);
          foreach ($temp as $v) {
              if (!in_array($v['word'], $words)) { //$v['word'] - тут нужно указать ключ вашего поля для слова
                  array_push($words, $v['word']); //тут тоже соответственно
              }
          }
          //после цикла вы получите массив введенных слов. Поэтому я и предлагал tvSuperSelect, с ним было бы проще, без лишнего цикла и вводить в него проще.
          Т.
            Евгений
            24 мая 2023, 16:42
            0
            /core/components/gallery/elements/tv/output/ выдает такую ошибку при сохранении с этой строкой
              Dan
              Dan
              24 мая 2023, 16:45
              0
              Дописал код в комменте. Честно, не понимаю причем тут gallery
                Евгений
                24 мая 2023, 19:10
                0
                тоже не понял но там и на другие снипеты орал
              Евгений
              24 мая 2023, 19:14
              0
              с tvsuperselct вид тв поля какой нужен
                Dan
                Dan
                24 мая 2023, 19:16
                +1
                Как установите его, в списке тв полей появится tvsuperselect
              Евгений
              24 мая 2023, 22:09
              0
              tvsuperselect
              и такой код
              <?php
              switch ($modx->event->name) {
                      case 'OnDocPublished':
                      case 'OnBeforeDocFormSave':
                      case 'OnDocFormSave':
                          if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
                          $res = $modx->getObject('modResource', 11);
                          $words = $res->getTVValue('words'); // тут получить слова, распарсить строку, смотря что там вернет.
                         
                          $content = $resource->get('content');
                          $pattern = '/(?:' . join('|', $words) . ')/i';
                          $content = preg_replace($pattern, '', $content);
                          
                          $resource->set('content', $content);
                          $resource->save();
                      break;
                            
              }
              не удаляет слова указанные в tv words
                Dan
                Dan
                25 мая 2023, 05:15
                0
                Ну вы хоть почитайте мой комментарий, я же в самом первом написал код, а вы снова по своему получаете, вот и не работает. tvSuperSelect тоже хранит json
                  Евгений
                  25 мая 2023, 09:25
                  0
                  <?php
                  switch ($modx->event->name) {
                          case 'OnDocPublished':
                          case 'OnBeforeDocFormSave':
                          case 'OnDocFormSave':
                              if ($resource->get('template') == 24 && !$resource->get('content')) $resource->set('published', 0);
                  $res = $modx->getObject('modResource', 11);
                  $words = json_decode($res->getTVValue('words'), true);
                             
                              $content = $resource->get('content');
                              $pattern = '/(?:' . join('|', $words) . ')/i';
                              $content = preg_replace($pattern, '', $content);
                              
                              $resource->set('content', $content);
                              $resource->save();
                          break;
                                
                  }
                  когда делаю так получаю ошибку при сохранении… которую выше писал но на снипет colorpicker
                    Dan
                    Dan
                    25 мая 2023, 09:31
                    0
                    При сохранении ресурса имеете в виду? Просто зависает? Тогда скорее другой плагин что-то ломает. Надо смотреть логи, так сложно сказать.
                      Евгений
                      25 мая 2023, 09:38
                      0
                      да, при сохранении выскакивает ошибка, но зависания нет, просто продолжаешь работать а сохранить не можешь :)

                      при этом для всех шаблонов хотя там в условиях указан конкретный
                      лог ошибок пуст
                      старый код плагина где я слова перечислял через запятую не вызывает проблем
                        Dan
                        Dan
                        25 мая 2023, 09:42
                        0
                        Вы лог модх смотрите? Надо серверный, ибо ошибка 100% с кодом 5хх, скорее 500.
                          Евгений
                          25 мая 2023, 09:48
                          0
                          ошибка выбивается сразу как я добавляю строку
                          $words = json_decode($res->getTVValue('words'), true);

                          а при такой $words = $res->getTVValue('words');
                          ее нет

                          в серверных логах ошибок нет
                            Dan
                            Dan
                            25 мая 2023, 10:07
                            0
                            А у вас поле точно типа tvSuperSelect? Странно конечно. Если не разберитесь, можете мне в тг или в сообщения написать, смогу сегодня в обеду глянуть
                            Евгений
                            25 мая 2023, 10:29
                            0
                            да, именно tvSuperSelect
                            Константин Ильин
                            25 мая 2023, 11:16
                            0
                            в вашем исходном коде, в название события есть пробел в начале, оно раньше не запускалось.
                            case ' OnBeforeDocFormSave':
                            так же строчка $words = $res->getTVValue('words'); может вернуть уже готовый массив и не надо его вытаскивать из json, как я ранее писал надо смотреть что там возвращает. Вот так:
                            $words = $res->getTVValue('words');
                            $modx->log(1, print_r($words,1));
                            Потом смотреть в журнале ошибок модх
                            Евгений
                            25 мая 2023, 11:36
                            0
                            <?php
                            switch ($modx->event->name) {
                                    case 'OnDocPublished':
                                    case 'OnBeforeDocFormSave':
                                    case 'OnDocFormSave':
                                        if ($resource->get('template') == 27 && !$resource->get('content')) $resource->set('published', 0);
                            $res = $modx->getObject('modResource', 11);
                            $words = $res->getTVValue('words');
                            $modx->log(1, print_r($words,1));
                                       
                                        $content = $resource->get('content');
                                        $pattern = '/(?:' . join('|', $words) . ')/i';
                                        $content = preg_replace($pattern, '', $content);
                                        
                                        $resource->set('content', $content);
                                        $resource->save();
                                    break;
                                          
                            }
                            вот так выводит, надо по и дее без ковычек и в ...
                            ["testx","testy"]

                            ну и само собой слова не чистятся
                            на coloricker плагин ругался я его отключил

                            [2023-05-25 11:39:37] (ERROR @ /var/www/www-root/data/www/.ru/core/cache/includes/elements/modplugin/59.include.cache.php: 9) [«testx»,«testy»]
                            [2023-05-25 11:39:37] (ERROR @ /var/www/www-root/data/www/.ru/core/cache/includes/elements/modplugin/59.include.cache.php: 12) PHP warning: join(): Invalid arguments passed

                            12 строка — $pattern = '/(?:'. join('|', $words). ')/i';
                            Евгений
                            25 мая 2023, 12:47
                            0
                            рабочий плагин строка в нем выглядит так если слова руками вписывать
                            $words = array('word1,word2`)
                            Dan
                            Dan
                            25 мая 2023, 13:38
                            0
                            Я у себя протестил, такой код норм чистит. Вы после сохранения страницу ресурса обновите в админке и увидите, что слова удалились из контента.
                            <?php
                            switch ($modx->event->name) {
                                    case 'OnDocPublished':
                                    case 'OnBeforeDocFormSave':
                                    case 'OnDocFormSave':
                                    $res = $modx->getObject('modResource', 1);
                                    $words = json_decode($res->getTVValue('words'), true);
                                       
                                    $content = $resource->get('content');
                                    $pattern = '/(?:' . join('|', $words) . ')/i';
                                    $content = preg_replace($pattern, '', $content);
                                    
                                    $resource->set('content', $content);
                                    $resource->save();
                                    break;
                                          
                            }
                            Евгений
                            25 мая 2023, 14:16
                            0
                            вывод через разделитель или по умолчанию?
                            Dan
                            Dan
                            25 мая 2023, 14:18
                            0
                            Вывод чего? В контенте ресурса у меня просто рандомный набор слов и слова из words плагин удаляет внутри контента.
                  Евгений
                  28 мая 2023, 10:17
                  0
                  у него есть какой то глюк или ограничение на слова и они просто обнуляются
          Евгений
          24 мая 2023, 21:40
          0
          а как сделать так чтобы он удалял именно конструкцию word1 а не просто word?
            Евгений
            28 мая 2023, 14:23
            0
            подскажите как сделать чтобы брало не только из одного TV а из двух или трех?
            точнее не как брать а как в коде плагина прописать так чтобы исключало сразу слова из 2 или 3 TV?

            сейчас это
            $words = json_decode($res->getTVValue('words'), true);         
            $pattern = '/(?:' . join('|', $words) . ')/i';
            как я понимаю можно
            1 сделать переменную words2
            а в строке pattern добавить его в исключение (не знаю только как )

            2 добавить сразу данные из TV поля words2 в переменную words
              Vladimir
              28 мая 2023, 15:04
              0
              Так
              $words = json_decode($res->getTVValue('words'), true);   
              $words2 = json_decode($res->getTVValue('words2'), true);
              
              $words3 = json_decode($res->getTVValue('words3'), true);   
              $words4 = json_decode($res->getTVValue('words4'), true);   
              
              $wordsToExclude = array_unique(array_merge($words, $words2, $words3, $words4));
              
              $pattern = '/(?:' . join('|', $wordsToExclude) . ')/i';
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            32