Slide 1

Slide 1 text

E x p e r i e n c e s i n m i g r a t i n g a D r u p a l 7 m o d u l e t o D r u p a l 8 João Ventura @jcnventura

Slide 2

Slide 2 text

T H A N K S !

Slide 3

Slide 3 text

J o ã o V e n t u r a @ j c n v e n t u r a Senior Developer at Wunder (Germany). Part of Drupal Portugal community (sometimes). Drupal user since Drupal 4.6. Maintainer of the print and adsense modules. 1 patch in D7 (moved drupal_eval to php_eval). 22 patches in D8.

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

D r u p a l 5 → 6 https://www.drupal.org/update/modules/5/6 82 API changes! CCK (Content types) Languages / Translations Menu Schema API

Slide 6

Slide 6 text

D r u p a l 6 → 7 https://www.drupal.org/update/modules/6/7 264 API changes! hook_nodeapi -> hook_node_xxx (same for + hook_block) CCK (Fields in core) Render API (and render arrays…) New database API

Slide 7

Slide 7 text

Taken from “Pirates of the Caribbean: At World's End” under the fair-use rule. (C) 2007 Walt Disney Pictures / Jerry Bruckheimer Films.

Slide 8

Slide 8 text

D r u p a l 7 → 8 https://www.drupal.org/update/modules/7/8 ??? API changes Symfony + Twig OOP Plugins Config

Slide 9

Slide 9 text

P e r s o n a l e x p e r i e n c e

Slide 10

Slide 10 text

p r i n t + a d s e n s e Maintainer of these modules since Drupal 5 Used at first in personal site (scratch my own itch) Allowed me to contribute to Drupal on my own free time Porting from Drupal 5 to 6: easy, able to follow core Porting from Drupal 6 to 7: hard, had to adapt multiple times to changing API.

Slide 11

Slide 11 text

L e s s o n s l e a r n e d p r e - D 8 Wait for beta. Don’t chase core. Leverage the improved system. Don’t just upgrade it. Coder upgrade provided some help. But in retrospective, pretty easy to upgrade a module.

Slide 12

Slide 12 text

L e t ’ s g e t Te c h n i c a l From “Ada Lovelace: The First Computer Programmer” http://iq.intel.com/ada-lovelace-the-first-computer-programmer/

Slide 13

Slide 13 text

. i n f o → . i n f o . y m l adsense.info name = AdSense core description = (…) package = Adsense core = 7.x configure = admin/config/services/ adsense adsense.info.yml name: 'AdSense' type: module description: (…) package: Adsense core: 8.x configure: adsense.main_settings

Slide 14

Slide 14 text

C o m p o s e r f i l e { "name": "drupal/adsense", "description": "Displays Google AdSense ads on your site to earn revenue.", "type": "drupal-module", "homepage": "https://drupal.org/project/adsense", "authors": [ { "name": "João Ventura", "homepage": "https://www.drupal.org/u/jcnventura" } ], "support": { "issues": "https://www.drupal.org/project/issues/adsense" }, "license": "GPL-2.0+" }

Slide 15

Slide 15 text

V a r i a b l e s adsense.module define('ADSENSE_BASIC_ID_DEFAULT', ‘’) adsense.admin.inc variable_get('adsense_basic_id', ADSENSE_BASIC_ID_DEFAULT) adsense.install variable_del(‘adsense_basic_id’)
 config/install/adsense.settings.yml adsense_basic_id: ‘’ src/Form/AdsenseIdSettings.php $config = \Drupal::config('adsense.settings'); $config->get(‘adsense_basic_id’)

Slide 16

Slide 16 text

U p g r a d e p a t h migration_templates/d7_adsense_settings.yml id: d7_adsense_settings label: AdSense 7 configuration migration_tags: - Drupal 7 source: plugin: variable variables: - adsense_basic_id process: adsense_basic_id: adsense_basic_id destination: plugin: config config_name: adsense.settings

Slide 17

Slide 17 text

M e n u r o u t i n g adsense.module function adsense_menu() { $items = array(); $items['admin/settings/adsense'] = array( 'title' => 'AdSense', 'description' => ‘…’, 'page callback' => 'drupal_get_form', 'page arguments' => array('adsense_main_settings'), 'access arguments' => array('administer adsense'), 'file' => 'adsense.admin.inc', );
 adsense.routing.yml adsense.main_settings: path: /admin/config/services/adsense defaults: _title: AdSense _form: \Drupal\adsense\Form\AdsenseMainSettin gs requirements: _permission: 'administer adsense'

Slide 18

Slide 18 text

C o n f i g u r a t i o n f o r m adsense.admin.inc function adsense_id_settings() { $form['adsense_basic_id'] = array( '#type' => 'textfield', '#title' => t(…), '#required' => TRUE, '#default_value' => variable_get(), '#description' => t(…), ); $form['#validate'][] = '_adsense_id_settings_validate'; return system_settings_form($form); } src/Form/AdsenseIdSettings.php class AdsenseIdSettings extends ConfigFormBase { public function getFormId() { return 'adsense_id_settings'; } protected function getEditableConfigNames() { return ['adsense.settings']; } public function buildForm(array $form, FormStateInterface $form_state) { $form['adsense_basic_id'] = [ '#type' => 'textfield', '#title' => t(…), '#required' => TRUE, '#default_value' => $config->get(…), '#pattern' => 'pub-[0-9]+', '#description' => t(…), ]; return parent::buildForm($form, $form_state); }

Slide 19

Slide 19 text

Tw i g t e m p l a t e templates/adsense-managed-async.html.twig script> <!-- {{ format }} --> <ins class="adsbygoogle" style="display:inline-block;width:{{ width }}px;height:{{ height }}px" data-ad-client="ca-{{ client }}" data-ad-slot="{{ slot }}"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({});

Slide 20

Slide 20 text

B l o c k s adsense_managed.module function adsense_managed_block_info() function adsense_managed_block_configure($delta = ‘’) function adsense_managed_block_save($delta = ‘', $edit = array()) function adsense_managed_block_view($delta = ‘')
 src/Plugin/Block/ManagedAdBlock.php /** * Provides an AdSense managed ad block. * * @Block( * id = "adsense_managed_ad_block", * admin_label = @Translation("Managed ad"), * category = @Translation("Adsense") * ) */ class ManagedAdBlock extends BlockBase implements AdBlockInterface { public function defaultConfiguration() public function buildConfigurationForm(array $form, FormStateInterface $form_state) public function blockSubmit($form, FormStateInterface $form_state) public function build() }

Slide 21

Slide 21 text

A n n o t a t i o n s / P l u g i n s Drupal 7: plugin system via submodules and hook_adsense_* API Drupal 8: real plugin system, based on Annotations src/Annotation/AdsenseAd.php /** * Defines an adsense ad item annotation object. * Plugin Namespace: Plugin\adsense\AdsenseAd. * @Annotation */ class AdsenseAd extends Plugin { public $id; public $name; public $isSearch; public $needsSlot; }

Slide 22

Slide 22 text

A n n o t a t i o n s / P l u g i n s src/Plugin/AdsenseAd/ManagedAd.php /** * Provides an AdSense managed ad unit. * @AdsenseAd( * id = "managed", * name = @Translation("Content ads"), * isSearch = FALSE, * needsSlot = TRUE * ) */ class ManagedAd extends ContentAdBase {

Slide 23

Slide 23 text

P S R - 4 “describes a specification for autoloading classes from file paths. (…) This PSR also describes where to place files that will be autoloaded according to the specification” Class namespace + name: namespace Drupal\adsense\Plugin\Block class ManagedAdBlock extends BlockBase implements AdBlockInterface { Class filename src/Plugin/Block/ManagedAdBlock.php

Slide 24

Slide 24 text

D r u p a l M o d u l e U p g r a d e r Handles the boring parts Converts module.info to module.info.yml Converts your hook_menu() to module.routing.yml Converts the configuration forms to src/Form/FormName.php etc. NOT a magic wand. You still have to port your functionality to work with D8 https://www.drupal.org/project/drupalmoduleupgrader

Slide 25

Slide 25 text

C o d e r S n i f f e r drupalcs: signals all code standards violations (coder sniffer). drupalcbf: automatically fixes everything it can (coder beautifier). https://www.drupal.org/project/coder Installing Coder Sniffer: https://www.drupal.org/node/1419988

Slide 26

Slide 26 text

– Murphy “ W H A T C O U L D G O W R O N G ? ” L I V E D E M O

Slide 27

Slide 27 text

L e s s o n s l e a r n e d D 8 Easy path Drupal module upgrader. Keep code in .module files. Make it work. Hard path Object-oriented-programming (Single responsibility principle, Plugins, etc.). No code other than hook_something() in .module file. Rewrite from scratch.

Slide 28

Slide 28 text

• João Ventura • d.o: jcnventura • Phone: +49.89.85636307 • [email protected] • Wunder Germany • [email protected] • www.wunder.io/de • Agnes-Pockels-Bogen 1, D1.019; 80992 München A n y q u e s t i o n s ? ?