├── .gitignore ├── 2019-10-21_10h02_50.jpg ├── 2019-10-21_10h03_47.jpg ├── 2019-10-23_13h23_19.jpg ├── README.md ├── ansible └── readme.md ├── apache.PNG ├── composer └── install_composer.sh ├── drupal-blt.PNG ├── drupal-code-style.jpg ├── drupal-enable.jpg ├── druplicon-small.png ├── enable_wsl.PNG ├── field.md ├── hook_node_update_info.png ├── images ├── hook_node_update_info.png └── readme.md ├── mysql └── readme.md ├── phpcs-1.jpg ├── phpcs-2.jpg ├── phpcs-3.jpg ├── phpcs4.jpg ├── phpstorm └── readme.md ├── style-checkbox.png ├── ubuntu-logo.png ├── ubuntu_install.PNG ├── vagrant └── readme.md ├── virtulamin └── readme.md ├── windows-logo.png ├── winver.PNG ├── wsl2.PNG ├── wsl_kernel.PNG ├── wsl_lamp_drupal_setup.md ├── xdebug-config-0.jpg ├── xdebug-config-2.jpg ├── xdebug-config-3.jpg ├── xdebug-verify.jpg ├── xdebug_wsl_1.jpg ├── xdebug_wsl_2.jpg ├── xdebug_wsl_3.jpg └── xdebugconfig-1.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore configuration files that may contain sensitive information. 2 | sites/*/*settings*.php 3 | sites/example.sites.php 4 | 5 | # Ignore paths that contain generated content. 6 | files/ 7 | sites/*/files 8 | sites/*/private 9 | sites/*/translations 10 | 11 | # Ignore default text files 12 | robots.txt 13 | /CHANGELOG.txt 14 | /COPYRIGHT.txt 15 | /INSTALL*.txt 16 | /LICENSE.txt 17 | /MAINTAINERS.txt 18 | /UPGRADE.txt 19 | /README.txt 20 | sites/README.txt 21 | sites/all/libraries/README.txt 22 | sites/all/modules/README.txt 23 | sites/all/themes/README.txt 24 | 25 | # Ignore everything but the "sites" folder ( for non core developer ) 26 | .htaccess 27 | web.config 28 | authorize.php 29 | cron.php 30 | index.php 31 | install.php 32 | update.php 33 | xmlrpc.php 34 | /includes 35 | /misc 36 | /modules 37 | /profiles 38 | /scripts 39 | /themes 40 | -------------------------------------------------------------------------------- /2019-10-21_10h02_50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flashvnn/drupal-snippets/8990f5ac79e402c86e3c98f8b9e273ddb531a5fa/2019-10-21_10h02_50.jpg -------------------------------------------------------------------------------- /2019-10-21_10h03_47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flashvnn/drupal-snippets/8990f5ac79e402c86e3c98f8b9e273ddb531a5fa/2019-10-21_10h03_47.jpg -------------------------------------------------------------------------------- /2019-10-23_13h23_19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flashvnn/drupal-snippets/8990f5ac79e402c86e3c98f8b9e273ddb531a5fa/2019-10-23_13h23_19.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Alter the Drupal token with ECA Token Alter 2 | 3 | https://www.drupal.org/project/token_eca_alter 4 | 5 | ``` 6 | [token-eca:{existing token}#{key}#{other_key}] 7 | 8 | [token-eca:node:title#truncate] 9 | [token-eca:node:title#truncate{length:100}] 10 | 11 | ``` 12 | 13 | ## Install php 8.3 with extensions for Drupal 14 | 15 | ``` 16 | sudo apt install php8.3 php8.3-cli php8.3-common php8.3-fpm php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-soap php8.3-intl php8.3-bcmath php8.3-opcache php8.3-mysql php8.3-pgsql php8.3-sqlite3 php8.3-imap php8.3-readline -y 17 | ``` 18 | 19 | ## Config default PHP version when installed multiple PHP versions 20 | 21 | ``` 22 | sudo apt update && sudo apt upgrade -y 23 | sudo apt install software-properties-common -y 24 | sudo add-apt-repository ppa:ondrej/php -y 25 | sudo apt update 26 | 27 | ## Install php 8.3 above 28 | 29 | sudo update-alternatives --config php 30 | ## Choose default php version 31 | 32 | 33 | ``` 34 | 35 | ## DNS, nameserver not working on WSL2 36 | 37 | ``` 38 | Update content for /etc/wsl.conf 39 | 40 | [network] 41 | generateResolvConf = false 42 | 43 | Update content for /etc/resolv.conf 44 | 45 | nameserver 8.8.8.8 46 | nameserver 1.1.1.1 47 | 48 | make it not change 49 | 50 | sudo chattr +i /etc/resolv.conf 51 | 52 | ``` 53 | 54 | ## Drush get all field name of content type 55 | 56 | ``` 57 | $ vendor/bin/drush field-info node article 58 | +-------------+----------+-------------------+-------------+ 59 | | Field name | Required | Field type | Cardinality | 60 | +-------------+----------+-------------------+-------------+ 61 | | body | | text_with_summary | 1 | 62 | | comment | | comment | 1 | 63 | | field_image | | image | 1 | 64 | | field_tags | | entity_reference | -1 | 65 | +-------------+----------+-------------------+-------------+ 66 | 67 | ``` 68 | 69 | 70 | 71 | 72 | ## Fix Git newline issue on MAC 73 | 74 | ```bash 75 | git config --global core.autocrlf input 76 | 77 | # On the project has git newline issue 78 | git rm -rf --cached . 79 | git reset --hard HEAD 80 | 81 | ``` 82 | 83 | ## Using Drush command with VBO 84 | 85 | ``` 86 | # drush vbo-execute some_view some_action --args=arg1/arg2 --batch-size=50 --display-id=page_1 --user-id=1 87 | # publish unpublished content 88 | 89 | drush vbo-exec view_unpublish_content entity:publish_action:node --display-id=page_1 --user-id=1 90 | ``` 91 | 92 | ## Export CSV with Vietnamese language 93 | 94 | ```php 95 | getActiveSheet(); 102 | 103 | // Thêm dữ liệu vào bảng tính 104 | $sheet->setCellValue('A1', 'Họ tên'); 105 | $sheet->setCellValue('A2', 'Nguyễn Văn A'); 106 | 107 | // Tạo writer cho CSV 108 | $writer = new Csv($spreadsheet); 109 | $writer->setDelimiter(','); // Ký tự phân cách 110 | $writer->setEnclosure('"'); // Ký tự bao quanh 111 | $writer->setLineEnding("\r\n"); // Ký tự kết thúc dòng 112 | $writer->setUseBOM(true); // Sử dụng BOM cho UTF-8, Important 113 | 114 | // Xuất file CSV 115 | header('Content-Type: text/csv; charset=utf-8'); // Important 116 | header('Content-Disposition: attachment; filename="data.csv"'); 117 | $writer->save('php://output'); 118 | ``` 119 | 120 | 121 | ## Composer ignore custom repositories 122 | 123 | ``` 124 | composer config repositories.packagist false 125 | ``` 126 | 127 | ## Check node in preview mode with twig 128 | 129 | ```twig 130 | {% if node.in_preview %} 131 |
PREVIEW MODE
132 | {% endif %} 133 | 134 | ``` 135 | 136 | ## Twig get file/image url of media 137 | 138 | ``` 139 | node-->[field_of_node]-->entity-->[field_of_media]-->entity-->fileuri 140 | 141 | {% set fileuri = node.field_banner.entity.field_media_image.entity.fileuri %} 142 | {{ file_url(fileuri) }} 143 | 144 | ``` 145 | 146 | ## Twig get link url of reference content 147 | 148 | ``` 149 | content-->[field_of_node]-->[0][field_of_reference][0]['#url'] 150 | 151 | {% set link_url = content.field_banner[0]['field_banner_link'][0]['#url']|render %} 152 | 153 | ``` 154 | 155 | ## Drupal twig get custom field module data 156 | 157 | https://www.drupal.org/project/custom_field 158 | 159 | ``` 160 | {% set attributes_data = [] %} 161 | {% for k, v in content.field_attributes[0]['#items'] %} 162 | {% set attributes_data = attributes_data|merge({(v['#name'] ~ ''):v['#value']}) %} 163 | {% endfor %} 164 | 165 | # Render the id 166 | {{ attributes_data['id'] }} 167 | ``` 168 | 169 | ## Bash script install composer for linux user 170 | 171 | ``` 172 | curl -s https://raw.githubusercontent.com/flashvnn/drupal-snippets/master/composer/install_composer.sh | bash 173 | source ~/.bashrc 174 | ``` 175 | 176 | 177 | ```bash 178 | #!/bin/bash 179 | 180 | # Define variables 181 | COMPOSER_DIR="$HOME/.local/bin" 182 | COMPOSER_PATH="$COMPOSER_DIR/composer" 183 | INSTALLER_PATH="composer-setup.php" 184 | 185 | # Create the Composer directory if it doesn't exist 186 | mkdir -p $COMPOSER_DIR 187 | 188 | # Download the Composer installer script 189 | php -r "copy('https://getcomposer.org/installer', '$INSTALLER_PATH');" 190 | 191 | # Verify the installer SHA-384 to ensure it is not corrupted 192 | HASH="$(wget -q -O - https://composer.github.io/installer.sig)" 193 | php -r "if (hash_file('SHA384', '$INSTALLER_PATH') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('$INSTALLER_PATH'); exit(1); } echo PHP_EOL;" 194 | 195 | # Run the installer script 196 | php $INSTALLER_PATH --install-dir=$COMPOSER_DIR --filename=composer 197 | 198 | # Remove the installer script 199 | php -r "unlink('$INSTALLER_PATH');" 200 | 201 | # Ensure the install directory is in the PATH 202 | if ! grep -q "$COMPOSER_DIR" <<< "$PATH"; then 203 | echo "export PATH=\"$COMPOSER_DIR:\$PATH\"" >> ~/.bashrc 204 | fi 205 | 206 | echo "Composer installed successfully in $COMPOSER_DIR" 207 | 208 | ``` 209 | 210 | ## Drupal update module and install custom entity 211 | 212 | ``` 213 | /** 214 | * Install custom entity my_custom_entity. 215 | */ 216 | function my_module_update_10002(&$sandbox): void { 217 | // Check if the table exists first. If not, then create the entity. 218 | if (!\Drupal::database()->schema()->tableExists('my_custom_entity')) { 219 | \Drupal::entityTypeManager()->clearCachedDefinitions(); 220 | \Drupal::entityDefinitionUpdateManager() 221 | ->installEntityType(\Drupal::entityTypeManager()->getDefinition('my_custom_entity')); 222 | } 223 | } 224 | 225 | ``` 226 | 227 | 228 | ## Apache proxy pass to nodejs application with websocket 229 | 230 | ``` 231 | ProxyPass / http://localhost:8080/ 232 | ProxyPassReverse / http://localhost:8080/ 233 | 234 | RewriteCond %{HTTP:Upgrade} websocket [NC] 235 | RewriteCond %{HTTP:Connection} upgrade [NC] 236 | RewriteRule ^/?(.*) "ws://localhost:8080/$1" [P,L] 237 | 238 | ``` 239 | 240 | ## Install nvm and nodejs per user on linux without root 241 | 242 | ``` 243 | curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash 244 | source ~/.bashrc 245 | nvm install node 246 | ``` 247 | 248 | ## Composer don't copy to libraries folder 249 | 250 | Config npm and bower 251 | 252 | https://drupaljournal.com/gist/install-npm-and-bower-packages-using-composer-drupal 253 | 254 | ``` 255 | composer require --no-update oomphinc/composer-installers-extender:^2 256 | composer update oomphinc/composer-installers-extender npm-asset/jquery-validation 257 | ``` 258 | 259 | ## What is .well-known/traffic-advice directory? 260 | 261 | ``` 262 | https://webmasters.stackexchange.com/questions/138033/what-is-well-known-traffic-advice-directory 263 | 264 | # Create file .well-known/traffic-advice 265 | # Insert content 266 | 267 | [{ 268 | "user_agent": "prefetch-proxy", 269 | "google_prefetch_proxy_eap": { 270 | "fraction": 1.0 271 | } 272 | }] 273 | 274 | # Config htaccess for Apache 275 | 276 | RewriteRule ^\.well-known/traffic-advice$ - [T=application/trafficadvice+json,END] 277 | 278 | # Config Nginx 279 | 280 | # Private Prefetch Proxy 281 | # https://developer.chrome.com/blog/private-prefetch-proxy/ 282 | location /.well-known/traffic-advice { 283 | types { } default_type "application/trafficadvice+json; charset=utf-8"; 284 | } 285 | 286 | ``` 287 | 288 | 289 | ## Drupal drush sql dump/import with compress 290 | 291 | ``` 292 | Drush sql dump and compress 293 | 294 | vendor/bin/drush sql-dump --gzip --result-file=./../db.sql 295 | 296 | Import compress file 297 | 298 | vendor/bin/drush sqlq --file=db.sql.gz 299 | 300 | ``` 301 | 302 | 303 | ## Only allow access with Cloudflare proxy with .htaccess, prevent ddos 304 |  305 | 306 | 307 | Add to .htaccess or apache .conf 308 | 309 | ``` 310 | RewriteCond %{HTTP:X-MY-TOKEN} ^$ 311 | RewriteRule ^ - [F,L] 312 | ``` 313 | 314 | Change X-MY-TOKEN with your private name. 315 | 316 | ## Javascript clear client data, cahce, cookie, session 317 | 318 | ```js 319 | sessionStorage.clear() 320 | 321 | localStorage.clear() 322 | 323 | caches.keys().then(keys => { 324 | keys.forEach(key => caches.delete(key)) 325 | }) 326 | 327 | indexedDB.databases().then(dbs => { 328 | dbs.forEach(db => indexedDB.deleteDatabase(db.name)) 329 | }) 330 | 331 | document.cookie = document.cookie.split(';').reduce((newCookie1, keyVal) => { 332 | var pair = keyVal.trim().split('=') 333 | if (pair[0]) { 334 | if (pair[0] !== 'path' && pair[0] !== 'expires') { 335 | newCookie1 += pair[0] + '=;' 336 | } 337 | } 338 | return newCookie1 339 | }, 'expires=Thu, 01 Jan 1970 00:00:00 UTC; path:/;') 340 | ``` 341 | 342 | ## PHP quick convert string to number 343 | 344 | ```php 345 | 346 | $str_num = '3.14'; 347 | $number = is_number($str_num) ? $str_num + 0 : $str_num; 348 | 349 | ``` 350 | 351 | ## Workflow label from state key 352 | 353 | ``` 354 | $workflow_state = $entity->get('moderation_state')->value; 355 | /** @var \Drupal\content_moderation\ModerationInformation $moderation_information_service */ 356 | $moderation_information_service = \Drupal::service('content_moderation.moderation_information'); 357 | $label = ''; 358 | if ($workflow = $moderation_information_service->getWorkflowForEntity($entity)) { 359 | $label = $workflow->getTypePlugin()->getState($workflow_state)?->label(); 360 | } 361 | ``` 362 | 363 | ## Clear cache with drush sql query 364 | 365 | ```bash 366 | vendor/bin/drush sql:query "TRUNCATE cachetags;TRUNCATE cache_bootstrap;TRUNCATE cache_config;TRUNCATE cache_container;TRUNCATE cache_data;TRUNCATE cache_default;TRUNCATE cache_discovery;TRUNCATE cache_dynamic_page_cache;TRUNCATE cache_entity;TRUNCATE cache_menu;TRUNCATE cache_page;TRUNCATE cache_render;TRUNCATE cache_toolbar;" 367 | 368 | ``` 369 | 370 | ## Drupal Views alter Filter to CAST() string as Float 371 | 372 | ```php 373 | //https://stackoverflow.com/questions/33417033/drupal-views-alter-filter-to-cast-string-as-float 374 | 375 | function custom_helpers_views_query_alter(&$view, &$query) { 376 | if ( $view->name == 'mietangebote' ) { 377 | 378 | // Miete 379 | if(!empty($view->exposed_raw_input['field_baserent_value'])){ 380 | 381 | foreach($query->where[1]['conditions'] as $key => $condition) { 382 | if ( $condition['field'] == 'field_data_field_baserent.field_baserent_value' ) { 383 | $query->where[1]['conditions'][$key]['operator'] = 'formula'; // important. 384 | $query->where[1]['conditions'][$key]['value'] = array(':val' => (double)$query->where[1]['conditions'][$key]['value']); 385 | $query->where[1]['conditions'][$key]['field'] = 'CAST(' . $query->where[1]['conditions'][$key]['field'] . ' AS UNSIGNED) >= :val'; 386 | //dpm($view->query->where[1]['conditions'][$key]); 387 | break; 388 | } 389 | } 390 | 391 | // For sorting as well 392 | foreach($query->orderby as $key => $condition) { 393 | if ( $condition['field'] == 'field_data_field_count_field_count_value' ) { 394 | $query->orderby[$key]['field'] = 'CAST(' . $query->orderby[$key]['field'] . ' AS UNSIGNED)'; 395 | break; 396 | } 397 | } 398 | } 399 | } 400 | } 401 | ``` 402 | 403 | ## Config settings.local.php for local development with pantheon.io 404 | 405 | ```php 406 | 'drupal10', 410 | 'username' => 'drupal10', 411 | 'password' => 'drupal10', 412 | 'host' => 'database', 413 | 'port' => '3306', 414 | 'driver' => 'mysql', 415 | 'prefix' => '', 416 | 'collation' => 'utf8mb4_general_ci', 417 | ]; 418 | 419 | $settings['hash_salt'] = '$HASH_SALT'; 420 | $settings["file_temp_path"] = 'sites/default/files/tmp'; 421 | $settings['config_sync_directory'] = '../config'; 422 | $settings['trusted_host_patterns'][] = '.*'; 423 | 424 | $config['system.logging']['error_level'] = 'verbose'; 425 | 426 | /** 427 | * Disable CSS and JS aggregation. 428 | */ 429 | $config['system.performance']['css']['preprocess'] = FALSE; 430 | $config['system.performance']['js']['preprocess'] = FALSE; 431 | 432 | ``` 433 | 434 | ## Move cursor to begin and end of line on MacOS 435 | 436 | ``` 437 | Control + A for goto the beginning and Control + E to goto the end 438 | ``` 439 | 440 | ## Custom Entity list builder with view 441 | ``` 442 | https://git.drupalcode.org/project/entity_extra/blob/HEAD/src/Controller/ViewsEntityListBuilder.php 443 | ``` 444 | 445 | 446 | ## Remove unwanted tab on node view/edit/delete page 447 | 448 | ``` 449 | /** 450 | * Hide view tab from node edit. 451 | */ 452 | function MYMODULE_menu_local_tasks_alter(&$data, $route_name, \Drupal\Core\Cache\RefinableCacheableDependencyInterface &$cacheability) { 453 | if($route_name == 'entity.node.edit_form'){ 454 | unset($data['tabs'][0]['entity.node.canonical']); 455 | } 456 | } 457 | 458 | ``` 459 | 460 | ## Find hook node update information in database 461 | 462 | ``` 463 | table: key_value 464 | column: collection 465 | find for: 'system.schema' 466 | 467 | ``` 468 | 469 |  470 | 471 | ## Bash script fix error with \r 472 | 473 | ``` 474 | sed -i 's/\r$//' filename 475 | ``` 476 | 477 | 478 | ## Linux find command examples 479 | 480 | ```bash 481 | 482 | #Find by name 483 | find . -name “*.jpg” 484 | ... 485 | ./Pictures/iPhoto Library/Data/2006/Roll 20/00697_bluewaters_1440x900.jpg 486 | ./Pictures/iPhoto Library/Data/2006/Roll 20/00705_cloudyday_1440x900.jpg 487 | ./Pictures/iPhoto Library/Data/2006/Roll 20/00710_fragile_1600x1200.jpg 488 | ./Pictures/iPhoto Library/Data/2006/Roll 20/00713_coolemoticon_1440x900.jpg 489 | ./Pictures/iPhoto Library/Data/2006/Roll 20/00714_cloudyday_1440x900.jpg 490 | ... 491 | 492 | #Find by User 493 | find . -user daniel 494 | ... 495 | ./Music/iTunes/iTunes Music/Tool/Undertow/01 Intolerance.m4a 496 | ./Music/iTunes/iTunes Music/Tool/Undertow/02 Prison Sex.m4a 497 | ./Music/iTunes/iTunes Music/Tool/Undertow/03 Sober.m4a 498 | ... 499 | 500 | #Find only directories 501 | find . -type d 502 | ... 503 | ./Development/envelope 504 | ./Development/mhp 505 | ... 506 | 507 | #Find everything over a megabyte in size 508 | find ~/Movies/ -size +1024M 509 | 510 | ... 511 | /Movies/Comedy/Funny.mpg 512 | /Movies/Drama/Sad.avi 513 | ... 514 | 515 | #Show me what content owned by root have been modified within the last minute 516 | find /etc/ -user root -mtime 1 517 | 518 | ... 519 | /etc/passwd 520 | /etc/shadow 521 | ... 522 | 523 | #The checks you can use here are: 524 | #-atime: when the file was last accessed 525 | #-ctime: when the file’s permissions were last changed 526 | #-mtime: when the file’s data was last modified 527 | 528 | 529 | # find all files in my directory with open permissions 530 | find ~ -perm 777 531 | ... 532 | ~/testfile.txt 533 | ~/lab.rtf 534 | ... 535 | 536 | #Find all files on your system that are world writeable 537 | find / – perm -0002 538 | 539 | #Correct the permissions on your web directory 540 | find /your/webdir/ -type d -print0 | xargs -0 chmod 755;find /your/webdir -type f | xargs chmod 644 541 | 542 | #Find files that have been modified within the last month and copy them somewhere 543 | find /etc/ -mtime -30 | xargs -0 cp /a/path 544 | 545 | #Daniel’s files of type jpeg 546 | find . -user daniel -type f -name *.jpg 547 | 548 | ... 549 | ./Pictures/iPhoto Library/autumn_woods.jpg 550 | ./Pictures/iPhoto Library/blue_forest.jpg 551 | ./Pictures/iPhoto Library/brothers.jpg 552 | ... 553 | 554 | Daniel’s jpeg files without autumn in the name 555 | find . -user daniel -type f -name *.jpg ! -name autumn* 556 | 557 | ... 558 | ./Pictures/iPhoto Library/blue_forest.jpg 559 | ./Pictures/iPhoto Library/brothers.jpg 560 | ... 561 | 562 | #Root’s ruby files accessed in the last two minutes 563 | find /apps/ -user root -type f -amin -2 -name *.rb 564 | 565 | ... 566 | /apps/testing.rb 567 | /apps/runme.rb 568 | ... 569 | 570 | ``` 571 | 572 | ## install nodejs on linux without sudo 573 | ``` 574 | https://www.johnpapa.net/node-and-npm-without-sudo/ 575 | 576 | Install Node.js from https://nodejs.org/en/download/ 577 | 578 | Update to the latest version of npm npm install npm -g 579 | 580 | Make a new folder for the npm global packages mkdir ~/.npm-packages 581 | 582 | Tell npm where to find/store them npm config set prefix ~/.npm-packages 583 | 584 | Verify the install 585 | 586 | Make a folder for your npm packages and tell your computer about it. 587 | 588 | mkdir "${HOME}/.npm-packages" 589 | echo NPM_PACKAGES="${HOME}/.npm-packages" >> ${HOME}/.bashrc 590 | echo prefix=${HOME}/.npm-packages >> ${HOME}/.npmrc 591 | echo NODE_PATH=\"\$NPM_PACKAGES/lib/node_modules:\$NODE_PATH\" >> ${HOME}/.bashrc 592 | echo PATH=\"\$NPM_PACKAGES/bin:\$PATH\" >> ${HOME}/.bashrc 593 | echo source "~/.bashrc" >> ${HOME}/.bash_profile 594 | source ~/.bashrc 595 | 596 | ``` 597 | 598 | ## Intercepting JavaScript Fetch API requests and responses 599 | 600 | ``` 601 | https://blog.logrocket.com/intercepting-javascript-fetch-api-requests-responses/ 602 | ``` 603 | 604 | **Request interceptor**: 605 | 606 | ```js 607 | const { fetch: originalFetch } = window; 608 | window.fetch = async (...args) => { 609 | let [resource, config ] = args; 610 | 611 | // request interceptor starts 612 | resource = 'https://jsonplaceholder.typicode.com/todos/2'; 613 | // request interceptor ends 614 | 615 | const response = await originalFetch(resource, config); 616 | 617 | // response interceptor here 618 | return response; 619 | }; 620 | 621 | 622 | fetch('https://jsonplaceholder.typicode.com/todos/1') 623 | .then((response) => response.json()) 624 | .then((json) => console.log(json)); 625 | 626 | // log 627 | // { 628 | // "userId": 1, 629 | // "id": 2, 630 | // "title": "quis ut nam facilis et officia qui", 631 | // "completed": false 632 | // } 633 | ``` 634 | 635 | **Response interceptor:** 636 | 637 | ```js 638 | const { fetch: originalFetch } = window; 639 | window.fetch = async (...args) => { 640 | let [resource, config] = args; 641 | 642 | let response = await originalFetch(resource, config); 643 | 644 | // response interceptor 645 | const json = () => 646 | response 647 | .clone() 648 | .json() 649 | .then((data) => function(){ 650 | console.log('Intercepted:', data) 651 | return { ...data, title: `Intercepted: ${data.title}` } 652 | }); 653 | 654 | response.json = json; 655 | return response; 656 | }; 657 | 658 | fetch('https://jsonplaceholder.typicode.com/todos/1') 659 | .then((response) => response.json()) 660 | .then((json) => console.log(json)); 661 | 662 | // log 663 | // { 664 | // "userId": 1, 665 | // "id": 1, 666 | // "title": "Intercepted: delectus aut autem", 667 | // "completed": false 668 | // } 669 | ``` 670 | 671 | ## Drupal print pretty json output 672 | 673 | ```php 674 | 675 | $form['json_data'] = [ 676 | '#type' => 'item', 677 | '#title' => $this->t('JSON'), 678 | '#markup' => '
' . json_encode($json_object, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . '', 679 | ]; 680 | 681 | ``` 682 | 683 | 684 | ## Fix Drupal/PHP/Composer patch not working on Mac OS 685 | 686 | ``` 687 | brew install gpatch 688 | ``` 689 | 690 | ## Docker: Add a restart policy to a container that was already created 691 | 692 | ``` 693 | docker update --restart=always