Suggested Topics Flashcards
(91 cards)
[Security] SQL : Example
db_query(“INSERT INTO {video_files} (fid, status, dimensions) VALUES (%d, %d, ‘%s’)”, $video[‘fid’], VIDEO_RENDERING_PENDING, $video[‘dimensions’]);
%d for integer values and %s for string values. You can also use %f for a floating point value, %b for binary data and %% just to insert a percent symbol
3 aspects of hook_initi()
Cached page doesn’t run this hook
When this hook is called, all modules are already loaded in memory
It happens after bootstrap mode
3 aspects of hook_boot()
Even cached page executes this hook
This hook is called before modules or most include files are loaded into memory.
It happens while Drupal is still in bootstrap mode.
[CSS] CSS selector precedence.
Precedence is evaluated according to these rules:
Inline CSS takes precedence over any other CSS (outdated form of styling, typically still used in email templating).
More specific selectors take precedence over less specific ones.
ID selectors take precedence over class selectors.
[jQuery] Drupal specific jQuery code sample what will execute only once for each page.
$('#some_element', context).once('mybehavior', function () { // Code here will only be applied to $('#some_element') // a single time. });
[Library] Including the jQuery library in a page.
Include the jQuery library in a page
Use a preprocess function to attach like
[‘#attached’][‘#library’][] = ‘mytheme/mylibraryname’;
[Git] Squashing multiple git commits into one commit while rebasing.
git rebase -i master
[Git] Committing all changes made inside a directory.
git add .
git commit -m “Commit message.”
[PHP] Abstract class.
PHP 5 introduces abstract classes and methods. Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method’s signature - they cannot define the implementation.
abstract class AbstractClass {
class ConcreteClass1 extends AbstractClass {
class ConcreteClass2 extends AbstractClass {
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue(‘FOO_’) .”\n”;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue(‘FOO_’) .”\n”;
[Theming] hook_preprocess_hook()
Twig renders everything automatically so there is no need to call drupal_render() or theme() within a preprocess function. Instead, render arrays should be passed to the template since this allows for much more customization than an already-rendered HTML string.
// Drupal 8 - passing a render array to the template. $variables['table'] = [ '#theme' => 'table', '#header' => $header, '#rows' => $rows, ];
// Before, unnecessary call to drupal_render(). $variables['teaser'] = drupal_render($node_teaser);
// After, with drupal_render() removed. $variables['teaser'] = $node_teaser;
[Theming] Difference between hook_preprocess_html() and template_preprocess_page(&$variables)
mytheme_preprocess_page(&$vars) {
$vars[‘variable’] = ‘string’; // $variable will be available in page.tpl.php
}
mytheme_preprocess_html(&$vars) {
$vars[‘variable’] = ‘string’; // $variable will be available in html.tpl.php
}
mytheme_preprocess_custom_theme_function(&$vars) {
$vars[‘variable’] = ‘string’; // $variable will be available in the template you specified in mymodule_theme() (custom-theme-template.tpl.php)
}
[Theming] Theme template suggestion
You enable Twig Debugging in sites/default/services.yml.
parameters:
twig. config:
debug: true
[Coding standard] What goes between “namespace” and “use” statements
Empty line between “namespace” and “use” statements
[API] Custom code that is going to execute after node insert
use Drupal\node\Entity\Node; /** * Implements hook_ENTITY_TYPE_insert(). */ function mymodule_node_insert(Node $node) {
[API] Custom code that is going to execute after node delete
hook_ENTITY_TYPE_delete
[API] Watchdog logging
hook_watchdog() is gone. For a module to implement a logger, it has to register a service tagged as logger. eg services:
logger.mylog:
class: Drupal\mylog\Logger\MyLog
tags:
- { name: logger }
This class must implement \Psr\Log\LoggerInterface. like this:
namespace Drupal\mylog\Logger;
use Drupal\Core\Logger\RfcLoggerTrait;
use Psr\Log\LoggerInterface;
class MyLog implements LoggerInterface { use RfcLoggerTrait;
/** * {@inheritdoc} */ public function log($level, $message, array $context = array()) { // Do stuff }
}
D8 - procedural
// Logs a notice
\Drupal::logger(‘my_module’)->notice($message);
// Logs an error
\Drupal::logger(‘my_module’)->error($message);
[API] Block annotation
Creating a custom block defined by your module involves the following steps:
Create a block plugin using annotations
Extend the Drupal\Core\Block\BlockBase class.
Implement the methods from the Drupal\Core\Block\BlockPluginInterface interface needed for your use case.
namespace Drupal\fax\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/** * Provides a 'Fax' block. * * @Block( * id = "fax_block", * admin_label = @Translation("Fax block"), * ) */ class FaxBlock extends BlockBase { // Override BlockPluginInterface methods here. }
[API] Retrieving settings using the configuration API
Reading configuration
Configuration is read using the get() method. This can be used in several ways. To read a piece of configuration, just provide its key.
$config = \Drupal::config(‘system.maintenance’);
$message = $config->get(‘message’);
Calls to \Drupal::config() can also be chained.
$message = \Drupal::config(‘system.maintenance’)->get(‘message’);
To read nested configuration, separate the keys with the ‘.’ character.
$enabled = \Drupal::config(‘system.performance’)->get(‘cache.page.enabled’);
You can read configuration at any level, if there is configuration nested underneath your level, it will be returned as an array.
$page_cache = \Drupal::config(‘system.performance’)->get(‘cache.page’);
This would return an array with two keys - ‘enabled’ and ‘max_age’.
To return all the data in a config object, just call get() with no arguments.
Also, you can return all configuration keys available on the system or just those keys starting with a particular substring ($prefix).
$keys = \Drupal::service(‘config.factory’)->listAll($prefix = “”);
[Tests] Choosing the right base class
Drupal 8 comes with various automated testing options to choose from. Most of those are part of core testing framework.
- Unit tests
- Kernel tests
- Functional tests
It is also possible to use external framework like behat with scenarios in gherkin syntax. Read more about different types of testing in core here.
[Security] SQL injection
db_query(“INSERT INTO {video_files} (fid, status, dimensions) VALUES (%d, %d, ‘%s’)”, $video[‘fid’], VIDEO_RENDERING_PENDING, $video[‘dimensions’]);
[Caching] Cache context and cache tag (hard)
The service ID is standardized. It always begins with cache_context., followed by the parents of the cache context, finally followed by the name of the cache context. So, for example: cache_context (mandatory prefix) + route (parents) + book_navigation (this cache context’s name):
cache_context.route.book_navigation:
class: Drupal\book\Cache\BookNavigationCacheContext
arguments: [‘@request_stack’]
tags:
- { name: cache.context }
This defines the route.book_navigation cache context.
[Caching] Dynamic page caching
Drupal 8 provides the Dynamic Page Cache module that is recommended for websites of all sizes. It caches pages minus the personalized parts, and is therefore useful for all users (both anonymous & authenticated).
Disabling while developing
In example.settings.local.php, this section can be found:
/**
* Disable Dynamic Page Cache.
*
* Note: you should test with Dynamic Page Cache enabled, to ensure the correct
* cacheability metadata is present (and hence the expected behavior). However,
* in the early stages of development, you may want to disable it.
*/
# $settings[‘cache’][‘bins’][‘dynamic_page_cache’] = ‘cache.backend.null’;
Uncomment the commented-out line to disable the dynamic page cache. But please do pay attention to the comment!
[Views] Contextual parameters
Contextual Filters in Drupal 8 are similar to the Drupal 7 with advance feature and more dynamic compared to normal filter. A Contextual Filter provides more convenient way to fetch the data either from variables sent programmatically or URL.
Configuration update for an existing module
If your module is making a data model change related to configuration, then you need to properly update your data model. The four steps are:
Update your configuration schema YML file so that it reflects your new data model. This will make sure that people that install your module after you made the change will get the correct schema. See the Configuration Schema documentation for details on that. Make sure any configuration items provided by your module in the config/install and config/optional directories have been updated, so that people installing your module will get correct configuration. Write a hook_update_N() function. This will update configuration items for existing users of your module who already had it installed before you made the change so that they can continue to function. This is described below. Write tests to ensure the code in your hook_update_N() correctly modifies the configuration. This will make sure that people who have an older version of your module installed can successfully update to the new version. See https://www.drupal.org/docs/8/api/update-api/writing-automated-update-tests-for-drupal-8 for details.
/**
* Add fruit to the default configuration for example.module.
*/
function example_update_8001() {
$config_factory = \Drupal::configFactory();
$config = $config_factory->getEditable(‘example.configuration’);
$config->set(‘fruit’, [‘apple’, ‘banana’, ‘mango’]);
$config->save(TRUE);
}
Test twig template!
test_var: {{ test_var }}
{{ submitted }}
Submitted by {{ author }} on {{ date }}
{% trans %} Submitted by {{ author.username }} on {{ node.created }} {% endtrans %}
```'; } } class Santro extends Cars { public function getCompanyName() { return "Hyundai" . '
'; } public function getPrice() { return 300000 . '
'; } } $car = new Baleno(); $car1 = new Santro(); echo $car->getCompanyName(); echo $car->getPrice(); echo $car1->getCompanyName(); echo $car1->getPrice(); ```