Debugging in drupal 8

Post on 14-Feb-2017

1.481 views 2 download

Transcript of Debugging in drupal 8

Debugging in Drupal 8Life After DPM : Creating and Debugging a

Module

Allie Jones

Allie Ray Jones | @AllieRays

Review of ResourcesGitbook 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 SocksDemo Site

Bear Install Profile Drupal 8 Site

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.

OverviewDebugging is a Personal Choice. Pick

Your Tools.

Drupal Console IDE Xdebug Continuous Integration

Zivtech Rocks My Socks ( demo site http://zivte.ch/1Ss47k )

But First, Basic Configuration

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

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;

Easy / Low Hanging Configuration Options

Documentation: https://api.drupal.org/api/drupal/8 Community: StackOverflow, Drupal.StackExchange & Drupal IRC

Change Records: https://www.drupal.org/list-changes/drupal

Change Records: https://www.drupal.org/list-changes/drupal

Drupal Print MessageThe 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?

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

But Seriously, Did You

Clear Your Cache?

Easy / Low Hanging Configuration Options

"Log. (Huh) What is it good for. Absolutely ..."

Debugging/admin/reports/dblog

Devel Module

Drupal 7 Drupal 8

Drupal 8 Devel out of the Box

Devel Submodule: Kint prettify all the things

“It's var_dump() and debug_backtrace() on steroids”

print data in a human readable way

backtracing

Devel Submodule: Web Profiler/admin/config/development/devel/webprofiler

Based on Symfony’s toolbar

Summary toolbar

Resources admin page

Review resource utilization

Cache effectiveness

Database queries

Views

Route and Controller Information

Web Profiler in action

Drupal Console Built on the Symfony console library

Debug Your Code drupal routes:debugdrupal router:debug [internal route

name]

Clear Cache drupal router:rebuild

Generate Codedrupal generate:moduledrupal generate:controllerdrupal generate:entity:configdrupal generate:form

Demo

Zivtech Rocks My Socks (demo site)

Socks Module

Module & Basic Controller: drupal generate:modulegenerate:controller

Config Entity : drupal generate:entity:config

Form : drupal generate:form

Let’s Break Some Things !

Problem: Class Not Found

PHPStormPHP IDE Integrated Development Environment by Jetbrains

Code hinting

Auto completion

Breakpoints

Built in Drupal settings support

Controller Goal: Display a basic page

namespace Drupal\socks\Controller;use Drupal\Core\Controller\ControllerBase;

class SockController extends ControllerBase { public function content() { $sockContent = \Drupal::service('socks.sock_content'); $somethings = $sockContent->displaySomethings();

return [ '#type' => 'markup', '#markup' => t($somethings) ]; }

}

socks.sock_controller_content: path: 'socks' defaults: _controller: '\Drupal\socks\Controller\SockController::content' _title: 'All the Socks' requirements: _permission: 'access content'

socks/src/Controller/SockController.php socks/socks.routing.yml

Controller

namespace Drupal\socks\Controller;

class SockController extends ControllerBase { public function content() { $sockContent = \Drupal::service('socks.sock_content'); $somethings = $sockContent->displaySomethings();

return [ '#type' => 'markup', '#markup' => t($somethings) ]; }}

Problem Solution

Problem: Accessing Private and Protected Methods

Goal: Create a configurable entity type of Sock

namespace Drupal\socks\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;

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

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

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

Problem: Syntax Error

XdebugAllows 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

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

Formclass 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

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')

Debugging and QA does not stop at code completion.

Problem: Shared Staging Environment Client Approval Process

Probo CI

Probo CI creates test environments for each new feature

Visual representation of the project while development is in progresswith Pull Request builds

Code more confidently &Speed up approval process

Continuous integration

Probo CIassets: - dev.sql.gzsteps: - name: Example site setup plugin: Drupal database: dev.sql.gz databaseGzipped: true databaseUpdates: true revertFeatures: true clearCaches: true

SOLUTIONhttps://github.com/AllieRays/debugging-drupal-8/blob/probos/.probo.yaml

Problem: Cherry PickedDeployments

PROBLEM

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

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

Gitbook of Configuration Steps: https://www.gitbook.com/book/zivtech/debug-tools-for-drupal8/details

Thank You!