// Load file object
$file = File::load($fid);
// Get uri (public://foo/bar/baz.png)
$uri = $file->getFileUri(););
// Get path in FS (/var/www/drupal/sites/default/files/foo.txt)
$path = drupal_realpath($file->getFileUri());
// Relative path in FS: /sytes/default/files/... (if public://)
$relative_path = file_url_transform_relative(file_create_url($uri));
// Load file content
$contents = file_get_contents($uri);Create a directory in public:// if it doesn't exist.
$image_dest = 'public://article/images';
if (!is_dir($image_dest)) {
\Drupal::service('file_system')->mkdir($image_dest, NULL, TRUE);
} Create a file using FileRepository::writeData (docs) in Drupal from image data:
use Drupal\Core\File\FileSystemInterface;
$image_url = "https://example.com/images/img.png";
$image_content = file_get_contents($image_url);
$image_filename = "img.png";
if ($image_content) {
// D9.x
$imageFid = \Drupal::service('file.repository')
->writeData(
$image_content,
"$image_dest/$image_filename",
FileSystemInterface::EXISTS_REPLACE
);
// D8.x
file_save_data($image_content, "$image_dest/$image_filename", FileSystemInterface::EXISTS_REPLACE);
}Once we have a FileEntity (returned by writeData) you can create a Media like so:
$data = [
'bundle' => 'image',
'name' => 'Title/ALT text form image',
'field_media_image' => ['target_id' => $imageFid],
];
$mediaEntity = \Drupal::entityManager()
->getStorage('media')
->create($data);
$mediaEntity->save();- file_save_data, file_copy and file_move are deprecated and replaced with a service - file_save_data, file_copy and file_move are deprecated and replaced with a service that implements \Drupal\file\FileRepositoryInterface.
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
$node = Node::load($nid);
// or, more recomended (https://www.drupal.org/project/drupal/issues/2945539)
$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
// Taxonmomy term
$term_item = $node->field_supplement_type->getValue();
$term = array_pop($term_item);
$tid = $term['target_id'];
// Load taxonomy term to use data
$supplement = Term::load($tid);
// or, more recomended (https://www.drupal.org/project/drupal/issues/2945539)
$supplement = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($tid);
$item = [
'nid' => $nid,
'title_prefix' => $node->field_supplement_title_prefix->value,
'title' => $node->title->value,
'tid' => $tid,
'supplement' => $supplement->getName(),
'home_image' => $this->getImagesCrop(...),
'cover_image' => $this->getImagesCrop(...),
'slug' => $supplement->field_slug->value,
'date' => $node->field_supplement_date->value,
];
// Other alternatives
$node->get('field_slug')->getString();
$node->field_slug->getString();Get the path of a node with:
Drupal 8.7 or earlier:
$alias = \Drupal::service('path.alias_manager')
->getAliasByPath("/node/$nid");
Drupal 8.8 or 9 you should use the path_alias.manager service:
$alias = \Drupal::service('path_alias.manager')
->getAliasByPath("/node/$nid");
For more information: https://drupal.stackexchange.com/questions/230746/get-path-alias-from-nid-or-node-object and https://www.drupal.org/node/3092086
If you have a node object you can use:
// Absolute URL
$node->toUrl()->setAbsolute()->toString()
// Relative URL
$node->toUrl()->toString();
In this sample code $article is a content type with a $field_author field that is an entity reference to a content-type called author.
if ($article->field_author->isEmpty()) {
// No hay autores. Salimos.
return;
}
$article_authors = [];
foreach($article->field_author as $author) {
$author_node = $author
->get('entity')
->getTarget()
->getValue();
$article_authors[] = [
'id' => $author_node->ID(),
'title' => $author_node->title->value,
'field_first_name' => $author_node->field_first_name->value,
'field_last_name' => $author_node->field_last_name->value,
'field_slug' => $author_node->field_slug->value
];
}or better yet:
$authors = $article->get('field_author')->referencedEntities();
foreach($authos as $author) {
$article_authors[] = [
'id' => $author->ID(),
// ...
];
} // ...
// Assuming the image is already uploaded to your server:
$fid = '123'; // The fid of the image you are going to use.
$image_media = Media::create([
'bundle' => 'your_image_bundle_name_here',
'uid' => '1',
'langcode' => Language::LANGCODE_DEFAULT,
'status' => Media::PUBLISHED,
'your_image_field_name_here' => [
'target_id' => $fid,
'alt' => t('foo'),
'title' => t('bar'),
],
]);
$image_media->save();
// Then do the same for the video media entity.
// $video_media = ... ->save();
$node = Node::create([
// The node entity bundle.
'type' => 'article',
'langcode' => 'en',
'created' => $created_date,
'changed' => $created_date,
// The user ID.
'uid' => 1,
'moderation_state' => 'published',
'title' => $title,
'field_article_section' => ['target_id' => $section_target_id],
'field_author' => 111,
'field_article_main_image' => ['target_id' => $image_media->id()],
'field_article_main_video' => array(
// ... the same as before
),
'field_article_body_summary' => [
'summary' => substr(strip_tags($text), 0, 100),
'value' => $text,
'format' => 'rich_text'
]
]);
$node->save();
$new_nid = $node->id();References
- https://www.drupal.org/project/media_entity/issues/2813025
- https://codimth.com/blog/web/drupal/how-create-nodes-programmatically-drupal-8
- Working with the Entity API | Entity API | Drupal Wiki guide on Drupal.org
Geting the image style from a file or a uri. Taken from this gist
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
// File ID.
$fid = 123;
// Load file.
$file = File::load($fid);
// Get origin image URI.
$image_uri = $file->getFileUri();
// Load image style "thumbnail".
$style = ImageStyle::load('thumbnail');
// Get URI.
$uri = $style->buildUri($image_uri);
// Get URL.
$url = $style->buildUrl($image_uri);// Load taxonomy tree into $tree
$tree = \Drupal::entityTypeManager()
->getStorage('taxonomy_term')
->loadTree(self::HOME_SUPPLEMENT_LIST_VID); // Sample query on Nodes
$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', 'supplement');
$query->condition('field_supplement_type.entity.tid', $slug->tid);
// or by name:
$query->condition('field_tags.entity.name', 'tag1');
// or by parent tid
$query->condition('field_supplement_type.entity.parent', $slug->tid);
// Disable access control if we are anonynous for example
$query->accessCheck(FALSE);
$now = new DrupalDateTime('now');
$now->setTimezone(new \DateTimeZone(DATETIME_STORAGE_TIMEZONE)); // set a desired timezone (instead of the one from the site)
$query->condition('field_date', $now->format(DATETIME_DATETIME_STORAGE_FORMAT), '>=');
$query->sort('field_supplement_date', 'DESC');
$query->range(0, 1);
$entity_ids = $query->execute();
foreach($entity_ids as $nid) {
// Load all information for this node
$node = Node::load($nid);
// Do something with node and return some data
$supplements[] = $doSomething($node);
}
// Sample query on taxonomy. Filtering by a custom column on a taxonomy
$query = \Drupal::entityQuery('taxonomy_term');
$query->condition('vid', 'vocubulary_name');
$query->condition('field_custom_text', $text);
$tids = $query->execute();
$terms = \Drupal\taxonomy\Entity\Term::loadMultiple($tids);Using services:
$service = \Drupal::service('module.service_name');
$result = $service->methodInMyService(157);Creating a service (Example taken from https://www.drupal.org/project/drupal/issues/2945539#comment-13291384):
Add a mymodule.services.yml to your module directory:
services:
mymodule.myservice:
class: Drupal\mymodule\Services\MyService
arguments: ['@entity_type.manager']Add the service in src/Services/MyService.php with:
namespace Drupal\mymodule\Services;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\NodeStorageInterface;
/**
* Class MyService.
*/
class MyService {
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var NodeStorageInterface
*/
protected $nodeStorage;
/**
* @param EntityTypeManagerInterface $entity_type_manager
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->nodeStorage = $this->entityTypeManager->getStorage('node');
}
/**
* Load a node.
*
* @param int $nid
* The ID of the node to load.
*/
public function loadANode($nid) {
return $this->nodeStorage->load($nid);
}
}It is good practice to pass along references to popular services instead of using \Drupal::service(). For example: if you need an entityTypeManager it is preferred to inject it instead of using \Drupal::entityTypeManager(). It makes your code more easily testable. Some common services to inject into your Service might be:
entity_type.manager-EntityTypeManagerobject to perform entity queries ondatabase-Connectionobject to the Drupal database to perform queries oncurrent_user-AccountProxyto the current userdate.formatter-DateFormatterobject which gives you access to theDateFormat::format()using Drupal date formats
For a full listing of Drupal's core services check this link
Para logear en reemplazo de watchdog() se usa el siguiente código:
\Drupal::logger('my_module')->error($message);Otras opciones son:
\Drupal::logger('my_module')->emergency( $message, $vars )
\Drupal::logger('my_module')->alert( $message, $vars );
\Drupal::logger('my_module')->critical( $message, $vars );
\Drupal::logger('my_module')->error( $message, $vars );
\Drupal::logger('my_module')->warning( $message, $vars );
\Drupal::logger('my_module')->notice( $message, $vars );
\Drupal::logger('my_module')->info( $message, $vars );
\Drupal::logger('my_module')->debug( $message, $vars );- Para más información: https://www.drupal.org/node/2595985
Links:
use Drupal\node\Entity\Node;
// Serialize a node to JSON
$node = Node::load($nid);
$format = 'json';
$serialized_content = \Drupal::service('serializer')
->serialize($node, $format)
);
// Deserialize from JSON -> Node
$node = \Drupal::service('serializer')
->deserialize($serialized_content, \Drupal\node\Entity\Node::class, 'json');You can serialize more complex structures like so:
<?php
use Drupal\node\Entity\Node;
$list = [
Node::load(44130),
Node::load(44131),
Node::load(44130),
];
$object = [
'total' => 3,
'data' => $list
];
print_r(
\Drupal::service('serializer')->serialize($object, 'json')
);will output:
{
"data": [
{
"nid": "44130",
"title": "Primer update de la nota"
},
{
"nid": "44131",
"title": "Un nuevo update a mi nodo"
},
{
"nid": "44132",
"title": "Tercer update de la nota"
}
],
"total": 3
}Para ejecutar una migración via código:
// Correr migración
$manager = \Drupal::service('plugin.manager.migration');
$plugins = $manager->createInstances([]);
$migration = FALSE;
foreach($plugins as $id => $plugin) {
if ($id == '[[[migration-id]]]') {
$migration = $plugin;
}
}
// Implementation of MigrateMessageInterface to track migration messages.
$log = new ReclamoLogMigrateMessage();
// if $replace run with equivalente of --update drush flag
if ($replace) {
$migration->getIdMap()->prepareUpdate();
}
// Create MigrateExecutable instance
$executable = new MigrateExecutable($migration, $log);
// Run migration
$executable->import();// For "mymodule_name," any unique namespace will do.
// I'd probably use "mymodule_name" most of the time.
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$tempstore->set('my_variable_name', $some_data);
// Retrieve data
$tempstore = \Drupal::service('user.private_tempstore')->get('mymodule_name');
$some_data = $tempstore->get('my_variable_name');
// Clear data
$tempstore->set('my_variable_name', false);more info here: https://atendesigngroup.com/blog/storing-session-data-drupal-8
- Complete example of a module with a controller + twig view: https://github.com/ericski/Drupal-8-Module-Theming-Example
If it is about clearing the cache after the user changes settings, you can clear the node_view cache tag with Drupal::entityManager()->getViewBuilder('node')->resetCache(). If you want to clear the cache of a specific tag, you can pass the node ID to that method or you can use \Drupal\Core\Cache\Cache::invalidateTags($node->getCacheTags()).
Each thing that is rendered has one or multiple cache tags (inspect the X-Drupal-Cache-Tags header of a page response, I'm sure there will be development tools to better understand them in the future), by invalidating them, you can automatically clear all caches that contain them. You can enable debuggin by setting http.response.debug_cacheability_headers: true in your services.yml
- https://www.drupal.org/docs/8/api/cache-api/cache-tags
- Debugging: https://www.drupal.org/docs/8/api/responses/cacheableresponseinterface#debugging
- Cachability of REST responses: https://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/
- Drupal 8 Themeing Guide: https://sqndr.github.io/d8-theming-guide/