SlideShare a Scribd company logo
1 of 51
Download to read offline
Staying Sane with Drupal
A Developer's Survival Guide
Oscar Merida, @omerida
Northeast PHP, Boston
August 2015
80% of building sites with
Drupal is configuration (easy)
Credit: https://www.flickr.com/photos/jeepersmedia/12953571545/
The hard part is the final
20% of customization
• Functionality that is
new to Drupal
• or different than
assumptions
• Integration with
external systems
Credit: https://www.flickr.com/photos/jurvetson/15393495039
Drupal is procedural
• Not Object Oriented
• Many structures like nodes, forms, users, etc use StdClass
objects or arrays
• Not MVC like other PHP frameworks
• but there is separation of concerns between menu callbacks
& theme layers
• Hooks afford a way to alter existing functionality or implement
new features.
• Leverage hooks
Play Well with Others
• Don’t short circuit how
things work.
• If you're stuck, ask for help.
• "Always code as if the
person who ends up
maintaining your code is a
violent psychopath who
knows where you live."
• http://c2.com/cgi/wiki?
CodeForTheMaintainer
Use Drupal APIs
• EntityFieldQuery
• Form ArrayPI
• node_load(), node_presave(), node_* hooks
• Node Access System
Dig into the Documentation
• api.drupal.org has function definitions and
examples.
• Security - 

https://www.drupal.org/writing-secure-code
• Check Project Issue Queues
Best Practices
Rules of the Road
• Use Version Control (git, svn, etc.)
• Use branches to manage workflow
• Replicate production environment in a VM
• Rule 0.1 - never edit files on live
Follow Drupal's coding standard.
• Everyone on the team must follow it.
• https://www.drupal.org/coding-standards
• Don't waste cycles arguing about which
standard to follow.
• Can use your IDE to follow a standard.
• BONUS: Use PHP CodeSniffer to enforce it.
Use Features
• Drupal saves a lot of configuration to the database,
• makes code sharing & deployments difficult.
• Use Features + Strongarm modules to export settings to
Features modules.
• Create one Feature module for each Content Type or Function
• Include related fields, Views, Display Suite settings, Panels &
Pages, Contexts, Path aliases, Rules,etc.
• Have a Base module with shared fields and global settings
like input formats.
Share Features
• Track your modules in VCS
• When you update codebase, check Features UI for
Overrides and resolve them.
Automate Deployments
• As simple as having a simple script to sync files
to your environments
• Or automagically update dev, stage, production
by pushing to the correct VCS branch
• https://www.freelock.com/node/1108
• BUT remember to keep sensitive information out
of VCS (like database credentials).
Don't Fear the Command Line
• Drush is faster and easier to automate than
going through the UI.
• Clearing caches - drush cc all
• DB Snapshot - drush sql-dump > ../mydb.sql
• Creating a user - drush user-create
• Reindexing search - drush search-index
Contrib makes life
easy
…except when it doesn’t.
Focus on building new solutions.
• Avoid “Not-invented-here” syndrome
• There's a module for that. In fact, there's
probably several …
http://dilbert.com/strip/2014-08-11
But with great power…
• Inherit technical debt
of a module.
• Keep up-to-date with
new releases,
especially security
releases.
• Sometimes you don't
need a module to
change things.
Evaluating a module
• Does the maintainer have other modules?
• Does it have a stable release?
• Does it have recent commits?
• Is the issue queue active?
• Does it have good documentation?
Practically core…
• Views (is in D8)
• Views Bulk Operations
• Features & Strongarm
• Pathauto & Token
• Webform
• Rules
• Email
• Link
• Smart Trim
• Redirect
• Entity Reference
• Entity API
• Entity Cache
Nice to Have
• Bean (better Blocks)
• Administration Views
• Display Suite
• Backup & Migrate
• Content Locking
• Menu Block
• Revisioning
• Add Another
Migration tools
• Feeds or Migrate
• Pathologic
• Views Data Export
Views
• GUI based Query Builder
• Has its own terminology
• Excels at building
display output.
• Not limited to HTML.
https://commons.wikimedia.org/wiki/File:Tower_Optical_Binoculars.jpg
Fields & Filters
• Fields - the fields to return from the query
• SELECT id, name, birthdate
• Filters - conditions to select items
• WHERE name=“smith”
Contextual Filters
• Apply filters based on external arguments.
• Filter values usually come from the URL path.
• Node ID
• User ID
• Term ID
Relationships
• Add a related table to the base query
• JOIN groups ON (groups.id=users.group_id)
• Can then pull in fields from other entites into
Fields, Filters, and Contexts.
Use an Existing View Programatically.
• views_embed_view(): Useful for building custom blocks
with logic while keeping them configurable in the Views UI.
function mymodule_view() {
$tid = (int) arg(2);
$preferred = views_embed_view('dept_resources', 'block_1', $tid);
// test if the view is empty by looking for view-empty class
if (false !== strpos($preferred, 'class="view-empty"')) {
$all = views_embed_view('dept_resources', 'block_2', $tid);
$block['content'] = $all;
} else {
$block['content'] = $preferred;
}
return $block;
}
Views Hooks
• Views API provides a number of hooks for
changing a view.
• hook_views_pre_view()
• hook_views_pre_ender()
• hook_views_query_alter()
• and more! 

https://api.drupal.org/api/views/views.api.php/group/views_hooks/7
hook_views_pre_view()
• Runs at start of processing. Useful for changing
or cleaning up arguments.
function foo_views_pre_view(&$view, &$display_id, &$args) {
if ('map_legend' == $view->name) {
// get location short name from aliased view pat
// ex. "campus/fairfax-va"
$shortname = parse_path_shortname();
// get the campus node with the matching shortname
$node = foo_campus_lookup_shortname($shortname);
$args[0] = $node->nid;
}
}
hook_views_pre_render()
• Runs at start of rendering.
• Useful for changing titles, adding headers & footers,
replacing placeholders.
function foo_views_pre_render(&$view) {
if ('campus_map' == $view->name) {
if (isset($view->result[0]->nid)) {
$node = $view->result[0]->_field_data['nid']['entity'];
$view->set_title('Campuses for ' . $node->title);
}
return;
}
hook_views_query_alter()
• Alter a query before it runs.
• Helps deal with input edge cases.
function foo_views_query_alter(&$view, &$query) {
if ('campus_contacts' == $view->name) {
if ('mid-state' == arg(2)) {
$query->where[0]['conditions'][0]['value'] = 'Mid-State';
}
}
}
but sometimes…
• You need to query for a collection of Entities
• In that case, use EntityFieldQuery
• https://www.drupal.org/node/1343708
• Unless you're reading & writing your own custom
tables, don't use db_query().
function foo_lookup_shortname($short)
{
// now look up the node for this short to make sure it exists
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'campus')
->propertyCondition('status', 1)
->fieldCondition('field_short_name', 'value', $short, '=')
->range(0, 1);
$result = $query->execute();
if (!$result || empty($result)) {
return false;
}
$ids = array_keys($result['node']);
$nodes = node_load_multiple($ids);
$node = array_pop($nodes); // return first
return $node;
}
Writing Custom
Modules
Custom modules for:
• Implementing hooks
• Integration with 3rd party systems
• Custom entities
Use Permissions
• hook_perm defines permissions
• Check for custom permission in routes, views, etc.
• Avoid checking for one or more roles.
/**
* Implements hook_permission().
*/
function foo_email_digest_permission() {
return array(
'administer foo digest' => array(
'title' => t('Administer FOO Digest'),
'description' => t('Manage Digest settings.'),
),
);
}
Use Node Grants
• hook_node_grants defines
what "realms" a user works
with.
• A user can belong to one or
more groups in a realm.
• https://www.phase2technology.com/
drupal-7-node-access-grants-locks-
and-keys/
function foo_node_grants($account, $op) {
$grants = array();
// If a user is an admin then grant access to all
if (user_has_role('Site Admin', $account)) {
$admin_nids = foo_get_workspace_nids();
$grants['workspace_member'] = $admin_nids;
} else {
$ws_nids = foo_get_users_ws_nids($account);
// add the workspace nodes that the user
// is an owner of too.
$owner_nids = foo_get_owner_ws_nids($account);
$grants['workspace_member']
= array_merge($ws_nids, $owner_nids);
}
return $grants;
}
Use Node Grants, pt 2
• hook_node_access_records
control access to nodes.
• Control user access for
viewing, updating, deleting at
the node-level.
• Integrates with views and
search results.
function foo_node_access_records($n)
{
// don't clutter grants
if ('resource' !== $n->type) {
return;
}
$ws_nid = $n->field_workspace['und'][0]['target_id'];
if (empty($ws_nid)) {
return;
}
$grants = array();
$grants[] = array (
'realm' => 'workspace_member',
'gid' => $ws_nid,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => 0,
);
return $grants;
}
Define custom pages for
your module
/**
* Implements hook_menu().
*/
function foo_email_digest_menu() {
$items['admin/config/system/foo_digest'] = array(
'title' => 'FOO Daily Digest',
'description' => 'Administer FOO Digest settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array('foo_digest_admin'),
'access arguments' => array('administer foo digest'),
'file' => 'foo_email_digest.admin.php',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
Check Requirements
Use hook_requirements
to check installation
requirements or report
status.
/**
* Implements hook_requirements().
*/
function foo_email_digest_requirements($phase) {
if ('runtime' == $phase) {
$toggle = variable_get('foo_digest_toggle', 'off');
if ('on' == $toggle) {
$requirements['foo_digest_toggle'] = array(
'title' => 'FOO Digest Status',
'value' => check_plain($toggle),
'severity' => REQUIREMENT_OK,
);
} else {
$requirements['foo_digest_toggle'] = array(
'title' => 'FOO Digest Status',
'value' => check_plain($toggle),
'severity' => REQUIREMENT_WARNING,
);
}
Expose tasks via Drush
• Make functionality
available via drush
• http://www.drush.org/en/
master/commands/
• Can then execute
them in Terminal
• easier to schedule
via cron too
/**
* Implements hook_drush_command().
*/
function foo_email_digest_drush_command() {
$items['foo-digest-send'] = array(
'description' => 'Send email digest.',
'aliases' => array('foodig'),
);
return $items;
}
function drush_foo_email_digest_foo_digest_send() {
foo_digest_send();
}
Best Practices
• Create an admin settings form
• Keep editable settings outside of code
• Consider having switches to toggle functionality
on/off
• Provide theme functions
• Themes and other modules can override
rendered display
Key Global Functions
• t()
• check_plain()
• filter_xss
• arg()
• current_path()
• menu_get_item()
• drupal_goto()
• drupal_deny_access()
• get_current_user()
• drupal_message()
Basics
• t() - Output a translatable string with replacements
• check_plain() - Output sanitized text. Important if
you’re taking user input and displaying it.
• filter_xss() - Output sanitized text, allow some HTML
tags. Important if you’re taking user input and
displaying it.
• See also filter_admin_xss()
• arg() - Get an argument from the URL path.
Remember to filter input!
get_current_user()
• Retrieve the user object for the current user.
• Better than global $user;
<?php
function foo() {
$user = get_current_user();
if (0 == $user->uid) {
drupal_goto('user/login');
}
}
current_path()
• Returns the current unaliased path. Useful if a
hook should only run on one or more specific
paths.
if ('node/15' == current_path()) {
// customize this node
}
if ('publications' == current_path()) {
// customize this node
}
drupal_get_path_alias()
• Returns the aliased path for an internal path.
// check alias of current page
$alias = drupal_get_path_alias();
if ('about' == $alias) {
// customize the 'About Us' page
}
menu_get_item()
• Returns the currents menu item path. Similar to
current_path(), easier to test if something
should only run on a set of pages.
$menu = menu_get_item();
// make sure we're on any user profile page
if ('user/%' !== $menu['path']) {
return
}
drupal_goto()
• Redirect client to another URL. Allows other
modules to rewrite paths.
if (0 == $user->uid) {
drupal_goto('user/login');
}
drupal_deny_access()
• Show an access denied message.
if (0 == $user->uid) {
drupal_deny_access();
}
drupal_set_message()
• Display success, warning, or error messages to
client (web or Drush).
<?php
function foo() {
$node = node_load('node/' . $nid);
// ...do some stuff to $node
// something went wrong
drupal_set_message(
'Could not use node',
'warning', // status|warning|error
);
}
Thank You. Questions?
• Follow me @omerida
• Slides:
• http://phpa.me/drupal-sane-nephp
• Feedback:
• https://joind.in/talk/view/14727
• Editor-in-chief of php[architect]
• Check out http://world.phparch.com

More Related Content

What's hot

【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践taobao.com
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes ramakesavan
 
WordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkWordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkExove
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developersDream Production AG
 
[2015/2016] Local data storage for web-based mobile apps
[2015/2016] Local data storage for web-based mobile apps[2015/2016] Local data storage for web-based mobile apps
[2015/2016] Local data storage for web-based mobile appsIvano Malavolta
 
Lecture 9 - Java Persistence, JPA 2
Lecture 9 - Java Persistence, JPA 2Lecture 9 - Java Persistence, JPA 2
Lecture 9 - Java Persistence, JPA 2Fahad Golra
 
WordPress Themes 101 - PSUWeb13 Workshop
WordPress Themes 101 - PSUWeb13 WorkshopWordPress Themes 101 - PSUWeb13 Workshop
WordPress Themes 101 - PSUWeb13 WorkshopCurtiss Grymala
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...Atlassian
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...Atlassian
 
Lecture 4: JavaServer Pages (JSP) & Expression Language (EL)
Lecture 4:  JavaServer Pages (JSP) & Expression Language (EL)Lecture 4:  JavaServer Pages (JSP) & Expression Language (EL)
Lecture 4: JavaServer Pages (JSP) & Expression Language (EL)Fahad Golra
 
Lecture 2: Servlets
Lecture 2:  ServletsLecture 2:  Servlets
Lecture 2: ServletsFahad Golra
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindValentine Matsveiko
 
Becoming A Drupal Master Builder
Becoming A Drupal Master BuilderBecoming A Drupal Master Builder
Becoming A Drupal Master BuilderPhilip Norton
 
Training in Android with Maven
Training in Android with MavenTraining in Android with Maven
Training in Android with MavenArcadian Learning
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engineWO Community
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupalBlackCatWeb
 

What's hot (20)

【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes
 
WordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkWordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a Framework
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developers
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
[2015/2016] Local data storage for web-based mobile apps
[2015/2016] Local data storage for web-based mobile apps[2015/2016] Local data storage for web-based mobile apps
[2015/2016] Local data storage for web-based mobile apps
 
Lecture 9 - Java Persistence, JPA 2
Lecture 9 - Java Persistence, JPA 2Lecture 9 - Java Persistence, JPA 2
Lecture 9 - Java Persistence, JPA 2
 
WordPress Themes 101 - PSUWeb13 Workshop
WordPress Themes 101 - PSUWeb13 WorkshopWordPress Themes 101 - PSUWeb13 Workshop
WordPress Themes 101 - PSUWeb13 Workshop
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
 
Lecture 4: JavaServer Pages (JSP) & Expression Language (EL)
Lecture 4:  JavaServer Pages (JSP) & Expression Language (EL)Lecture 4:  JavaServer Pages (JSP) & Expression Language (EL)
Lecture 4: JavaServer Pages (JSP) & Expression Language (EL)
 
Lecture 2: Servlets
Lecture 2:  ServletsLecture 2:  Servlets
Lecture 2: Servlets
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mind
 
JSP Part 2
JSP Part 2JSP Part 2
JSP Part 2
 
Becoming A Drupal Master Builder
Becoming A Drupal Master BuilderBecoming A Drupal Master Builder
Becoming A Drupal Master Builder
 
Drupal 8: Fields reborn
Drupal 8: Fields rebornDrupal 8: Fields reborn
Drupal 8: Fields reborn
 
Training in Android with Maven
Training in Android with MavenTraining in Android with Maven
Training in Android with Maven
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engine
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupal
 
Maven in Mule
Maven in MuleMaven in Mule
Maven in Mule
 

Viewers also liked

Las redes sociales en la política
Las redes sociales en la política Las redes sociales en la política
Las redes sociales en la política davidpadron22
 
Caracterísiticas del Periodismo Digital en Bolivia 2012
Caracterísiticas del Periodismo Digital en Bolivia 2012Caracterísiticas del Periodismo Digital en Bolivia 2012
Caracterísiticas del Periodismo Digital en Bolivia 2012Tonny Lopez
 
Introducción al estudio de la Literatura
Introducción al estudio de la LiteraturaIntroducción al estudio de la Literatura
Introducción al estudio de la LiteraturaGabriel Castriota
 
SIPPO Digital Marketing Trends Maboneng
SIPPO Digital Marketing Trends MabonengSIPPO Digital Marketing Trends Maboneng
SIPPO Digital Marketing Trends MabonengWilliam Price
 
FY 2017 Budget Analysis Section IV Capital Budget
FY 2017 Budget Analysis  Section IV Capital BudgetFY 2017 Budget Analysis  Section IV Capital Budget
FY 2017 Budget Analysis Section IV Capital BudgetKyle Patterson
 
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفال
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفالأهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفال
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفالOsama Madbooly
 

Viewers also liked (11)

Las redes sociales en la política
Las redes sociales en la política Las redes sociales en la política
Las redes sociales en la política
 
barzgar soltani 1389 modelsazi
barzgar soltani 1389 modelsazibarzgar soltani 1389 modelsazi
barzgar soltani 1389 modelsazi
 
El Periódico Digital - Tercera sesión
El Periódico Digital - Tercera sesiónEl Periódico Digital - Tercera sesión
El Periódico Digital - Tercera sesión
 
Conductismo
ConductismoConductismo
Conductismo
 
MEMORANDUM NPV
MEMORANDUM NPVMEMORANDUM NPV
MEMORANDUM NPV
 
Caracterísiticas del Periodismo Digital en Bolivia 2012
Caracterísiticas del Periodismo Digital en Bolivia 2012Caracterísiticas del Periodismo Digital en Bolivia 2012
Caracterísiticas del Periodismo Digital en Bolivia 2012
 
Aprendiendo a leer.pptx
Aprendiendo a leer.pptx Aprendiendo a leer.pptx
Aprendiendo a leer.pptx
 
Introducción al estudio de la Literatura
Introducción al estudio de la LiteraturaIntroducción al estudio de la Literatura
Introducción al estudio de la Literatura
 
SIPPO Digital Marketing Trends Maboneng
SIPPO Digital Marketing Trends MabonengSIPPO Digital Marketing Trends Maboneng
SIPPO Digital Marketing Trends Maboneng
 
FY 2017 Budget Analysis Section IV Capital Budget
FY 2017 Budget Analysis  Section IV Capital BudgetFY 2017 Budget Analysis  Section IV Capital Budget
FY 2017 Budget Analysis Section IV Capital Budget
 
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفال
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفالأهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفال
أهم المظاهر والسلوكيات الغريبة المؤقتة التي تظهر للأطفال
 

Similar to Staying Sane with Drupal NEPHP

Drupal security
Drupal securityDrupal security
Drupal securityJozef Toth
 
Drupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaDrupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaGábor Hojtsy
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesShabir Ahmad
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Learning to run
Learning to runLearning to run
Learning to rundominion
 
Doing Drupal security right
Doing Drupal security rightDoing Drupal security right
Doing Drupal security rightGábor Hojtsy
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to TornadoGavin Roy
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Lucidworks
 
Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Drupalcon Paris
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
Doing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonDoing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonGábor Hojtsy
 
13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS 13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS DrupalMumbai
 
Django Overview
Django OverviewDjango Overview
Django OverviewBrian Tol
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS BackendLaurent Cerveau
 
Web Development with Python and Django
Web Development with Python and DjangoWeb Development with Python and Django
Web Development with Python and DjangoMichael Pirnat
 
Frame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningFrame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningDavid Stein
 
Extjs3.4 Migration Notes
Extjs3.4 Migration NotesExtjs3.4 Migration Notes
Extjs3.4 Migration NotesSimoAmi
 
SilverStripe From a Developer's Perspective
SilverStripe From a Developer's PerspectiveSilverStripe From a Developer's Perspective
SilverStripe From a Developer's Perspectiveajshort
 

Similar to Staying Sane with Drupal NEPHP (20)

Drupal security
Drupal securityDrupal security
Drupal security
 
Drupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaDrupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp Bratislava
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Learning to run
Learning to runLearning to run
Learning to run
 
Doing Drupal security right
Doing Drupal security rightDoing Drupal security right
Doing Drupal security right
 
Fapi
FapiFapi
Fapi
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
 
Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Doing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonDoing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon London
 
13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS 13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS
 
Django Overview
Django OverviewDjango Overview
Django Overview
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS Backend
 
Web Development with Python and Django
Web Development with Python and DjangoWeb Development with Python and Django
Web Development with Python and Django
 
Frame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine LearningFrame - Feature Management for Productive Machine Learning
Frame - Feature Management for Productive Machine Learning
 
Extjs3.4 Migration Notes
Extjs3.4 Migration NotesExtjs3.4 Migration Notes
Extjs3.4 Migration Notes
 
SilverStripe From a Developer's Perspective
SilverStripe From a Developer's PerspectiveSilverStripe From a Developer's Perspective
SilverStripe From a Developer's Perspective
 
CodeIgniter & MVC
CodeIgniter & MVCCodeIgniter & MVC
CodeIgniter & MVC
 

More from Oscar Merida

Symfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with easeSymfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with easeOscar Merida
 
Integration Testing with Behat drupal
Integration Testing with Behat drupalIntegration Testing with Behat drupal
Integration Testing with Behat drupalOscar Merida
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development EnvironmentsOscar Merida
 
How to Evaluate your Technical Partner
How to Evaluate your Technical PartnerHow to Evaluate your Technical Partner
How to Evaluate your Technical PartnerOscar Merida
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development EnvironmentsOscar Merida
 
Publishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocPublishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocOscar Merida
 
Migrate without migranes
Migrate without migranesMigrate without migranes
Migrate without migranesOscar Merida
 

More from Oscar Merida (10)

PHP OOP
PHP OOPPHP OOP
PHP OOP
 
Start using PHP 7
Start using PHP 7Start using PHP 7
Start using PHP 7
 
Symfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with easeSymfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with ease
 
Integration Testing with Behat drupal
Integration Testing with Behat drupalIntegration Testing with Behat drupal
Integration Testing with Behat drupal
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development Environments
 
How to Evaluate your Technical Partner
How to Evaluate your Technical PartnerHow to Evaluate your Technical Partner
How to Evaluate your Technical Partner
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development Environments
 
Publishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocPublishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandoc
 
Migrate without migranes
Migrate without migranesMigrate without migranes
Migrate without migranes
 
Hitch yourwagon
Hitch yourwagonHitch yourwagon
Hitch yourwagon
 

Recently uploaded

Radiant Call girls in Dubai O56338O268 Dubai Call girls
Radiant Call girls in Dubai O56338O268 Dubai Call girlsRadiant Call girls in Dubai O56338O268 Dubai Call girls
Radiant Call girls in Dubai O56338O268 Dubai Call girlsstephieert
 
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$kojalkojal131
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxellan12
 
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Roomgirls4nights
 
Russian Call girls in Dubai +971563133746 Dubai Call girls
Russian  Call girls in Dubai +971563133746 Dubai  Call girlsRussian  Call girls in Dubai +971563133746 Dubai  Call girls
Russian Call girls in Dubai +971563133746 Dubai Call girlsstephieert
 
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...tanu pandey
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl ServiceRussian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl Servicegwenoracqe6
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.soniya singh
 
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130  Available With RoomVIP Kolkata Call Girl Kestopur 👉 8250192130  Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Roomdivyansh0kumar0
 
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With RoomVIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Roomishabajaj13
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Sheetaleventcompany
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsThierry TROUIN ☁
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Roomdivyansh0kumar0
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Roomdivyansh0kumar0
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607dollysharma2066
 

Recently uploaded (20)

Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
 
Radiant Call girls in Dubai O56338O268 Dubai Call girls
Radiant Call girls in Dubai O56338O268 Dubai Call girlsRadiant Call girls in Dubai O56338O268 Dubai Call girls
Radiant Call girls in Dubai O56338O268 Dubai Call girls
 
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
Call Girls Dubai Prolapsed O525547819 Call Girls In Dubai Princes$
 
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptxAWS Community DAY Albertini-Ellan Cloud Security (1).pptx
AWS Community DAY Albertini-Ellan Cloud Security (1).pptx
 
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls KolkataRussian Call Girls in Kolkata Ishita 🤌  8250192130 🚀 Vip Call Girls Kolkata
Russian Call Girls in Kolkata Ishita 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With RoomVIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
VIP Kolkata Call Girls Salt Lake 8250192130 Available With Room
 
Russian Call girls in Dubai +971563133746 Dubai Call girls
Russian  Call girls in Dubai +971563133746 Dubai  Call girlsRussian  Call girls in Dubai +971563133746 Dubai  Call girls
Russian Call girls in Dubai +971563133746 Dubai Call girls
 
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...Pune Airport ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready...
Pune Airport ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready...
 
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl ServiceRussian Call girl in Ajman +971563133746 Ajman Call girl Service
Russian Call girl in Ajman +971563133746 Ajman Call girl Service
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
 
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130  Available With RoomVIP Kolkata Call Girl Kestopur 👉 8250192130  Available With Room
VIP Kolkata Call Girl Kestopur 👉 8250192130 Available With Room
 
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With RoomVIP Kolkata Call Girl Salt Lake 👉 8250192130  Available With Room
VIP Kolkata Call Girl Salt Lake 👉 8250192130 Available With Room
 
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
Call Girls Service Chandigarh Lucky ❤️ 7710465962 Independent Call Girls In C...
 
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Ashram Chowk Delhi 💯Call Us 🔝8264348440🔝
 
AlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with FlowsAlbaniaDreamin24 - How to easily use an API with Flows
AlbaniaDreamin24 - How to easily use an API with Flows
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
 
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Defence Colony Delhi 💯Call Us 🔝8264348440🔝
 
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
 
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
FULL ENJOY Call Girls In Mayur Vihar Delhi Contact Us 8377087607
 

Staying Sane with Drupal NEPHP

  • 1. Staying Sane with Drupal A Developer's Survival Guide Oscar Merida, @omerida Northeast PHP, Boston August 2015
  • 2. 80% of building sites with Drupal is configuration (easy) Credit: https://www.flickr.com/photos/jeepersmedia/12953571545/
  • 3. The hard part is the final 20% of customization • Functionality that is new to Drupal • or different than assumptions • Integration with external systems Credit: https://www.flickr.com/photos/jurvetson/15393495039
  • 4. Drupal is procedural • Not Object Oriented • Many structures like nodes, forms, users, etc use StdClass objects or arrays • Not MVC like other PHP frameworks • but there is separation of concerns between menu callbacks & theme layers • Hooks afford a way to alter existing functionality or implement new features. • Leverage hooks
  • 5. Play Well with Others • Don’t short circuit how things work. • If you're stuck, ask for help. • "Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live." • http://c2.com/cgi/wiki? CodeForTheMaintainer
  • 6. Use Drupal APIs • EntityFieldQuery • Form ArrayPI • node_load(), node_presave(), node_* hooks • Node Access System
  • 7. Dig into the Documentation • api.drupal.org has function definitions and examples. • Security - 
 https://www.drupal.org/writing-secure-code • Check Project Issue Queues
  • 9. Rules of the Road • Use Version Control (git, svn, etc.) • Use branches to manage workflow • Replicate production environment in a VM • Rule 0.1 - never edit files on live
  • 10. Follow Drupal's coding standard. • Everyone on the team must follow it. • https://www.drupal.org/coding-standards • Don't waste cycles arguing about which standard to follow. • Can use your IDE to follow a standard. • BONUS: Use PHP CodeSniffer to enforce it.
  • 11. Use Features • Drupal saves a lot of configuration to the database, • makes code sharing & deployments difficult. • Use Features + Strongarm modules to export settings to Features modules. • Create one Feature module for each Content Type or Function • Include related fields, Views, Display Suite settings, Panels & Pages, Contexts, Path aliases, Rules,etc. • Have a Base module with shared fields and global settings like input formats.
  • 12. Share Features • Track your modules in VCS • When you update codebase, check Features UI for Overrides and resolve them.
  • 13. Automate Deployments • As simple as having a simple script to sync files to your environments • Or automagically update dev, stage, production by pushing to the correct VCS branch • https://www.freelock.com/node/1108 • BUT remember to keep sensitive information out of VCS (like database credentials).
  • 14. Don't Fear the Command Line • Drush is faster and easier to automate than going through the UI. • Clearing caches - drush cc all • DB Snapshot - drush sql-dump > ../mydb.sql • Creating a user - drush user-create • Reindexing search - drush search-index
  • 15. Contrib makes life easy …except when it doesn’t.
  • 16. Focus on building new solutions. • Avoid “Not-invented-here” syndrome • There's a module for that. In fact, there's probably several … http://dilbert.com/strip/2014-08-11
  • 17. But with great power… • Inherit technical debt of a module. • Keep up-to-date with new releases, especially security releases. • Sometimes you don't need a module to change things.
  • 18. Evaluating a module • Does the maintainer have other modules? • Does it have a stable release? • Does it have recent commits? • Is the issue queue active? • Does it have good documentation?
  • 19. Practically core… • Views (is in D8) • Views Bulk Operations • Features & Strongarm • Pathauto & Token • Webform • Rules • Email • Link • Smart Trim • Redirect • Entity Reference • Entity API • Entity Cache
  • 20. Nice to Have • Bean (better Blocks) • Administration Views • Display Suite • Backup & Migrate • Content Locking • Menu Block • Revisioning • Add Another
  • 21. Migration tools • Feeds or Migrate • Pathologic • Views Data Export
  • 22. Views • GUI based Query Builder • Has its own terminology • Excels at building display output. • Not limited to HTML. https://commons.wikimedia.org/wiki/File:Tower_Optical_Binoculars.jpg
  • 23. Fields & Filters • Fields - the fields to return from the query • SELECT id, name, birthdate • Filters - conditions to select items • WHERE name=“smith”
  • 24. Contextual Filters • Apply filters based on external arguments. • Filter values usually come from the URL path. • Node ID • User ID • Term ID
  • 25. Relationships • Add a related table to the base query • JOIN groups ON (groups.id=users.group_id) • Can then pull in fields from other entites into Fields, Filters, and Contexts.
  • 26. Use an Existing View Programatically. • views_embed_view(): Useful for building custom blocks with logic while keeping them configurable in the Views UI. function mymodule_view() { $tid = (int) arg(2); $preferred = views_embed_view('dept_resources', 'block_1', $tid); // test if the view is empty by looking for view-empty class if (false !== strpos($preferred, 'class="view-empty"')) { $all = views_embed_view('dept_resources', 'block_2', $tid); $block['content'] = $all; } else { $block['content'] = $preferred; } return $block; }
  • 27. Views Hooks • Views API provides a number of hooks for changing a view. • hook_views_pre_view() • hook_views_pre_ender() • hook_views_query_alter() • and more! 
 https://api.drupal.org/api/views/views.api.php/group/views_hooks/7
  • 28. hook_views_pre_view() • Runs at start of processing. Useful for changing or cleaning up arguments. function foo_views_pre_view(&$view, &$display_id, &$args) { if ('map_legend' == $view->name) { // get location short name from aliased view pat // ex. "campus/fairfax-va" $shortname = parse_path_shortname(); // get the campus node with the matching shortname $node = foo_campus_lookup_shortname($shortname); $args[0] = $node->nid; } }
  • 29. hook_views_pre_render() • Runs at start of rendering. • Useful for changing titles, adding headers & footers, replacing placeholders. function foo_views_pre_render(&$view) { if ('campus_map' == $view->name) { if (isset($view->result[0]->nid)) { $node = $view->result[0]->_field_data['nid']['entity']; $view->set_title('Campuses for ' . $node->title); } return; }
  • 30. hook_views_query_alter() • Alter a query before it runs. • Helps deal with input edge cases. function foo_views_query_alter(&$view, &$query) { if ('campus_contacts' == $view->name) { if ('mid-state' == arg(2)) { $query->where[0]['conditions'][0]['value'] = 'Mid-State'; } } }
  • 31. but sometimes… • You need to query for a collection of Entities • In that case, use EntityFieldQuery • https://www.drupal.org/node/1343708 • Unless you're reading & writing your own custom tables, don't use db_query().
  • 32. function foo_lookup_shortname($short) { // now look up the node for this short to make sure it exists $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node') ->entityCondition('bundle', 'campus') ->propertyCondition('status', 1) ->fieldCondition('field_short_name', 'value', $short, '=') ->range(0, 1); $result = $query->execute(); if (!$result || empty($result)) { return false; } $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); $node = array_pop($nodes); // return first return $node; }
  • 34. Custom modules for: • Implementing hooks • Integration with 3rd party systems • Custom entities
  • 35. Use Permissions • hook_perm defines permissions • Check for custom permission in routes, views, etc. • Avoid checking for one or more roles. /** * Implements hook_permission(). */ function foo_email_digest_permission() { return array( 'administer foo digest' => array( 'title' => t('Administer FOO Digest'), 'description' => t('Manage Digest settings.'), ), ); }
  • 36. Use Node Grants • hook_node_grants defines what "realms" a user works with. • A user can belong to one or more groups in a realm. • https://www.phase2technology.com/ drupal-7-node-access-grants-locks- and-keys/ function foo_node_grants($account, $op) { $grants = array(); // If a user is an admin then grant access to all if (user_has_role('Site Admin', $account)) { $admin_nids = foo_get_workspace_nids(); $grants['workspace_member'] = $admin_nids; } else { $ws_nids = foo_get_users_ws_nids($account); // add the workspace nodes that the user // is an owner of too. $owner_nids = foo_get_owner_ws_nids($account); $grants['workspace_member'] = array_merge($ws_nids, $owner_nids); } return $grants; }
  • 37. Use Node Grants, pt 2 • hook_node_access_records control access to nodes. • Control user access for viewing, updating, deleting at the node-level. • Integrates with views and search results. function foo_node_access_records($n) { // don't clutter grants if ('resource' !== $n->type) { return; } $ws_nid = $n->field_workspace['und'][0]['target_id']; if (empty($ws_nid)) { return; } $grants = array(); $grants[] = array ( 'realm' => 'workspace_member', 'gid' => $ws_nid, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, ); return $grants; }
  • 38. Define custom pages for your module /** * Implements hook_menu(). */ function foo_email_digest_menu() { $items['admin/config/system/foo_digest'] = array( 'title' => 'FOO Daily Digest', 'description' => 'Administer FOO Digest settings.', 'page callback' => 'drupal_get_form', 'page arguments' => array('foo_digest_admin'), 'access arguments' => array('administer foo digest'), 'file' => 'foo_email_digest.admin.php', 'type' => MENU_NORMAL_ITEM, ); return $items; }
  • 39. Check Requirements Use hook_requirements to check installation requirements or report status. /** * Implements hook_requirements(). */ function foo_email_digest_requirements($phase) { if ('runtime' == $phase) { $toggle = variable_get('foo_digest_toggle', 'off'); if ('on' == $toggle) { $requirements['foo_digest_toggle'] = array( 'title' => 'FOO Digest Status', 'value' => check_plain($toggle), 'severity' => REQUIREMENT_OK, ); } else { $requirements['foo_digest_toggle'] = array( 'title' => 'FOO Digest Status', 'value' => check_plain($toggle), 'severity' => REQUIREMENT_WARNING, ); }
  • 40. Expose tasks via Drush • Make functionality available via drush • http://www.drush.org/en/ master/commands/ • Can then execute them in Terminal • easier to schedule via cron too /** * Implements hook_drush_command(). */ function foo_email_digest_drush_command() { $items['foo-digest-send'] = array( 'description' => 'Send email digest.', 'aliases' => array('foodig'), ); return $items; } function drush_foo_email_digest_foo_digest_send() { foo_digest_send(); }
  • 41. Best Practices • Create an admin settings form • Keep editable settings outside of code • Consider having switches to toggle functionality on/off • Provide theme functions • Themes and other modules can override rendered display
  • 42. Key Global Functions • t() • check_plain() • filter_xss • arg() • current_path() • menu_get_item() • drupal_goto() • drupal_deny_access() • get_current_user() • drupal_message()
  • 43. Basics • t() - Output a translatable string with replacements • check_plain() - Output sanitized text. Important if you’re taking user input and displaying it. • filter_xss() - Output sanitized text, allow some HTML tags. Important if you’re taking user input and displaying it. • See also filter_admin_xss() • arg() - Get an argument from the URL path. Remember to filter input!
  • 44. get_current_user() • Retrieve the user object for the current user. • Better than global $user; <?php function foo() { $user = get_current_user(); if (0 == $user->uid) { drupal_goto('user/login'); } }
  • 45. current_path() • Returns the current unaliased path. Useful if a hook should only run on one or more specific paths. if ('node/15' == current_path()) { // customize this node } if ('publications' == current_path()) { // customize this node }
  • 46. drupal_get_path_alias() • Returns the aliased path for an internal path. // check alias of current page $alias = drupal_get_path_alias(); if ('about' == $alias) { // customize the 'About Us' page }
  • 47. menu_get_item() • Returns the currents menu item path. Similar to current_path(), easier to test if something should only run on a set of pages. $menu = menu_get_item(); // make sure we're on any user profile page if ('user/%' !== $menu['path']) { return }
  • 48. drupal_goto() • Redirect client to another URL. Allows other modules to rewrite paths. if (0 == $user->uid) { drupal_goto('user/login'); }
  • 49. drupal_deny_access() • Show an access denied message. if (0 == $user->uid) { drupal_deny_access(); }
  • 50. drupal_set_message() • Display success, warning, or error messages to client (web or Drush). <?php function foo() { $node = node_load('node/' . $nid); // ...do some stuff to $node // something went wrong drupal_set_message( 'Could not use node', 'warning', // status|warning|error ); }
  • 51. Thank You. Questions? • Follow me @omerida • Slides: • http://phpa.me/drupal-sane-nephp • Feedback: • https://joind.in/talk/view/14727 • Editor-in-chief of php[architect] • Check out http://world.phparch.com