The document discusses debugging techniques in Drupal 8. It begins by outlining some basic configuration options like PHP error reporting and the Devel module. It then covers specific debugging tools like Xdebug, Drupal Console, and the Web Profiler module. Various code examples demonstrate debugging problems like class not found errors and accessing protected properties. Continuous integration with Probo CI and pull requests are presented as solutions for testing and client approval workflows. The key steps for debugging are identified as thinking through code logically, identifying goals, finding the right tool to solve problems, and testing fixes.
3. Review of Resources
Gitbook of Configuration Steps: https://www.gitbook.com/book/zivtech/debug-tools-for-drupal8/details
Github Repo of ZRMS and Module: https://github.com/AllieRays/debugging-drupal-8
Demo Site: http://zivte.ch/1Ss473k
Slide Deck: http://zivte.ch/1VxWF60
Zivtech Rocks My Socks
Demo Site
Bear Install Profile Drupal 8 Site
4. Plan Ahead:
Configuration to avoid frustration
Reduce technical debt
Why is this Important?
Stop ‘Googling’ all of your problems away
(If this blog post doesn’t solve my problem another one will)
● Fix problems & code faster
Stop thinking about debugging after the fact. You should be logically thinking through as you develop.
5. Overview
Debugging is a Personal Choice. Pick Your Tools.
Drupal Console IDE Xdebug
Continuous
Integration
8. Easy / Low Hanging Configuration Options
PHP.ini
Set Error Reporting to Strict: error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
Display Errors as Html: display_errors = On
Log your errors to a php_error file: log_errors = On || log_errors_max_len = 1024
9. Easy / Low Hanging Configuration Options
Configuration Settings: Use your setting.local.php.
In setting.php add an include
if (file_exists(__DIR__ . '/settings.local.php')) {
include __DIR__ . '/settings.local.php';
}
setting.local.php
Show all error messages, with backtrace information.
$config['system.logging']['error_level'] = 'verbose';
Disable CSS and JS aggregation.
$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;
12. Drupal Print Message
The Devel Module provides helper functions to print variables in the browser.
function dpm($input, $name = NULL, $type = 'status') {
if (Drupal::currentUser()->hasPermission('access devel information')) {
$export = kprint_r($input, TRUE, $name);
drupal_set_message($export, $type, TRUE);
}
return $input;
}
What is DPM anyways?
13. Caching
From the Terminal:
● Drush: drush cr (new as of D8)
● Drupal Console: drupal cache:rebuild
Everyone’s favorite love / hate relationship
From the Browser:
● Admin Ui: /admin/config/development/performance
● Chrome Settings: Disable cache
34. Goal: Create a configurable entity type of Sock
namespace DrupalsocksEntity;
use DrupalCoreConfigEntityConfigEntityBase;
class Sock extends ConfigEntityBase {
public $id;
public $uuid;
public $label;
public $description;
public $fabric;
public $rating;
}
socks/Entity/Sock.php
class SockListBuilder extends ConfigEntityListBuilder {
public function buildRow(EntityInterface $entity) {
$row['id'] = $entity->id();
$row['description'] = $entity->description;
$row['fabric'] = $entity->fabric;
$row['rating'] = $entity->rating;
return $row + parent::buildRow($entity);
}
}
socks/src/Controller/SockListBuilder.php
Config Entity
35. class Sock extends ConfigEntityBase {
/**
* The sock's rating.
* @var string
*/
protected $rating;
}
public function buildRow(EntityInterface $entity) {
$row['id'] = $entity->id();
$row['description'] = $entity->description;
$row['fabric'] = $entity->fabric;
$row['rating'] = $entity->rating;
return $row + parent::buildRow($entity);
}
PROBLEM
Config Entity
36. SOLUTION
protected $rating;
/**
* @return string
*/
public function getRating() {
return $this->rating;
}
/**
* @param string $rating
*/
public function setRating($rating) {
$this->rating = $rating;
}
public function buildRow(EntityInterface $entity) {
$row['id'] = $entity->id();
$row['description'] = $entity->description;
$row['fabric'] = $entity->fabric;
$row['rating'] = $entity->getRating();
return $row + parent::buildRow($entity);
}
Sock Entity
Sock List Builder
Accessing a protected property by creating methods
38. Xdebug
Allows script execution to be paused at any point to read through variables
Support stack and execution traces in error messages
Profiling to find performance bottlenecks
https://zivtech.gitbooks.io/zrms/content/xdebug.html admin/reports/status/php
39. public function submitForm(array &$form, FormStateInterface $form_state) {
$result = $form_state->getValue('fav_sock');
drupal_set_message($this->t('Your favorite sock is @fav_sock',
array('@fav_sock' => $result)));
if ($result == 'Ankle Biters') {
$form_state->setRedirect('socks.knee_highs_controller_content');
}
else {
if ($result == 'Old Fashions') {
$form_state->setRedirect('socks.old_fashions_controller_content');
}
else {
$form_state->setRedirect('socks.knee_highs_controller_content');
}
}
}
Form Goal: Let users pick their favorite sock
class FavoriteSockForm extends FormBase {
public function getFormId() {
return 'favorite_sock_form';
}
public function buildForm(array $form,
FormStateInterface $form_state) {
$form['fav_sock'] = array(
'#type' => 'radios',
'#options' => array(
'Ankle Biters' => $this->t('Ankle Biters'),
'Old Fashions' => $this->t('Old Fashions'),
'Knee Highs' => $this->t('Knee Highs')
),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
socks/src/Form/FavoriteSockForm.php
40. Form
class FavoriteSockForm extends FormBase {
public function getFormId() {
return 'favorite_sock_form';
}
public function buildForm(array $form,
FormStateInterface $form_state) {
$form['fav_sock'] = array(
'#type' => 'radios',
'#options' => array(
'Ankle Biters' => $this->t('Ankle Biters'),
'Old Fashions' => $this->t('Old Fashions'),
'Knee Highs' => $this->t('Knee Highs')
),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$result = $form_state['values']['fav_sock'];
drupal_set_message($this->t('Your favorite sock is @fav_sock',
array('@fav_sock' => $result)));
if ($result == 'Ankle Biters') {
$form_state->setRedirect('socks.knee_highs_controller_content');
}
else {
if ($result == 'Old Fashions') {
$form_state->setRedirect('socks.old_fashions_controller_content');
}
else {
$form_state->setRedirect('socks.knee_highs_controller_content');
}
}
}
socks/src/Form/FavoriteSockForm.php
41. Xdebug
$form_state->getValue is an object,
but the code is trying to access it as if it were an array.
Change $form_state['values']['fav_sock'] to $form_state->getValue('fav_sock')
44. Probo CI
Probo CI creates test environments for each new feature
Visual representation of the project
while development is in progress
with Pull Request builds
Code more confidently &
Speed up approval process
Continuous integration
45. Probo CI
assets:
- dev.sql.gz
steps:
- name: Example site setup
plugin: Drupal
database: dev.sql.gz
databaseGzipped: true
databaseUpdates: true
revertFeatures: true
clearCaches: true
SOLUTION
https://github.com/AllieRays/debugging-drupal-8/blob/probos/.probo.yaml
48. Pull Requests with Probo CI
SOLUTION
https://github.com/AllieRays/debugging-drupal-8/pull/1
https://9365d60b-17fa-4834-bb2b-3bba252a14c6.probo.build/ || zivte.ch/1Ss473k
49. Gitbook of Configuration Steps: https://www.gitbook.com/book/zivtech/debug-tools-for-drupal8/details
Github Repo of ZRMS and Module: https://github.com/AllieRays/debugging-drupal-8
Demo Site: http://zivte.ch/1Ss473k
Slide Deck: http://zivte.ch/1VxWF60
Step 1: Logically think through as you develop.
Step 2: Identify the goal/objective of your code.
Step 3: Identify problem and use appropriate tools to solve your problem.
Step 4: Fix and Test.
Step 5: Test Again.
Step 6: Success!
Review
50. Gitbook of Configuration Steps:
https://www.gitbook.com/book/zivte
ch/debug-tools-for-drupal8/details
What really interested me about making this presentation was I wanted to stop googling everytime i got error. If we start to think of debuggging as a continuous development process we will code faster, fix problems and reduce technical debt.
these are some of the tools but not all of them
debugging is personal. you should get personal with it.
it might be more work in the beggning but it will save you hours of development time when you use the right tools for the job.
In order to break and debug we have to have some code right?
The PHP.ini file is the default file for php configuration. You can turn on error reporting and display errors on your local development environment.
limits on arrays and object length
offers recursion protection
limits string length
on by default, but is only enabled if php is configured to render errors as html and html errors are off by default.
minimize elements WHAT PHP IN IS
Remember when I said debugging is personal?
Move settings.local.php to your /sites/default folder
Dont add settings.php to your repo
If you have ever looked at the DPM function. It basically says if the user has access to development information print all variables and print it to the message region. Kprint calls krumo. Krumo is a debugging tool (initially PHP4/PHP5, now PHP5 only), which displays structured information about any PHP variable. It is a nice replacement for print_r() or var_dump() which are used by a lot of PHP developers.
You can also sees some of the new oop.
In drupal 7 you would have seen something like if “user_access” now you can see the currentuser method
function dpm($input, $name = NULL, $type = 'status') { if (user_access('access devel information')) { $export = kprint_r($input, TRUE, $name); drupal_set_message($export, $type); } return $input;}
Dpm | Dsm
There are a few different ways you can clear your cache
From the termianl and your browser
In chrome there is also a settings that lets you disable cache while your dev tools are open this is really great when you are doing front end development
Promise i won’t talk about caching the entire time.
I think weve all been there right?
you know something is working and you think youve cleared your cache but really you just needed to clear your cache again
and maybe clear your cache a few more times for safe measure
Drupal 7 DE VEEEEELLLLLLLLLL
http://drupal7demo.local/user/1/devel
Drupal 8
http://zrms.local/devel/user/1
You are presented with a collapsible trace leading up to your call, you get to see the actual code of each step, the full dump of arguments that were passed, and - if available - the object which contained the method that was called.
A backtrace is a report containing a sequence of nested function and method calls to the point where the trace is generated, which gives context to a developer to know what happened.
Feeling Better Already
but if you take a closer look
like krumo Kint is a php dubbing tool.
So the Toolbar is a short summary about the last request. If you click on any of the icons you will get more information.
For all the bell and whistle tools you will need to enable third party javascript libraries.
http://zrms.local/admin/reports/profiler/view/44a61d#request
D\s\C is short for Drupal System Controller
hover over to syntax
This is great for reverse engineering.
If we go back to the Zivtech What’s your favorite sock Form
http://zrms.local/admin/reports/profiler/view/e9bf47#request
You can see everything include all of the file pathing
even all of the route_params
The reason why we need to have debugging technics setup from the start is because we will be generating so much boilerplate code. The number of files is increasing but that doesn’t necessarily mean increase in complexity.
drupal router:debug favorite_sock_form.form
Object-oriented programming is a style of coding that allows developers to group similar tasks into classes.
Why am I still talking about Routes? Because all pages in drupal 8 will have a route and a controller. If the route is wrong or incorrect your site will break.
you can then use the route name as an argument to see more detailed information about each route .
once you generate your boilerplate code you can go into each file and add in your customization
for example
add fields to your forms
customize your submit method - like controller what happens when someone submits a form.
In order to break and debug we have to have some code right?
Im just going to breeze over whats in the module and then we will go circle back to go more indepth to each part of the module.
Cmd/Ctrl + click on a method and see the definition
idessss
Autoloading use statements
Look up interfaces.
When a property or method is declared protected, it can only be accessed within the class itself or in descendant classes (classes that extend the class containing the protected method).
Declare the getProperty() method as protected in MyClass and try to access it directly from outside the class:
Settings stored in the configuration API
contract: When you implement an interface you are agreeing to abide by the rules that the interface sets up. 5:55 PM
You can do more than asked but not less.
[5:56 PM] Laurence: And if you meet the expectations of the contract, you are rewarded with stuff that works and hooks up to complicated systems.
Xdebug is a PHP extension was created in 2002 as an alternative to adding a bunch of var dumps and debug backtraces to the code.
Configuration: because we are developing inside a virtual machine, they’re a bit tricky to debug with Xdebug which is, by default, tuned for localhost. so i put how I set up xdebug in the configuration gitbook.
Setup xdebug with PHPStorm and you'll have your classic breakpoint debugging.
Different IDEs will implement xDebug interactions in different ways; but the basic principles will remain the same.
Now that we have an awesome module and we know everyone is going to love our socks it is time to show it to our client
Sometime we have to debug our clients
so what are some problems that occur when we need to debug our clients
approve as you work on a feature
tease things appart
staff section broken and dummy content
look on tuesday instead of at the end of sprint
checking different things
Probo creates test environments for each new feature as your team develops so that everyone (QA or UAT testers, project managers, developers) can see and interact with development changes earlier and more frequently throughout development without waiting for an environment update.
Continuous Integration (CI) is a development practice
that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.
continuous integration feedback super fast
more effective and
-- something we’ve struggled with so we made this thing open source also a thing instrstructure wjo oauth with github sass services Free to try
Probo creates test environments for each new feature as your team develops so that everyone (QA or UAT testers, project managers, developers) can see and interact with development changes earlier and more frequently throughout development without waiting for an environment update.