• Блог
  • Метод xPDOObject::fromArray()
Этот метод разработчики MODX часто используют для присвоения значений объекту. Формируете массив с новыми значениями, а затем одной строчкой передаете значения объекту. Давайте посмотрим на его определение.
fromArray(
   array $assocArray,
   [string $keyPrefix = ''],
   [boolean $setPrimaryKeys = false],
   [boolean $rawValues = false],
   [boolean $adhocValues = false]
)

Пример создания нового ресурса с присвоением ему значений.

$fields = array(
    'pagetitle' => 'Новый ресурс',
    'alias' => 'new_page',
    'published' => '1',
    'hidemenu' => '0',
    'introtext' => 'Этот ресурс создан программно.',
)
 
$resource = $modx->newObject('modResource');
$resource->fromArray($fields);
$resource->save();

Тут нужно отметить, что метод fromArray() присваивает значение для каждого поля объекта через метод set(), т.е. значение преобразуется согласно модели. Например, даты переводятся в UNIX timestamp формат, массивы в JSON формат, пароли хешируются и т.д. Но что, если нужно присвоить именно переданное значение без его обработки? Можно, конечно, сделать отдельное присвоение такому полю

$resource->field = 'Значение, которое не нужно конвертить';

Но в методе fromArray() есть параметр, который отключает конвертирование значений — $rawValues. Достаточно указать true, и данные перенесутся без изменений.

Еще один момент, с которым я столкнулся при работе с этим методом — передача первичных ключей. В чём проблема? Если вы передаёте первичный ключ в массиве значений, то он не присвоится. Это проблема обычно возникает при работе с пользовательскими объектами. Пример такого кода

$fields = array(
    'country' => 'Russia', /* Первичный ключ */
    'city' => 'Moscow', /* Первичный ключ */
    'population' => '12000000',
)
 
$city->fromArray($fields);
$city->save();
// Значения county и city не сохранятся (будут пустые).

Эта проблема решается параметром $setPrimaryKeys. Т.е. вызывать нужно так

$fields = array(
    'country' => 'Russia', /* Первичный ключ */
    'city' => 'Moscow', /* Первичный ключ */
    'population' => '12000000',
)
 
$city->fromArray($fields,'',true);
$city->save();

Ну и давайте пробежимся по оставшимся параметрам метода:

  • $prefix — вырезает указанную строку (префикс) из ключей массива.
  • $adhocValues — если «true», то для несуществующих полей у объекта создаются свойства с именами таких ключей. Используется редко. Я не видел его применения.
  • 20 декабря 2015, 09:38   1076     7

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

    1. Мишан 10 января 2017, 16:33 # 0
      А такой вопрос: А как опубликовать не один ресурс, а сразу несколько десятков или сотен?

      Допустим мы спарсили какую то информацию с сайта раскидали её по массивам. И как нам теперь эти массивы сохранить в ресурсы modx?

      Например у нас много много много вот таких массивов:
      Array
      (
          [pagetitle] => 
      CLINIQUE Набор Happy For men
          [longtitle] => 
      CLINIQUE Набор Happy For men
          [description] => 
      CLINIQUE Набор Happy For men
          [introtext] => 
      CLINIQUE Набор Happy For men
          [content] => Содержимое тестовой страницы
          [alias] => new-page
          [template] => 1
          [published] => 1
          [parent] => 0
      )
      Array
      (
          [pagetitle] => 
      ADIDAS Подарочный набор Champion League III Arena Edition
          [longtitle] => 
      ADIDAS Подарочный набор Champion League III Arena Edition
          [description] => 
      ADIDAS Подарочный набор Champion League III Arena Edition
          [introtext] => 
      ADIDAS Подарочный набор Champion League III Arena Edition
          [content] => Содержимое тестовой страницы
          [alias] => new-page
          [template] => 1
          [published] => 1
          [parent] => 0
      )
      Array
      (
          [pagetitle] => 
      BVLGARI Подарочный набор Man In Black
          [longtitle] => 
      BVLGARI Подарочный набор Man In Black
          [description] => 
      BVLGARI Подарочный набор Man In Black
          [introtext] => 
      BVLGARI Подарочный набор Man In Black
          [content] => Содержимое тестовой страницы
          [alias] => new-page
          [template] => 1
          [published] => 1
          [parent] => 0
      )
      1. Сергей Шлоков 10 января 2017, 17:22 # 0
        В вашем случае лучше использовать процессор создания ресурса. Организовываете цикл и для каждого массива вызываете процессор:
        //$array - массив с данными ресурса
        $response = $modx->runProcessor('resource/create', $array);
        if ($response->isError()) {
            return $modx->error->failure($response->getMessage());
        }
        
        1. Мишан 10 января 2017, 18:28 # 0
          Так я пробывал не работает почему то.

          <?php
          header('Content-type: text/html; charset-utf-8');
            require ('phpQuery-onefile.php');
            
            function get_content($url) {
              $ch = curl_init($url);
              curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
              curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
              $res = curl_exec($ch);
              return $res;
            }
            $object = $modx->newObject('modResource');
            function parser ($url, $start, $end) {
              if ($start < $end) {
          
                  $file = get_content($url);
                  $doc = phpQuery::newDocument($file);
                  
                  foreach ($doc->find('.productItem') as $article ) {
                      $article = pq($article);
                      $titl = $article->find('.h3-like.title a')->text();
                     
                      $resurs = array(
                          'pagetitle' => $titl,
                          'longtitle' => $titl,
                          'description' => $titl,
                          'introtext' => $titl,
                          'content' => 'Содержимое тестовой страницы',
                          'alias' => 'new-page',
                          'template' => 1,
                      	'published' => 1,
                      	'parent' => 0
                      );
                      
                     
                      $response = $modx->runProcessor('resource/create', $resurs);
                      if ($response->isError()) {
                          return $modx->error->failure($response->getMessage());
                      }
                      
                      echo '<pre>';
                      print_r ($resurs);
                      echo '</pre>';
          
                  }
                  
                  /* Шагаем по страницам */
                  $next = $doc->find('.pagination li.active')->next()->find('a')->attr('href');
                  if ( !empty($next)){
                      $start++;
                      parser($url, $start, $end);
                  }
          
              }
              
          
            }
            
            
            $url = 'https://www.letu.ru/idei-dlya-podarka/podarki-dlya-nego';
            $start = 0;
            $end = 1;
            parser($url, $start, $end);
          1. Сергей Шлоков 10 января 2017, 20:26 # 0
            Alias должен быть уникальным.
            1. Мишан 10 января 2017, 20:49 # 0
              здесь не в алиасе дело, а вчём не знаю…
              Даже если сделать вот так:
              <?php
              header('Content-type: text/html; charset-utf-8');
                require ('phpQuery-onefile.php');
                
                function get_content($url) {
                  $ch = curl_init($url);
                  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                  $res = curl_exec($ch);
                  return $res;
                }
                $object = $modx->newObject('modResource');
                function parser ($url, $start, $end) {
                  if ($start < $end) {
              
                      $file = get_content($url);
                      $doc = phpQuery::newDocument($file);
                      
                      foreach ($doc->find('.productItem') as $article ) {
                          $article = pq($article);
                          $titl = $article->find('.h3-like.title a')->text();
                         
                          $resurs = array(
                              'pagetitle' => $titl,
                              'longtitle' => $titl,
                              'description' => $titl,
                              'introtext' => $titl,
                              'content' => 'Содержимое тестовой страницы',
                              'alias' => trim($titl),
                              'template' => 1,
                          	'published' => 1,
                          	'parent' => 0
                          );
                          
                          $response = $modx->runProcessor('resource/create', $resurs);
                          if ($response->isError()) {
                              return $modx->error->failure($response->getMessage());
                          }
                          
                         
                          echo '<pre>';
                          print_r ($resurs);
                          echo '</pre>';
              
                      }
                      
                      /* Шагаем по страницам */
                      $next = $doc->find('.pagination li.active')->next()->find('a')->attr('href');
                      if ( !empty($next)){
                          $start++;
                          parser($url, $start, $end);
                      }
              
                  }
                  
              
                }
                
                
                $url = 'https://www.letu.ru/idei-dlya-podarka/podarki-dlya-nego';
                $start = 0;
                $end = 1;
                parser($url, $start, $end);
              Функция перестаёт работать если добавить:
              $response = $modx->runProcessor('resource/create', $resurs);
                          if ($response->isError()) {
                              return $modx->error->failure($response->getMessage());
                          }
              1. Сергей Шлоков 10 января 2017, 22:40 # 0
                Попробуйте заменить
                return $modx->error->failure($response->getMessage());
                на
                echo $response->getMessage();
                1. Мишан 11 января 2017, 09:14 # 0
                  походу дело в:
                  $response = $modx->runProcessor('resource/create', $resurs);
                  Без него работает с ним нет.
                  :w

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

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