Horrible Truth 1 “Drupal is written in PHP, which is uttterly offensive to people.” Horrible Truth 2 “Drupal loads too much code” -rasmus Is Drupal too Modular? Horrible Truth 4 “Drupal is basically a 404 page to which you can add modules”” drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); index.php includes/bootstrap.inc - load necessary functions drupal_page_header() starts timer, sets up caching, module callout includes/common.inc - utility functions such as path formatting functions, form generation and validation, etc. fix_gpc_magic() sets $status 404 switch - case Not Found case Access Denied drupal_page_footer() drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); drupal_load() drupal_not_found(); drupal_access_denied(); drupal_site_offline(); $return = menu_execute_active_handler(); print theme('page', $return); drupal_page_footer(); What's on the menu api? MENU_CALLBACK MENU_DEFAULT_LOCAL_TASK MENU_LOCAL_TASK MENU_MAX_DEPTH MENU_MAX_PARTS MENU_NORMAL_ITEM MENU_SUGGESTED_ITEM MENU_CALLBACK MENU_DEFAULT_LOCAL_TASK MENU_LOCAL_TASK MENU_MAX_DEPTH MENU_MAX_PARTS MENU_NORMAL_ITEM MENU_SUGGESTED_ITEM Scream API Horrible Truth 7 The Dreaded Hooks of Torture Hooks of Torture • to implement a hook, create a function that 'extends' hooks into an existing hook (“hook function”) • not functions but can be overloaded • call user function array used to make dynamic function calls module_invoke_all <?php function module_invoke_all() { $args = func_get_args(); $hook = $args[0]; unset($args[0]); $return = array(); foreach (module_implements($hook) as $module) { $function = $module .'_'. $hook; $result = call_user_func_array($function, $args); hook_admin /** * channels_admin * implements hook_admin * Provides channels admin form to save settings for the following fields: * */ function channels_admin() { $form['channels'] = array( '#type' => 'textfield', '#title' => t('Channel'), hook_perms /** * Implements hook_perm(). */ function channels_perm() { return array( 'access channel content', 'administer channels', ); } hook_menu /** * Implements hook_menu(). anne/ function channels_menu() { $items = array(); $items['admin/settings/channels'] = array( 'title' => 'channel settings', 'description' => 'select channel', 'page callback' => 'drupal_get_form', 'page arguments' => hook_block /** * Implementation of hook_block(). */ function channels_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': $blocks[0]['info'] = t('current_channel'); return $blocks; case 'view': $totals = _channels_get_theme(); hook_menu_alter /** Implementation of hook_menu_alter(). */ function noaccess_menu_alter(&$items) { $items['node']['access arguments'] = array('access node path'); } /** Implementation of hook_perm(). function noaccess_perm() { return array('access node path'); */ Hook Soup Does Drupal have a Learning Curve... …or a Learning Brick Wall ? “Community Plumbing” Product! Framework! Drupal is a Pushme - Pullyou Field API What's a Node? Horrible Truth 9 “Drupal Isn't 'Classy”'? H o r r i b l e T r u t h 10 “Drupal isn't Object Oriented?” DRUPAL DESIGN PATTERN Drupal Design Pattern REALITY CHECK. Drupal Design Pattern Drupal Anti-Pattern “Load Everything then Cherry Pick What You Need.” H o r r i b l e T r u t h 11 Drupal Encourages Slavery Making Drupal “Slave Safe!” Actions* & Triggers *(not slave safe) Database TNG Performance & Scaling Sample Metrics from a large Drupal site: 50 million page views per month 6.5 million site visitors per month 150,000 page views per hour load tests to levels of greater than 500,000 page views per hour Drupal.org delivers approximately 1M/day/month Object Caching APC Advantages Low latency No need to serialize/unserialize items Scales perfectly with more web servers Disadvantages No enforced consistency across multiple web servers Cache is not shared; each web server must generate each item memcached Advantages Consistent across multiple web servers Cache is shared across all web servers; items only need to be generated once Disadvantages High latency Requires serializing/unserializing items Easily shards data across multiple web servers, but is still a big, shared cache Cache Headers drush * Download and enable devel module: drush dl devel drush enable devel * Run cron: drush cron * Refresh modules and core updates informartion: drush refresh * Take a snapshot of the DB: drush sql dump > mydb.sql * Open a mysql console for running SQL commands into Drupal DB: drush drush_make core = "7.x" projects[] = "drupal" projects[] = "acquia_connector" projects[apachesolr][download][type] = "cvs" projects[apachesolr][download][module] = "contributions/modules/apachesolr" projects[apachesolr][download][revision] = "DRUPAL-7--0" projects[acquia_search][type] = "module" projects[acquia_search][download][type] = "svn" projects[acquia_search][download][url] = "https://svn.acquia.com/drupal/branches/1.x7.x/modules/acquia/acquia_search/" libraries[SolrPhpClient][download][type] = "get" libraries[SolrPhpClient][download][url] = "http://solr-phpclient.googlecode.com/files/SolrPhpClient.r22.2009-11-09.tgz" libraries[SolrPhpClient][destination] = "modules/apachesolr" Automated Backup touch ~/.logrotate.state ~/.logrotate.config emacs ~/.logrotate.config ~/backup/dev.sql.gz { rotate 7 daily nocompress nocopytruncate