Drupal 7 + Symfony = Drupal 8

Alexander Bogomolov / @abogomolov

HttpKernel

HttpFoundation

EventDispatcher

Drupal 7 - Hooks

function hook_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['type']) && $form['type']['#value'] . '_node_settings' == $form_id) {
    $form['workflow']['upload_' . $form['type']['#value']] = array(
      '#type' => 'radios',
      '#title' => t('Attachments'),
      '#default_value' => variable_get('upload_' . $form['type']['#value'], 1),
      '#options' => array(t('Disabled'), t('Enabled')),
    );
  }
}

Drupal 8 - Events

$dispatcher = \Drupal::service('event_dispatcher');
$event = $dispatcher->dispatch('demo_form.save', new DemoEvent());
event_dispatcher_demo.config_subscriber:
  class: Drupal\event_dispatcher_demo\EventSubscriber\ConfigSubscriber
  tags:
    - { name: event_subscriber }
namespace Drupal\event_dispatcher_demo\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ConfigSubscriber implements EventSubscriberInterface {
  static function getSubscribedEvents() {
    $events['demo_form.save'][] = array('onConfigSave', 0);
    return $events;
  }

  public function onConfigSave($event) {
  }
}
Responding to Events in Drupal 8

Drupal 8

Events + Hooks

ClassLoader

YAML

Drupal 7

Config & Content in database :(

Theme- und Moduldefinition

Drupal 7 - mymodule.info

name = Themename
core = 7.x

stylesheets[all][] = assets/css/prod/style.css
scripts[]          = assets/js/application.min.js

regions[help]           = Help
regions[highlighted]    = Highlighted
regions[header]         = Kopfbereich
regions[content]        = Content
regions[sidebar]        = Sidebar
regions[footer]         = Footer

Drupal 8 - mymodule.info.yml

name: "Themename"
type: theme
description: ''
core: 8.x
package: Custom

regions:
  page_top:     'Page top'
  header:       'Header'
  help:         'Help'
  highlighted:  'Highlighted'
  sidebar:      'Sidebar'
  content:      'Content'
  page_bottom:  'Page bottom'

libraries:
  - theme/global-styling-theme

Config

uuid: 9b22cf76-d123-4948-ab08-8c0c9491829a
name: 'My project'
mail: bogomolov@eosnewmedia.de
slogan: ''
page:
  403: ''
  404: ''
  front: /node
admin_compact_mode: false
weight_select_max: 100
langcode: en
default_langcode: en

Routing

Drupal 7

// mymodule.module

function mymodule_menu() {
  $items = [];

  $items['mypath1'] = [
    'type'             => MENU_NORMAL_ITEM,
    'title'            => 'My Path 1',
    'page callback'    => '_mymodule_mypath1_page',
    'access arguments' => ['access content'],
  ];

  $items['mypath2'] = [
    'title'            => 'My Path 1'
    'page callback'    => 'drupal_get_form',
    'page arguments'   => ['_mymodule_mypath2_form'],
    'access arguments' => ['access content'],
  ];

  return $items;
}

function _mymodule_mypath1_page() {
  return array(
    '#type' => 'markup',
    '#markup' => t('Hello World!'),
  );
}

Drupal 8

Route

# mymodule.routing.yml

mymodule.route_name:
  path: '/my/route/{slug}/{id}'
  defaults:
    _title_callback: '\Drupal\mymodule\Controller\DemoController::getTitle'
    _controller: '\Drupal\mymodule\Controller\DemoController::showDetails'
    #_title: 'Hello World'
    #_form: '\Drupal\mymodule\Form\DemoForm'
  requirements:
    _permission: 'access content'
    slug: '[0-9a-zA-Z-_]+'
    id: '[0-9]+'
  options:
    no_cache: TRUE
Structure of routes

Menu item

# mymodule.links.menu.yml

mymodule.route_name:
    title: 'My title'
    description: 'Mydescription'
    route_name: mymodule.route_name
    parent: mymodule.parent_route

Dependency Injection

Services

# mymodule.services.yml

services:
  mymodule.geo_zip_service:
    class: Drupal\mymodule\GeoCoder\GeoZipService
    arguments: [ '@mymodule.repository.zip_code' ]
$geoZipService = \Drupal::service('mymodule.geo_zip_service');
Services and dependency injection in Drupal 8

Twig

Twig in Drupal 8

Drupal 7 - PHP

<!DOCTYPE html>
<html class="no-js">
  <head profile="<?php print $grddl_profile; ?>">
    <?php print $head; ?>
    <title><?php print $head_title; ?></title>
    <?php print $styles; ?>
    <?php print $scripts; ?>
  </head>
  <body class="<?php print $classes; ?>" <?php print $attributes;?>>
    <?php print $page_top; ?>
    <?php print $page; ?>
    <?php print $page_bottom; ?>
  </body>
</html>

Drupal 8 - Twig

<!DOCTYPE html>
<html class="no-js">
  <head>
    {{ head }}
    <title>{{ head_title|safe_join(' | ') }}</title>
    {{ styles }}
    {{ scripts }}
  </head>
  <body {{ attributes }}>
    {{ page_top }}
    {{ page }}
    {{ page_bottom }}
  </body>
</html>

Serializer

Views (HAL)

Serialization API in Drupal 8

// Serializing data
$serializer = \Drupal::service('serializer');
$output = $serializer->serialize($entity, 'json');

// Deserializing data
$entity = $serializer->deserialize($incoming_data, 'Drupal\entity_test\Plugin\Core\Entity\EntityTest', 'json');

Validation

Entity Validation API in Drupal 8
$definition = DataDefinition::create('integer')->setConstraint('Range', array('min' => 5));
$typed_data = \Drupal::typedDataManager()->create($definition, 10);
$violations = $typed_data->validate();

if ($violations->count() > 0) {
  // Validation failed.
}

Out of the box

  • Assetic
  • Console
  • Composer
  • Doctrine
  • EasyRDF
  • Guzzle
  • PHPUnit
  • PSR-3 Logging
  • Symfony2 CMF’s Routing Component

Fragen?

Vielen Dank!