Upgrading Drupal Modules Chris Tankersley php[world] 2015 php[world] 2015 1
Upgrading Drupal Modules Chris Tankersley php[world] 2015
php[world] 2015 1
Who Am I
• PHP Programmer for over 10 years • Drupal Developer for 5 Years • Symfony 2, Silex, and ZF2 Programmer • Maintainer of Social Media Bar • hJps://github.com/dragonmantank
php[world] 2015 2
It’s Finally Happening!!!!1!!one
php[world] 2015 3
Now we have to update our modules
php[world] 2015 4
In the Before Times
php[world] 2015 5
Drupal 6 to Drupal 7
php[world] 2015 6
Drupal 6 Drupal 7
Fix All the API Changes
Drupal 7 to Drupal 8
php[world] 2015 7
Drupal 7
Drupal 7 to Drupal 8
php[world] 2015 8
Drupal 7
PreJy Much Just API Changes
Social Media Bar
php[world] 2015 9
Gotta Share Them all
php[world] 2015 10
Client Project
php[world] 2015 11
Open Source and Give Back
php[world] 2015 12
Gotta Update Them All
php[world] 2015 13
Updating the Module
php[world] 2015 14
New Structure
modules/
|
‘- SocialMediaBar
+ src/
+ SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 15
Big Changes
• PSR4 Autoloading (yay!) • YAML config files instead of INI config files • Real objects for nearly everything • Much cleaner separa`on of concerns for code
php[world] 2015 16
Good News
Much of your business logic will probably be copy-‐paste work
php[world] 2015 17
Bad News
Much of the documenta`on is s`ll out of date
php[world] 2015 18
Let’s Get Started
php[world] 2015 19
New Structure
modules/ |
‘- SocialMediaBar
+ src/
+ SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 20
Move your module?
• Core modules live in core/modules now • modules/ isn’t off limits anymore! • Can s`ll live in sites/*/modules/ • Naming conven`ons s`ll apply
php[world] 2015 21
Info Files and YAML
php[world] 2015 22
New Structure
modules/
|
‘- SocialMediaBar
+ src/
+ SocialMediaBar.info.yml + SocialMediaBar.routing.yml
php[world] 2015 23
YAML Format
• Human and machine readable markup language • Indenta`on-‐based markup • Supports most basic types of data • Drupal uses it for module, theme, and configura`on informa`on
php[world] 2015 24
Update Your .info File
• We are switching from .ini format to .yml format • Modules must add type: module to actually show up as a module
php[world] 2015 25
socialmediabar.info name = Social Media Bar description = Adds a social media bar to different content types core = 7.x package = "Social Media" php = 5.3 stylesheets[all][] = css/socialmediabar.css scripts[] = js/socialmediabar.js
dependencies[] = libraries configure = admin/config/services/socialmediabar
php[world] 2015 26
socialmediabar.info.yml name: Social Media Bar description: Adds a social media bar to different content types core: 8.x type: module package: "Social Media"
php[world] 2015 27
New Routing System
php[world] 2015 28
New Structure
modules/
|
‘- SocialMediaBar
+ src/
+ SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 29
hook_menu() is dead, long live Routing!
• This is all moved to YAML files • hook_menu() is now split into routing.yml and links.*.yml • routing.yml handles defining URIs and route config • links.*.yml handles how links appear in the system
php[world] 2015 30
socialmediabar_menu()
php[world] 2015 31
function socialmediabar_menu() { return array( 'admin/config/services/socialmediabar' => array( 'title' => 'Social Media Bar Admin', 'description' => 'Set up configuration options for the Social Media Bar', 'page callback' => 'drupal_get_form', 'page arguments' => array('socialmediabar_admin_form'), 'access arguments' => array('administer socialmediabar settings'), ), 'socialmediabar/countproxy' => array( 'title' => 'Social Media Bar Admin', 'page callback' => 'socialmediabar_countproxy', 'type' => MENU_CALLBACK, 'access arguments' => array('access content'), ), 'socialmediabar/shareproxy' => array( 'page callback' => 'socialmediabar_shareproxy', 'type' => MENU_CALLBACK, 'access arguments' => array('access content'), ), ); }
socialmediabar.routing.yml
php[world] 2015
socialmediabar.admin: path: "/admin/config/services/SocialMediaBar" defaults: _form: "\Drupal\SocialMediaBar\Form\AdminForm" _title: "Social Media Bar Admin" requirements: _permission: "access content" socialmediabar.count_proxy: path: "/socialmediabar/countproxy" defaults: _controller: "\Drupal\SocialMediaBar\Controller\CountProxyController::index" requirements: _access: 'TRUE’
32
socialmediabar.links.menu.yml
php[world] 2015 33
socialmediabar.admin: title: 'Social Media Bar Admin' parent: system.admin_config_services description: 'Configure the Social Media Bar sharing bar' route_name: socialmediabar.admin
PSR-4 Autoloading
php[world] 2015 34
What is PSR-4
• Defines a folder structure so that classes can be loaded on demand, instead of all at once • Unlike PSR-‐0, allows shallow and split folders for loading • Much more efficient than the the old files[] key in .info • No more require at the top of your files • All of your code will now live in src/ • All of your code will now properly namespaced
php[world] 2015 35
Drupal 8 is turtles objects all the way down
php[world] 2015 36 hJps://upload.wikimedia.org/wikipedia/commons/4/47/River_terrapin.jpg
What is Namespacing?
• In PHP, a way to separate named classes and ‘bundle’ them together • Allows for renaming of classes to avoid class name duplica`on
namespace Drupal\SocialMediaBar\Controller;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Controller\ControllerBase as Base;
php[world] 2015 37
Your Module’s Namespace
Drupal\[modulename]
Lives in
modules/[modulename]/src
sites/all/modules/[modulename]/src
sites/default/modules/[modulename]/src
php[world] 2015 38
Why is it under the Drupal namespace?
php[world] 2015 39
Form Objects
php[world] 2015 40
socialmediabar.routing.yml
php[world] 2015
socialmediabar.admin: path: "/admin/config/services/SocialMediaBar" defaults: _form: "\Drupal\SocialMediaBar\Form\AdminForm" _title: "Social Media Bar Admin" requirements: _permission: "access content" socialmediabar.count_proxy: path: "/socialmediabar/countproxy" defaults: _controller: "\Drupal\SocialMediaBar\Controller\CountProxyController::index" requirements: _access: 'TRUE’
41
New Structure
modules/
|
‘- SocialMediaBar
+ src/ + Form/ + AdminForm.php + SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 42
Form API Changes
• The overall syntax is s`ll the same
• Form State is now an objects instead of an array • Routes now call forms using the _form key instead of drupal_get_form()
• Forms are now Objects, extending Drupal\Core\Form\FormBase • System forms now extend Drupal\Core\Form\ConfigFormBase
php[world] 2015 43
System/Config Forms
php[world] 2015 44
namespace Drupal\SocialMediaBar\Form; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; class AdminForm extends ConfigFormBase { public function getEditableConfigNames() public function getFormId() public function buildForm(array $form, FormStateInterface $form_state) public function submitForm(array &$form, FormStateInterface $form_state) }
Configuration
php[world] 2015 45
Configuration is now Object-Based
• Injected into Controllers and forms • Can be accessed by \Drupal::config() if needed
• Handled by namespaced areas of configura`on • socialmediabar.config
• Get individual keys from the config, set them to change values, and save them to commit the changes
php[world] 2015 46
php[world] 2015 47
public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config('socialmediabar.config'); $enabled_networks = $config->get('socialmediabar_enabled_networks') ?: []; // ... $form['available_networks']['socialmediabar_enabled_networks'] = array( '#type' => 'checkboxes', '#options' => array( 'facebook' => t('Facebook'), 'twitter' => t('Twitter'), 'linkedin' => t('LinkedIn'), 'googleplus' => t('Google+'), 'email' => t('ShareThis Email'), ), '#default_value' => array_values($enabled_networks), ); // ... }
php[world] 2015 48
public function submitForm(array &$form, FormStateInterface $form_state) { parent::submitForm($form, $form_state); $enabled_networks = $form_state->getValue('socialmediabar_enabled_networks'); $cache_time = $form_state->getValue('socialmediabar_cache_time’); $api_key = $form_state->getValue('socialmediabar_sharethis_apikey'); $config = $this->configFactory->getEditable('socialmediabar.config'); $config ->set('socialmediabar_enabled_networks’, $enabled_networks) ->set('socialmediabar_cache_time',$cache_time) ->set('socialmediabar_sharethis_apikey’, $api_key) ->save() ; }
Controllers
php[world] 2015 49
socialmediabar.routing.yml
php[world] 2015
socialmediabar.admin: path: "/admin/config/services/SocialMediaBar" defaults: _form: "\Drupal\SocialMediaBar\Form\AdminForm" _title: "Social Media Bar Admin" requirements: _permission: "access content" socialmediabar.count_proxy: path: "/socialmediabar/countproxy" defaults: _controller: "\Drupal\SocialMediaBar\Controller\CountProxyController::index" requirements: _access: 'TRUE’
50
New Structure
modules/
|
‘- SocialMediaBar
+ src/ + Controller/ + CountProxyController.php + SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 51
No More Callback Functions, Use Objects
• MENU_CALLBACK func`ons are now object::method signatures • Controllers extend Drupal\Core\Controller\ControllerBase • View output is now handled by Response Objects
php[world] 2015 52
php[world] 2015 53
namespace Drupal\SocialMediaBar\Controller; use Drupal\Core\Controller\ControllerBase; use Drupal\SocialMediaBar\Network\NetworkFactory; use Symfony\Component\HttpFoundation\JsonResponse; class CountProxyController extends ControllerBase { public function index() { $url = \Drupal::request()->get('url'); $provider = \Drupal::request()->get('provider'); $errors = []; // ... if (count($errors)) { return new JsonResponse(['errors' => $errors], 400); } try { $network = NetworkFactory::getNetwork($provider); $count = $network->getCount($url); return new JsonResponse([$provider => ['outbound' => $count]]); } catch (\Exception $e) { return new JsonResponse(['errors' => [$e->getMessage()]], 500); } } }
Theming
php[world] 2015 54
New Structure
modules/
|
‘- SocialMediaBar
+ src/ + templates/ + socialmediabar.html.twig + SocialMediaBar.info.yml
+ SocialMediaBar.routing.yml
php[world] 2015 55
hook_theme(), booooooooooooo!
• Has to live in [modulename].module • Automa`cally looks in the templates/ folder for Twig files
php[world] 2015 56
function SocialMediaBar_theme() { return array( 'socialmediabar' => array( 'template' => 'socialmediabar', 'variables' => array('api_key' => NULL, 'networks' => NULL), ), ); }
Things are attached via #attached
• No longer have drupal_add_css() or drupal_add_js() • Can easily bundle up CSS and JS into ‘libraries’
• [modulename].libraries.yml
• #attached can be used with a render array, or form descrip`ons
• hJps://www.drupal.org/developing/api/8/assets
php[world] 2015 57
JavaScript settings changes
• Now called drupalSettings instead of Drupal.settings • Passed via a drupalSettings key on #attached
php[world] 2015 58
php[world] 2015 59
public function render() { $config = \Drupal::config('socialmediabar.config'); $drupalSettings = [ 'apiKey' => $config->get('socialmediabar_sharethis_apikey'), ]; $networks = $config->get('socialmediabar_enabled_networks'); $response = [ '#theme' => 'socialmediabar', '#api_key' => $drupalSettings['apiKey'], '#networks' => $networks, '#attached' => [ 'library' => ['SocialMediaBar/socialmediabar'], 'drupalSettings' => ['socialmediabar' => $drupalSettings], ], ]; return render($response); }
Twig Extensions
php[world] 2015 60
Twig Extensions
• Allows func`on calls inside of a Twig file
php[world] 2015 61
socialmediabar.services.yml
php[world] 2015 62
services: socialmediabar.twig.renderer: class: Drupal\SocialMediaBar\Twig\RendererExtension tags: - { name: twig.extension }
php[world] 2015 63
namespace Drupal\SocialMediaBar\Twig; class RendererExtension extends \Twig_Extension { public function getName() { return 'socialmediabar.renderer'; } public function getFunctions() { return [ new \Twig_SimpleFunction('socialmediabar_render', [$this, 'render'], [ 'is_safe' => [true], ]) ]; } public function render() { // ... } }
Thank You!
hJp://ctankersley.com [email protected]
@dragonmantank
hJps://joind.in/14800
php[world] 2015 64