Drupal 8
Entity Reference Selection
Entity Reference Selection
To 'alter' what shows in an entity reference selection
Reference https://drupal.stackexchange.com/questions/298105/can-i-create-non-default-entityreferenceselection
In src/Plugin/EntityReferenceSelection
<?php
namespace Drupal\YOUR_MODULE\Plugin\EntityReferenceSelection;
use Drupal\node\Plugin\EntityReferenceSelection\NodeSelection;
/**
* Provides a query for a node entity reference selection.
*
* @EntityReferenceSelection(
* id = "YOUR_MODULE_REFERENCE_SELECTION_ID",
* label = @Translation("Filter nodes with a specific field value."),
* entity_types = {"node"},
* group = "YOUR_MODULE_REFERENCE_SELECTION_GROUP",
* weight = 1
* )
*/
class YourModuleEntityReferenceSelection extends NodeSelection {
/**
* {@inheritdoc}
*/
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$query = parent::buildEntityQuery($match, $match_operator);
$query->condition('field_featured', 1', '=');
return $query;
}
}
Admin configuration form with dependency injection
Admin configuration form with dependency injection
When adding a form using Form API, best practice is to use dependency injection when possible. Admin form classes typically 'extend ConfigFormBase'. If you want to add to it, it'll look like this.
<?php
namespace Drupal\my_module\Form;
use Drupal\Core\Config\Config;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Class myCustomAdminForm.
*
* @package Drupal\my_module\Form
*/
class myCustomAdminForm extends ConfigFormBase {
/**
* @var $configFactory
*/
protected $configFactory;
/**
* @var Config $myConfig
*/
protected $myConfig;
/**
* The Messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
public function __construct(
ConfigFactoryInterface $configFactory,
MessengerInterface $messenger
) {
parent::__construct($configFactory);
$this->myConfig = $this->config('my_config.settings.my_settings');
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('messenger')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'my_config.settings.my_settings',
];
}
/**
* This needs to return a string that is the unique ID of your form. Namespace the form ID based on your module's name.
*/
public function getFormId() {
return 'my_module_admin_form';
}
/**
* This returns a Form API array that defines each of the elements your form is composed of.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['text_input'] = [
'#type' => 'textfield',
'#description' => t('Enter data into this field'),
'#default_value' => $this->myConfig->get('my_config_values')
]
return parent::buildForm($form, $form_state);
}
/**
* Validate the form
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
if(empty($values['text_input']) {
$form_state->setErrorByName('text_input', t('You must enter data into this field.'));
}
}
/**
* Submit the form
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$this->myConfig->set('my_config_values', $values['text_input']);
$this->myConfig->save();
$this->messenger->addStatus('Your value has been saved.');
parent::submitForm($form, $form_state);
}
}
Set Message with a link as an argument
Set Message with a link as an argument
Need to output a message with a link in the text?
$link = Link::createFromRoute('Link Title', 'my_module.my_route', [
'argument' => 'argument value',
]);
$m_args = ['%message_link' => $link->toString()];
\Drupal::messenger()->addStatus(t('Here is a message, and here is a link. %message_link', $m_args));
Output Twig Values in console.log
Output Twig Values in console.log
Trying to debug twig? Not rendering? Try this from within your twig file...
<script>console.log({{ _context | json_encode | raw}});</script>
Create a simple service
Create a simple service
Also includes dependency injection
MY_MODULE.services.yml
services:
my_module.cool_service:
class: Drupal\my_module\Services\CoolService
arguments: ['@logger.factory']
/src/Services/CoolService.php
<?php
namespace Drupal\my_module\Services;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* CoolService returns what you give it in an array.
*/
class CoolService {
/**
* Logger Factory.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $loggerFactory;
/**
* Constructs the Cool service.
*
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
* A Guzzle client object.
*/
public function __construct(LoggerChannelFactoryInterface $loggerFactory) {
$this->loggerFactory = $loggerFactory->get('my_module');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('logger.factory')
);
}
public function doSomething($someData) {
$output = [
'my_data' => $someData;
];
$this->loggerFactory->error('Lets log a message!');
return $output;
}
}
Calling the service
$coolService = \Drupal::service('my_module.cool_service');
$returnedData = $coolService->doSomething('My Data');
echo $returnedData;
Update field values in multiple paragraphs
Update field values in multiple paragraphs
Let's say you have a LOT of paragraphs on your site. (Meaning Drupal Paragraphs contributed module entities).
Now you want to update a field in all of them. Rather than trying to find each and every one within nodes, you can run a simple script to update a field value.
This will simply load all paragraphs of a specific bundle. Then for each one, you update a value then save.
If you have a lot of paragraphs, you may want to run a batch process.
// Load all the paragraph entities of type
$entityManager = \Drupal::entityTypeManager();
$entities = $entityManager
->getStorage('paragraph')
->loadByProperties(['type' => 'MY_PARAGRAPH_TYPE','status' => 1]);
// Looping through each one and changing a value
// This could/should be set up in a batch process for a lot of items
foreach($entities as $key => $entity) {
$paragraphStorage = $entityManager->getStorage('paragraph');
$paragraph = $paragraphStorage->load($key);
$paragraph->set('field_my_field','MY_NEW_VALUE');
$paragraph->save();
}
Correct Timezone Handling
Correct Timezone Handling
Sometimes when outputting a Drupal date field, it will display in UTC, not in your desired timezone.
You can run the date through a few lines of code to output as desired.
$dt = new \DateTime($date[0]['value'], new \DateTimeZone('UTC'));
$dt->setTimeZone(new \DateTimeZone('America/Los_Angeles'));
$correct_date = $dt->format('Y-m-d H:i:s');
Using Composer to update Core and Modules
Using Composer to update Core and Modules
Oh, Composer.... How you make life so... uhh.... diff-eas-icult
Installing a module from an install that has been set up correctly with composer
composer require drupal/{name_of_contrib_module}