Drupal Problems and Solutions

DrupalABC aims to provide solution to programming problems faced by Drupal developers.Start learning by reading some of the latest problems below-

How to set Drupal cron using crontab in linux environment?

It is always a nice practice to disable automated cron module and setup Drupal cron tasks from the crontab in linux and use of Drush instead of hitting a request on Drupal generated URL. Here is the way to achieve that:

1. Enter command crontab -e to open the cron tab in editor.

2. Enter the following line and save the file.

    0 */2 * * * cd /var/www/html/example-drupal && /usr/local/bin/drush cron

So this will ensure cron runs every 2 hours. Make sure to set correct Drupal directory and drush path.

What are the correct nginx configuration settings for Magento website using PHP 7.3 FPM?

Based on the nginx sample configuration provided the by Magento repository, i have create an nginx configuration which can be used to setup Magento on any VPS.

upstream fastcgi_backend {
    server unix:/var/run/php/php7.3-fpm.sock;
}

server {
    listen 80;
    server_name magento.example.com;
    set $MAGE_ROOT /var/www/html/magento.example.com;
    root $MAGE_ROOT/pub;
    index index.php;
    autoindex off;
    charset UTF-8;
    error_page 404 403 = /errors/404.php;

    
   location /.user.ini {
        deny all;
    }

    location ~* ^/setup($|/) {
        root $MAGE_ROOT;
        location ~ ^/setup/index.php {
            fastcgi_pass   fastcgi_backend;
            fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
            fastcgi_param  PHP_VALUE "memory_limit=756M \n max_execution_time=600";
            fastcgi_read_timeout 600s;
            fastcgi_connect_timeout 600s;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~ ^/setup/(?!pub/). {
            deny all;
        }

        location ~ ^/setup/pub/ {
            add_header X-Frame-Options "SAMEORIGIN";
        }
    }

    location ~* ^/update($|/) {
        root $MAGE_ROOT;

        location ~ ^/update/index.php {
            fastcgi_split_path_info ^(/update/index.php)(/.+)$;
            fastcgi_pass   fastcgi_backend;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_param  PATH_INFO        $fastcgi_path_info;
            include        fastcgi_params;
        }

        location ~ ^/update/(?!pub/). {
            deny all;
        }

        location ~ ^/update/pub/ {
            add_header X-Frame-Options "SAMEORIGIN";
        }
    }
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location /pub/ {
        location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) {
            deny all;
        }
        alias $MAGE_ROOT/pub/;
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /static/ {
        expires max;

        location ~ ^/static/version {
            rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
        }

        location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {
            add_header Cache-Control "public";
            add_header X-Frame-Options "SAMEORIGIN";
            expires +1y;

            if (!-f $request_filename) {
                rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
            }
        }
        location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
            add_header Cache-Control "no-store";
            add_header X-Frame-Options "SAMEORIGIN";
            expires    off;

            if (!-f $request_filename) {
                rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
            }
        }
        if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /media/ {
        try_files $uri $uri/ /get.php$is_args$args;

        location ~ ^/media/theme_customization/.*\.xml {
            deny all;
        }

        location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
            add_header Cache-Control "public";
            add_header X-Frame-Options "SAMEORIGIN";
            expires +1y;
            try_files $uri $uri/ /get.php$is_args$args;
        }
        location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
            add_header Cache-Control "no-store";
            add_header X-Frame-Options "SAMEORIGIN";
            expires    off;
            try_files $uri $uri/ /get.php$is_args$args;
        }
        add_header X-Frame-Options "SAMEORIGIN";
    }

    location /media/customer/ {
        deny all;
    }

    location /media/downloadable/ {
        deny all;
    }

    location /media/import/ {
        deny all;
    }
    location /errors/ {
        location ~* \.xml$ {
            deny all;
        }
    }

    location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
        try_files $uri =404;
        fastcgi_pass   fastcgi_backend;
        fastcgi_buffers 1024 4k;

        fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
        fastcgi_param  PHP_VALUE "memory_limit=756M \n max_execution_time=18000";
        fastcgi_read_timeout 600s;
        fastcgi_connect_timeout 600s;

        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    gzip on;
    gzip_disable "msie6";
    gzip_comp_level 6;
    gzip_min_length 1100;
    gzip_buffers 16 8k;
    gzip_proxied any;
    gzip_types
        text/plain
        text/css
        text/js
        text/xml
        text/javascript
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/xml+rss
        image/svg+xml;
    gzip_vary on;

    location ~* (\.php$|\.phtml$|\.htaccess$|\.git) {
        deny all;
    }

}
 

How to set HTTPS on website using Nginx and CloudFlare as CDN

First of all, you have to add correct settings in Cloudflare under the SSL/TLS tab. Make sure it is set to Full if using self-generated/certbot generated certificate or else Full Strict if using Cloudflare provided certificate. Once the settings have been done from Cloudflare, move to Nginx configuration of the website and set them like this:

server {

       listen 80;

       listen [::]:80;

       server_name example.com www.example.com;

       return 301 https://example.com$request_uri;

 

}

server {

        listen 443 ssl;

        listen [::]:443 ssl;

        server_name www.example.com;

        ssl on;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        return 301 https://example.com$request_uri;

}

server {

        listen 443 ssl;

        listen [::]:443 ssl;

        server_name example.com;

        ssl on;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        root /var/www/html/example.com;

        index index.html;

 

        location / {

                try_files $uri $uri/ =404;

        }

}

 

First server block ensures redirection to HTTPS and 2nd makes sure non-www is redirected to www. You can modify them as per you convenience.  Avoid automatic NGINX redirections settings done by Certbot if using Cloudflare.

How to modify entity form display settings programtically?

Here is an example snippet for the same:

    $settings = \Drupal::entityTypeManager()
      ->getStorage('entity_form_display')
      ->load('commerce_product.default.default')
      ->setComponent('variations', [
        'type' => 'inline_entity_form_complex',
        'weight' => 10,
        'settings' => ['allow_new' => 'true', 'allow_duplicate' => 'true'],
      ])->save();

How to embed Webform in Drupal 8 form?

There might be a situation where a single/multiple webforms have to be added in a custom form or you may want to display webform based on some conditions. Here is an example snippet to achieve the same.

//Load webform programatically.

$webform = \Drupal::entityTypeManager()->getStorage('webform')->load($webform_id);
$webform_markup = $webform->getSubmissionForm();

//Add the markup into a Drupal 8 form.

$form['markup'] = [

      '#prefix' => '<div id = "webform">',
      '#suffix' => '</div>',
      '#type' => 'markup',
      '#markup' => $webform_markup,
      '#weight' => 1,

];

 

How to attach library using hook_preprocess_page?

Hook preprocess can be used to attach libraries on any page in Drupal 8 based on any condition. Developers can also add drupalSettings variable. Here is the code snippet:

/**
 * Hook_preprocess_page().
 */
function example_preprocess_page(&$variables) {

  $variables['#attached']['library'][] = 'example_module/example_library';

  $variables['#attached']['drupalSettings']['siteBaseUrl'] = 'example.com';

}

 

How to set entity form and entity view display settings programatically

Entity form display and Entity view display control which fields are shown in entity creation form and entity display page. Drupal provides complete control of fields and widgets through the user interface. We can also set these settings programmatically by loading correct configuration. 

    $settings = \Drupal::entityTypeManager()
      ->getStorage('entity_form_display')
      ->load('commerce_product.default.default')
      ->removeComponent('body')->save();

So when we run this snippet body field is removed from form display while creating a product of product type default. Feel free to experiment by setting other available configurations in configuration file of type entity view display and entity form display.