xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Как программно добавить к ноде картинку

Пример добавления к ноде 123 картинки path/to/file/example.jpg (после добавления она будет доступна по адресу sites/default/files/images/example.jpg):

$file_path = drupal_realpath('path/to/file/example.jpg');
 
$file = (object)array(
  'uid' => 1,
  'uri' => $file_path,
  'filename' => basename($file_path),
  'filemime' => file_get_mimetype($file_path),
);
 
$file = file_copy($file, 'public://images');
 
if ($file) {
  $node = node_load(123);
  $node->field_image[LANGUAGE_NONE][] = (array)$file;
  node_save($node);
}
Написанное актуально для Drupal 7
Похожие записи

Комментарии RSS

Неделю назад, потратил около половины дня на решение этой задачи =) только я это сделал в presave =)

а как удалить картинку из ноды ?
записать в $node->field_image[$node->language][] пустой массив ?

unset($node->field_image[язык]);

Благодарю! То, что нужно.

Для термов изменятся только функции load и save:

if ($file) {
  $term = taxonomy_term_load(123);
  $term->field_image[LANGUAGE_NONE][] = (array)$file;
  taxonomy_term_save($term);
}

Подозреваю, что для всех сущностей (entities) механизм будет похожим.

А как программно добавить фото в поле профиля пользователя при регистрации в хуке user_insert()?

точно так же

Это актуально только для 7 друпала.

А как быть с 6?
Там есть file_copy, но она не работает с объектами-файлами, а только с путями к объекту (и не возвращает объект-файл, а тру или фэлс, как php-шная copy). А вот file_save вообще нет.
И непонятно, как правильно загрузить файл. Потому что при программном создании ноды (через node_save) для поля-картинки требуется fid, уникальный ключ файла. А как вот это сделать непонятно, уже сутки голову ломаю :(
Можно ставить рандомный fid, но это же ужас.

Вот что то не получается. Картинка вставляется в базу, но в ноде не видна.
P.S. это скрипт переливания контента из joomla k2 компонент создаёт в md5 имя картинки

function addNode($node){
	$time = time();
	print $node->title.$node->id;
	$new_node = new StdClass();
	$new_node->type = 'product';
	$new_node->title = $node->title;
	$new_node->status = 1;
	$new_node->promote = 0;
	$new_node->comment = 0;
	$new_node->sticky = 0;
	$new_node->created = $time;
	$new_node->changed = $time;
	$new_node->body['und']['0']['value'] = $node->introtext;
	$new_node->body['und']['0']['format'] = 'full_html';
	$new_node->uid = 1;
	$new_node->language = 'und';
	$new_node->field_category['und']['0']['tid'] = 1;
	$img = md5('Image'.$node->id).'.jpg';
	$imageurl = 'public://product/'.$img;
	$oldimgurl = 'http://dev.essa.by/sites/default/files/product'.$img;
	//$imgsize = filesize($oldimgurl);
//print $imgsize;
	$fid = db_insert('file_managed')->fields(array(
 'uid' => 1, // ID пользователя, добавившего файл
 'filename' => $img, // оригинальное имя файла
 'uri' => $imageurl, // путь к файлу относительно папки sites/default/files
 'filemime' => 'image/jpeg', // MIME тип файла
 'filesize' => 11111, // Размер файла в байтах, можно определить через функцию filesize(полный_путь_к_файлу);
 'status' => 1, // 1 - Файл постоянный, 0 - временный (при запуске крона будет удален)
 'timestamp' => $time, // Таймштамп времени, когда файл был добавлен
))->execute();
print('<br> file='.$fid.'<br>');
$node->field_image['und'][0]['fid'] = 26;
$node->field_image['und'][0]['alt'] = $node->title;
$node->field_image['und'][0]['title'] = $node->title;
node_save($new_node);	
$newnid = $new_node->nid;}

Спасибо этому сайту за прекрасный "firebug"!
Я бы наверное ещё провозился бы 4 часа если бы не увидел в собственном комментарии глупую ошибку.
Даже не буду раскрывать фишку. Сами ищите!
Всего то не в тот объект (намёк).
Код приведенный выше 100% рабочий (если конечно ошибку исправите).
А я пошел чистить БД после 10-ков неудачных запусков этой функции =)
Успехов всем!

а как программно добавить поле для загрузки картинки?

А если картинку залить через FTP, местоположение, например, такое: "public://images/image.jpg" . Как на неё сослаться?

Вам нужно добавить её в таблицу файлов, что бы прикрепить к ноде. Это и описано в коде. Поле добавляется в форме при помощи FAPI. А разве это не есть ссылка public://images/image.jpg - разве что посмотрите таблицы файлов Drupal как там пути прописаны.

function addNodes(){
$node_body = 'Текст материала.';
$n = new stdClass();
$n->title = 'Заголовок ноды22222';
$n->body['und'][0]['format'] = 'filtered_html'; // формат ввода, разумеется машинное имя
$n->body['und'][0]['value'] = $node_body; // передаем содержимое
$n->type = 'article'; // тип материала: статья
$n->promote = 1; // помещать на главную страницу: да
$n->uid = 1; // ID пользователя, якобы создавшего ноду
$n->status = 1; // тут же опубликовать
$n->comment = 0; // разрешить комментировать статью
$n->language = 'ru'; // язык: русский

$file_path = 'images/2.jpg' ;
$fid = db_insert('file_managed')->fields(array(
'uid' => 1,
'filename' => '2.jpg',
'uri' => 'public://'.$file_path,
'filemime' => 'image/jpeg',
'filesize' => 59153,
'status' => 1,
'timestamp' => time(),
))->execute();
print $fid;
$n->field_image['und'][0]['fid'] = $fid;
node_save($n);
}
код работает но
пути к картинке такие

и

по этих адресах картинок нет (
как сделать что бы загружал уменьшенную копию ????

<code>function  addNodes(){
     $node_body = '<p>Текст материала.</p>'; 
   $n = new stdClass();
     $n->title = 'Заголовок ноды22222';
     $n->body['und'][0]['format'] = 'filtered_html'; // формат ввода, разумеется машинное имя
     $n->body['und'][0]['value'] = $node_body; // передаем содержимое
     $n->type = 'article'; // тип материала: статья
     $n->promote = 1; // помещать на главную страницу: да
     $n->uid = 1; // ID пользователя, якобы создавшего ноду
     $n->status = 1; // тут же опубликовать
     $n->comment = 0; // разрешить комментировать статью
     $n->language = 'ru'; // язык: русский
 
     $file_path =  'images/2.jpg' ;
         $fid = db_insert('file_managed')->fields(array(
		'uid' => 1,
		'filename' => '2.jpg',
		'uri' => 'public://'.$file_path,
		'filemime' => 'image/jpeg',
		'filesize' => 59153,
		'status' => 1,
		'timestamp' => time(),
	))->execute();
         print $fid;
          $n->field_image['und'][0]['fid'] = $fid;
    node_save($n);  
 }
код работает но 
пути к картинке такие
  src="http://drupal/?q=sites/default/files/styles/medium/public/images/2.jpg">
и 
 src="http://drupal/?q=sites/default/files/styles/large/public/images/2.jpg"> 

по этих адресах картинок нет (
как сделать что бы загружал уменьшенную копию ????

Точно такой же вопрос интересует, как и у Гостя. Как сделать что бы загружал уменьшенную копию?

Drupal загружает оригинальное изображение. Если выводить нужно меньшего размера это настраивается в view mode

Как переименовать файл при копировании?
Например, чтобы в вашем примере изначальная картинка была example.jpg, а при копировании имя файла поменялось на номер_ноды.jpg ?

в file_copy укажите новое имя вместе с путём

Есть более простое и оригинальное решение

 $node = node_load(123);
$file = system_retrieve_file(<a href="http://drupal.org/project/image.jpg" title="http://drupal.org/project/image.jpg" rel="nofollow">http://drupal.org/project/image.jpg</a>), NULL, TRUE, FILE_EXISTS_RENAME);
$node -> field_image[LANGUAGE_NONE]['0']['fid'] = $file->fid;
node_save($node);

$node = node_load(123);
$file = system_retrieve_file('http://drupal.org/project/image.jpg'), NULL, TRUE, FILE_EXISTS_RENAME);
$node -> field_image[LANGUAGE_NONE]['0']['fid'] = $file->fid;
node_save($node);

Приветствую!
А как прикрепить картинку используя ноде врапер?

$node_wrapper = entity_metadata_wrapper('node', $nid);
$file_img = file_load($fid_img);
$node_wrapper->language($locale)->{$field_name} = $file_img;

разобрался

$node_wrapper = entity_metadata_wrapper('node', $nid);
$file_img = file_load($fid_img);
$node_wrapper->language($locale)->{$field_name} = (array) $file_img;

Подскажите, пожалуйста, как массово переименовать имеющиеся изображения по имени ноды к которой они принадлежат? Например, у node1 есть изображение xxx.jpg, а должно стать node1.jpg .

Не нашёл более подходящей темы. Как лучше сделать следующиее:
Нужно к нодам програмно добавлять фотографии. Фотографии являются отдельными entity file. Одна нода может иметь до 10 000 фотографий.
Entity refferens загибается. Посоветуете что-нибудь?

Доброго времени суток!

Скажите, пожалуйста, если картинка в base64, то как ее добавить к ноде?

записать файл на диск, применить код из поста

Уважаемый xandeadx!
Эта строка:
$file_path = drupal_realpath('path/to/file/example.jpg');

path/to/file/example.jpg - здесь имеется ввиду путь до изображения на сервере или это может быть любой путь до картинки (даже до стороннего домена)?

путь до изображения на сервере

Пожалуйста, нужна помощь. Не получается загрузка. Сейчас сформулирую вопрос (5 мин.)... Подождите...

1. Есть два сайта на одном и том же сервере.
2. картинка лежит по адресу /home/vlgauto/vlgauto.ru/docs/images/banners/Audi.jpg
3. Мне необходимо перенести картинку на сайт с drupal и прикрепить её к термину
4. Пробую делать так:

$file_path = drupal_realpath('/home/vlgauto/vlgauto.ru/docs/images/banners/Audi.jpg');
 //здесь вроде проходит
$file = (object)array(
  'uid' => 1,
  'uri' => $file_path,
  'filename' => basename($file_path),
  'filemime' => file_get_mimetype($file_path),
  'alt' = $name;
  'title' = $name;
);
 //здесь вроде проходит
$file = file_copy($file, 'public://');
 //здесь какая-то ошибка. я так понимаю здесь должно быть копирование файла в директорию sites/default/files/
if ($file) {
  $termedit = taxonomy_term_load($term->tid);
  $termedit->field_catimage[LANGUAGE_NONE][] = (array)$file;
}

Что может быть не так?

Да, забыл указать в последнем операторе: taxonomy_term_save($termedit);
Подозреваю, что ошибка в пути для копирования файла. Можно ли указать конкретный путь вместо 'public://'?

файл не доступен для чтения
включена опция open_basedir
папка не доступна для записи
нет места на сервере
термина $termedit не существует
поля field_catimage не существует

1. файл не доступен для чтения - доступен.
2. включена опция open_basedir - нет.
3. папка не доступна для записи - установил права 777.
4. нет места на сервере - есть.
5. термина $termedit не существует - термин создается перед предполагаемой загрузкой картинки, извлекается $term->tid и загружается.
6. поля field_catimage не существует - создано

Если установить var_dump($file) перед функцией file_copy выдает следующее:
object(stdClass)#163 (6) { ["uid"]=> int(1) ["uri"]=> string(53) "/home/vlgauto/vlgauto.ru/docs/images/banners/Audi.jpg" ["filename"]=> string(8) "Audi.jpg" ["filemime"]=> string(10) "image/jpeg" ["alt"]=> string(45) "Авточехлы для сидений Audi" ["title"]=> string(45) "Авточехлы для сидений Audi" }

Однако после функции file_copy - var_dump($file): bool(false)

Подозреваю, что ошибка в пути для копирования файла. Можно ли указать конкретный путь вместо 'public://'?

можно

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

if(file_copy($file, '/home/vlgauto/d.vlgauto.ru/docs/sites/default/files/')){
        var_dump($file);
        echo '<img src="http://d.vlgauto.ru/sites/default/files/'.basename($file_path).'"/><br/>';
    } else {
        echo 'Ошибка при копировании<br/>';
    }

результат - Ошибка при копировании.

В чем может быть проблема?

файл грузится на сервер по относительной ссылке с помощью system_retrieve_file
Попробую так...

Благодарю вас за внимание!

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании