debugging in drupal 8

51
Debugging in Drupal 8 Life After DPM : Creating and Debugging a Module Allie Jones

Upload: allie-jones

Post on 14-Feb-2017

1.481 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Debugging in drupal 8

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

Module

Allie Jones

Page 2: Debugging in drupal 8

Allie Ray Jones | @AllieRays

Page 3: Debugging in drupal 8

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

Page 4: Debugging in drupal 8

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.

Page 5: Debugging in drupal 8

OverviewDebugging is a Personal Choice. Pick

Your Tools.

Drupal Console IDE Xdebug Continuous Integration

Page 6: Debugging in drupal 8

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

Page 7: Debugging in drupal 8

But First, Basic Configuration

Page 8: Debugging in drupal 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

Page 9: Debugging in drupal 8

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;

Page 10: Debugging in drupal 8

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

Page 11: Debugging in drupal 8

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

Page 12: Debugging in drupal 8

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?

Page 13: Debugging in drupal 8

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

Page 14: Debugging in drupal 8

But Seriously, Did You

Clear Your Cache?

Page 15: Debugging in drupal 8

Easy / Low Hanging Configuration Options

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

Debugging/admin/reports/dblog

Page 16: Debugging in drupal 8

Devel Module

Drupal 7 Drupal 8

Page 17: Debugging in drupal 8

Drupal 8 Devel out of the Box

Page 18: Debugging in drupal 8

Devel Submodule: Kint prettify all the things

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

print data in a human readable way

backtracing

Page 19: Debugging in drupal 8

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

Page 20: Debugging in drupal 8

Web Profiler in action

Page 21: Debugging in drupal 8

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

Page 22: Debugging in drupal 8

Demo

Page 23: Debugging in drupal 8

Zivtech Rocks My Socks (demo site)

Page 24: Debugging in drupal 8

Socks Module

Page 25: Debugging in drupal 8

Module & Basic Controller: drupal generate:modulegenerate:controller

Page 26: Debugging in drupal 8

Config Entity : drupal generate:entity:config

Page 27: Debugging in drupal 8

Form : drupal generate:form

Page 28: Debugging in drupal 8

Let’s Break Some Things !

Page 29: Debugging in drupal 8

Problem: Class Not Found

Page 30: Debugging in drupal 8

PHPStormPHP IDE Integrated Development Environment by Jetbrains

Code hinting

Auto completion

Breakpoints

Built in Drupal settings support

Page 31: Debugging in drupal 8

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

Page 32: Debugging in drupal 8

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

Page 33: Debugging in drupal 8

Problem: Accessing Private and Protected Methods

Page 34: Debugging in drupal 8

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

Page 35: Debugging in drupal 8

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

Page 36: Debugging in drupal 8

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

Page 37: Debugging in drupal 8

Problem: Syntax Error

Page 38: Debugging in drupal 8

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

Page 39: Debugging in drupal 8

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

Page 40: Debugging in drupal 8

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

Page 41: Debugging in drupal 8

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

Page 42: Debugging in drupal 8

Debugging and QA does not stop at code completion.

Page 43: Debugging in drupal 8

Problem: Shared Staging Environment Client Approval Process

Page 44: Debugging in drupal 8

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

Page 45: Debugging in drupal 8

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

Page 46: Debugging in drupal 8

Problem: Cherry PickedDeployments

Page 47: Debugging in drupal 8

PROBLEM

Page 48: Debugging in drupal 8

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

Page 49: Debugging in drupal 8

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

Page 50: Debugging in drupal 8

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

Page 51: Debugging in drupal 8

Thank You!