• Блог
  • Метод 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», то для несуществующих полей у объекта создаются свойства с именами таких ключей. Используется редко. Я не видел его применения.
0   3463

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

  1. Мишан 10 января 2017 # 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 # 0
      В вашем случае лучше использовать процессор создания ресурса. Организовываете цикл и для каждого массива вызываете процессор:
      //$array - массив с данными ресурса
      $response = $modx->runProcessor('resource/create', $array);
      if ($response->isError()) {
          return $modx->error->failure($response->getMessage());
      }
      
      1. Мишан 10 января 2017 # 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 # 0
          Alias должен быть уникальным.
          1. Мишан 10 января 2017 # 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 # 0
              Попробуйте заменить
              return $modx->error->failure($response->getMessage());
              на
              echo $response->getMessage();
              1. Мишан 11 января 2017 # 0
                походу дело в:
                $response = $modx->runProcessor('resource/create', $resurs);
                Без него работает с ним нет.
                :w

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

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