Skip to content
Snippets Groups Projects
unl.module 45.7 KiB
Newer Older
require_once dirname(__FILE__) . '/includes/common.php';

/**
 * Implementation of hook_entity_info_alter().
 */
function unl_entity_info_alter(&$entity_info) {
  // Add additional view_mode to admin/structure/types/manage/CONTENTTYPE/display for an abbriviated teaser (for use in sidebars, etc)
  $entity_info['node']['view modes']['abbr_teaser'] = array(
    'label' => t('Abbriviated teaser'),
    'custom settings' => TRUE,
  );
}

 * Implementation of hook_html_head_alter().
 */
function unl_html_head_alter(&$head_elements) {
  // If <link rel="home"> has already been set elsewhere (in a Context for example) then return...
  foreach ($head_elements as $key => $element) {
    if ($element["#tag"] == 'link' && isset($element['#attributes']['rel']) && $element['#attributes']['rel'] == 'home') {
      return;
    }
  }
  // If we are in a drilled down menu, change the home link to the drilled down item.
  $current_menu_link = _unl_get_current_menu_link();
  if ($current_menu_link && $current_menu_link->depth > 1) {
    $home_path = drupal_get_path_alias($current_menu_link->link_path);
  }
  else {
    $home_path = '<front>';
  }
  // ...otherwise add a <link rel="home"> tag with the front page as the href attribute
  $element = array(
    '#tag' => 'link',
    '#attributes' => array(
      'rel' => 'home',
      'href' => url($home_path, array('absolute' => TRUE)),
    ),
    '#type' => 'html_tag'
  );
  $head_elements['drupal_add_html_head_link:home'] = $element;
}

/**
 * Implementation of hook_context_plugins(). (Context module)
 */
function unl_context_plugins() {
  $plugins = array();
  $plugins['unl_context_reaction_linkrelhome'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'unl') .'/plugins',
      'file' => 'unl_context_reaction_linkrelhome.inc',
      'class' => 'unl_context_reaction_linkrelhome',
      'parent' => 'context_reaction',
    ),
  );
  $plugins['unl_context_reaction_blockremove'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'unl') .'/plugins',
      'file' => 'unl_context_reaction_blockremove.inc',
      'class' => 'unl_context_reaction_blockremove',
      'parent' => 'context_reaction',
    ),
  );
  return $plugins;
}

/**
 * Implementation of hook_context_registry(). (Context module)
 */
function unl_context_registry() {
  return array(
    'reactions' => array(
      'linkrelhome' => array(
        'title' => t('link rel="home" tag'),
        'plugin' => 'unl_context_reaction_linkrelhome',
      ),
      'blockremove' => array(
        'title' => t('Block Remove'),
        'plugin' => 'unl_context_reaction_blockremove',
      ),
    ),
  );
}

/**
 * Implementation of hook_context_page_reaction(). (Context module)
 */
function unl_context_page_reaction() {
  if ($plugin = context_get_plugin('reaction', 'linkrelhome')) {
    $plugin->execute();
  }
}

/**
 * Implementation of hook_page_build().
 */
function unl_page_build(&$page) {
  if (module_exists('context')) {
    if ($plugin = context_get_plugin('reaction', 'blockremove')) {
      $plugin->execute($page);
    }
    // See block_page_build. Clear static cache b/c in overlay form submissions
    // hook_page_build can get called more than once per page load.
    drupal_static_reset('context_reaction_block_list');
  }
}

/**
 * Implementation of hook_field_attach_view_alter().
 */
function unl_field_attach_view_alter(&$output, $context) {
  // Replace the field named field_hrorgunit containing an org unit number with that unit's listing from the UNL directory
  foreach (element_children($output) as $field_name) {
    $element = &$output[$field_name];
    switch ($element['#field_name']) {
      case 'field_hrorgunit':
        $result = file_get_contents('http://directory.unl.edu/departments/?view=deptlistings&org_unit='.$element['#items'][0]['value'].'&format=partial');
        if (!empty($result) && $result != '<div id="all_employees"></div>') {
          drupal_add_css('http://directory.unl.edu/css/peoplefinder_default.css', 'external');
          drupal_add_js('http://directory.unl.edu/scripts/peoplefinder.js', 'external');
          drupal_add_js('var PF_URL = "http://directory.unl.edu/", ANNOTATE_URL = "http://annotate.unl.edu/";', 'inline');
          // Need to check to see if directory.unl.edu only returned a partial result. If so, result will have a message in between the closing ul and div tags like so: </ul><p>Try refining your search.</p></div></div>
          if (!preg_match('/<\/ul>\s*\n*\s*<\/div><\/div>/', $result)) {
            // Extra message at the bottom indicating not all results returned - hide it
            drupal_add_css('#all_employees > * > p {display:none;}', 'inline');
            // Alert the user to visit the directory site
            drupal_add_js('jQuery(document).ready(function(){jQuery("#all_employees .result_head").css("font-size","13px").html("We\'re a big department! Partial listing shown below, please visit <a href=\"http://directory.unl.edu/departments/'.$element['#items'][0]['value'].'#all_employees\">our department lisiting on the UNL Directory</a> to see everyone.");});', 'inline');
          }
        }
        else {
          $result = '<p>Please visit the <a href="http://directory.unl.edu/">UNL Directory</a> for listings.</p>';
        }
        foreach ($element['#items'] as $delta => $item) {
          $element[$delta]['#markup'] = $result;
        }
        break;
      default:
    }
  }
}

/**
 * Implementation of hook_node_access().
 */
function unl_node_access($node, $op, $account) {
  // When content types are created they have blank permissions so base access on the 'Basic page' type. This is done because with shared permissions subsites can't edit permissions.
  //@TODO Make this configureable i.e. make it possible to opt-out certain types from this.
  switch($op) {
    case 'view':
      break;
    case 'create':
      return user_access('create page content', $account) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
    case 'update':
      if (isset($node->uid) && $node->uid == $account->uid) {
        return user_access('edit own page content', $account) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
      }
      return user_access('edit any page content', $account) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
    case 'delete':
      if (isset($node->uid) && $node->uid == $account->uid) {
        return user_access('delete own page content', $account) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
      }
      return user_access('delete any page content', $account) ? NODE_ACCESS_ALLOW : NODE_ACCESS_IGNORE;
  }
}

function unl_node_prepare($node) {
/**
 * Implementation of hook_wywiwyg_plugin() found in wysiwyg.api.php
 */
function unl_wysiwyg_plugin($editor) {
  switch ($editor) {
    case 'tinymce':
      return array(
        'unl' => array(
          // A URL to the plugin's homepage.
          'url' => 'http://gforge.unl.edu/gf/project/wdn_tinymce/',
           // The full path to the native editor plugin.
          'path' => $editor['library path'] . '/plugins/unl',
          // A list of editor extensions provided by this native plugin.
          // Extensions are not displayed as buttons and touch the editor's
          // internals, so you should know what you are doing.
          'extensions' => array(
            'unl' => 'UNL Extension'
          ),
          // Boolean whether this plugin is a native plugin, i.e. shipped with
          // the editor. Definition must be ommitted for plugins provided by
          // other modules.
          'internal' => TRUE,
          // Boolean whether the editor needs to load this plugin. When TRUE,
          // the editor will automatically load the plugin based on the 'path'
          // variable provided. If FALSE, the plugin either does not need to
          // be loaded or is already loaded by something else on the page.
          // Most plugins should define TRUE here.
          'load' => TRUE,
          // A list of buttons provided by this native plugin. The key has to
          // match the corresponding JavaScript implementation. The value is
          // is displayed on the editor configuration form only.
          'buttons' => array(
            'unlZenBox'   => 'UNL Zen Box',
            'unlZenTable' => 'UNL Zen Table',
            'unlGrid'   => 'UNL Grid',
            'unlLayout'   => 'UNL Layout',
            'unlTooltip'  => 'UNL Tooltip',
          ),
          // A list of global, native editor configuration settings to
          // override. To be used rarely and only when required.
          'options' => array(
            'skin' => 'unl',
            'table_styles' => 'ZenTable Bright (yellow)=zentable bright;ZenTable Cool (blue)=zentable cool;ZenTable Energetic (orange)=zentable energetic;ZenTable Soothing (green)=zentable soothing;ZenTable Primary (red)=zentable primary;ZenTable Neutral (gray)=zentable neutral;', 'doctype' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
            'valid_elements' => '*[*],script[charset|defer|id|src|type=text/javascript]',
          ),
        )
        // Wysiwyg wrapper plugin AJAX callback.
        // 'callback' => url('myplugin/browse'),
        // 'icon' => drupal_get_path('module', 'mymodule') . '/myplugin/myplugin.png',
        // Might need to be set later on; after retrieving customized editor
        // layout.
        //'theme_advanced_buttons1' => array(t('Button title (optional)') => 'myplugin'),
      );
  }
/**
 * Implementation of hook_permission().
 */
function unl_permission() {
  return array(
    'unl migration' => array(
      'title'       => t('Migration'),
      'description' => t('Migrate UNL Template based sites to drupal'),

    'unl site creation' => array(
      'title'       => t('Site Creation'),
      'description' => t('Create new drupal sites using the UNL profile'),
    'unl grant all permissions' => array(
      'title'       => t('Grant All Permissions'),
      'description' => t('If this is not checked, a user can only grant permissions that they themselves have. Requires the "Administer permissions" permission.'),
    'unl administer administrator permissions' => array(
      'title'       => t('Administer Administrator\'s Permissions'),
      'description' => t('If this is not checked, a user can not change the permissions of the administrator role. Requires the "Administer permissions" permission.'),
      'restrict access' => TRUE,
    'unl theme settings' => array(
      'title'       => t('Change Theme Settings'),
      'description' => t('Allow this role to change the current theme settings.'),
    ),

    'unl imce javascript upload' => array(
      'title'       => t('Upload Javascript Files Through IMCE'),
    ),
/**
 * Implements hook_preprocess_page().
 */
function unl_preprocess_page(&$vars) {
  switch (current_path()) {
    case 'admin/modules':
      if (!unl_user_is_administrator()) {
        // Changed here rather than using hook_help because the later merely appends to the existing text.
        $vars['page']['help']['system_help']['#markup'] = '<p>Not all modules can be turned on/off. If you have questions about modules on this page or modules not yet part of the UNL project contact an administrator.</p>';
      }
  }
}

 * Implementation of hook_menu().
function unl_menu() {
  global $user;

  $items = array();

  // Returns confirmation 'user_loggedin' if user is logged into the system
   $items['user/unl/whoami'] = array(
    'title' => 'UNL Whoami Tool',
    'access callback' => TRUE,
    'page callback' => 'unl_whoami',
    'file' => 'unl_whoami.php',

  // Returns html technical feedback form
  $items['user/unl/technical_feedback'] = array(
    'title' => 'Technical Feedback',
    'description' => 'Returns a form to fill out to give technical feedback',
    'access callback' => TRUE,
    'page callback' => 'technical_feedback',
    'file' => 'technical_feedback.php'
  // Adds UNL Migration Tool to the Content menu for admin
  $items['admin/content/unl/migration'] = array(
    'title'            => 'UNL Migration Tool',
    'description'      => 'Migrate a static UNL template page into drupal',
    'access arguments' => array('unl migration'),
    'page callback'    => 'drupal_get_form',
    'page arguments'   => array('unl_migration'),
    'type'             => MENU_LOCAL_TASK,
    'file'             => 'unl_migration.php',
  );
  $items['admin/content/unl/reset'] = array(
    'title'            => 'Reset Site',
    'description'      => 'Remove all nodes, menu items, etc from this site.',
    'access callback'  => 'unl_user_is_administrator',
    'page callback'    => 'drupal_get_form',
    'page arguments'   => array('unl_reset_site'),
    'type'             => MENU_LOCAL_TASK,
    'file'             => 'includes/reset_site.php',
  );
  // Redirect the Appearance link away from admin/appearance for users who can't Administer themes but can Change Theme Settings
  $items['admin/themes'] = array(
    'title' => 'Appearance',
    'description' => 'Configure your theme.',
    'access callback' => 'unl_user_access',
    'access arguments' => array(array('!administer themes', 'unl theme settings')),
    'page callback' => 'drupal_get_form',
    'position' => 'left',
    'weight' => -6,
  );
  // Hello world type page for performance/uptime monitoring
  $items['_status'] = array(
    'title'           => 'Still Alive',
    'page callback'   => 'unl_still_alive',
    'access callback' => TRUE,
  );
  $items['admin/config/system/unl'] = array(
    'title'            => 'UNL',
    'description'      => 'Configure UNL System Settings',
    'access callback'  => 'unl_user_is_administrator',
    'page callback'    => 'drupal_get_form',
    'page arguments'   => array('unl_config'),
    'file'             => 'includes/unl.admin.inc',
    'weight'	       => 1,
  );
  if (module_exists('imce')) {
    // Add IMCE file browser to Content section
    $items['admin/content/imce-file-browser'] = array(
      'title' => 'File browser',
      'page callback' => 'imce_user_page',
      'page arguments' => array($user->uid),
      'access callback' => '_unl_imce_file_browser_access',
      'file' => 'inc/imce.page.inc',
      'file path' => drupal_get_path('module', 'imce'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -10,
    );
    // Add IMCE file browser to Add content list
    $items['node/add/imce-file-upload'] = array(
      'title' => 'File upload',
      'description' => 'Upload files from your computer, such as PDF documents, to the file system.',
      'page callback' => 'imce_user_page',
      'page arguments' => array($user->uid),
      'access callback' => '_unl_imce_file_browser_access',
      'file' => 'inc/imce.page.inc',
      'file path' => drupal_get_path('module', 'imce'),
      'type' => MENU_NORMAL_ITEM,
    );
  }

  if (conf_path() == 'sites/default') {
    $items['admin/sites/unl'] = array(
      'title'            => 'UNL Site Creation Tool',
      'description'      => 'Create and manage UNL Drupal sites and aliases.',
      'access arguments' => array('unl site creation'),
      'type'             => MENU_LOCAL_TASK,
      'file'             => 'unl_site_creation.php',
    );
    $items['admin/sites/unl/sites'] = array(
      'title'       => 'Sites',
      'description' => 'Create and manage UNL Drupal sites.',
      'type'        => MENU_DEFAULT_LOCAL_TASK,
      'weight'      => -8,
    );
    $items['admin/sites/unl/%/delete'] = array(
      'title' => 'Delete site',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('unl_site_delete_confirm', 3),
      'access arguments' => array('unl site creation'),
      'file' => 'unl_site_creation.php',
    );

    $items['admin/sites/unl/aliases'] = array(
      'title'            => 'Aliases',
      'description'      => 'Manage aliases of UNL Drupal sites.',
      'access arguments' => array('unl site creation'),
      'page callback'    => 'unl_aliases_page',
      'type'             => MENU_LOCAL_TASK,
      'file'             => 'unl_site_creation.php',
    );
    $items['admin/sites/unl/user-audit'] = array(
      'title'            => 'User Audit',
      'description'      => 'Find out which sites users have access to.',
      'access arguments' => array('unl site creation'),
      'page callback'    => 'drupal_get_form',
      'page arguments'   => array('unl_user_audit'),
      'type'             => MENU_LOCAL_TASK,
      'file'             => 'unl_site_creation.php',
    );

    $items['admin/sites/unl/wdn_registry'] = array(
      'title'            => 'WDN Registry',
      'description'      => 'Settings for the connection to the WDN Registry.',
      'access arguments' => array('unl site creation'),
      'page callback'    => 'drupal_get_form',
      'page arguments'   => array('unl_wdn_registry'),
      'type'             => MENU_LOCAL_TASK,
      'file'             => 'unl_site_creation.php',
    );
    $items['admin/sites/unl/feed'] = array(
      'page callback'   => 'unl_sites_feed',
      'access callback' => TRUE,
      'file'            => 'unl_site_creation.php',
    );
  return $items;
/**
 * Implementation of hook_menu_alter().
 */
function unl_menu_alter(&$items) {
  // This duplicates the form at admin/appearance/settings/unl_wdn for roles that can't 'administer themes' but have 'unl theme settings' permission.
  // For these users the Appearance link is changed to point to admin/themes
  foreach (array('module', 'file', 'page arguments') as $key) {
    $items['admin/themes'][$key] = $items['admin/appearance/settings/' . variable_get('theme_default')][$key];
  }
  // Put all user pages in the admin theme
  $items['user']['theme callback'] = '_unl_get_admin_theme';
  // Make sure all Workbench Moderation admin pages are in the admin theme
  if (module_exists('workbench_moderation')) {
    $items['node/%node/moderation']['theme callback'] = '_unl_get_admin_theme';
    $items['node/%node/moderation/%/unpublish']['theme callback'] = '_unl_get_admin_theme';
  }
 * Implementation of hook_file_validate().
 * Fires when files are uploaded after Drupal Core sanitization but before saving to file system or db
 */
function unl_file_validate($file) {
  // For IMCE uploads only, check if Drupal core just altered a *.js upload to *.js.txt and correct if permitted
  if ($file->source == 'imce' && substr($file->filename, -7) == '.js.txt' && user_access('unl imce javascript upload')) {
    // Chop off the .txt extesnsion that's been added
    $file->destination = substr($file->destination, 0, -4);
    $file->filename = substr($file->filename, 0, -4);
  }
  return;
}

/**
 * Implementation of hook_form_FORM_ID_alter() for field_ui_display_overview_form.
 */
function unl_form_field_ui_display_overview_form_alter(&$form, &$form_state, $form_id) {
  // Add additional label display options in Manage Display section of content type editing (admin/structure/types/manage/content-type/display)
  foreach ($form['#fields'] as $key => $field) {
    $form['fields'][$field]['label']['#options'] += array('h2'=>'Block: h2','h3'=>'Block: h3','h4'=>'Block: h4','h5'=>'Block: h5','h6'=>'Block: h6');
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter() for system_modules.
 */
function unl_form_system_modules_alter(&$form, &$form_state, $form_id) {
  // Whitelist of modules that Site Admin are allowed to turn on and off on admin/modules
  $modules = array('aggregator', 'blog', 'book', 'comment', 'translation', 'dashboard', 'forum', 'help', 'list', 'locale', 'number', 'taxonomy', 'trigger', // Core on this line, Contrib below
                   'action_email_role', 'context', 'context_layouts', 'context_ui', 'features', 'unl_news', 'imce', 'imce_mkdir', 'imce_rename', 'menu_block', 'menu_block_export',
                   'form_builder', 'form_builder_webform_ui', 'webform', 'webform_alt_ui',
                   'workbench', 'workbench_access', 'workbench_files', 'workbench_media', 'workbench_moderation');

  if (!unl_user_is_administrator() && isset($form['modules'])) {
    foreach ($form['modules'] as $category_name => $category) {
      if (is_array($category)) {
        foreach ($category as $module_name => $module) {
          if (!in_array($module_name, $modules) && substr($module_name,0,1) !== '#') {
            $form['modules'][$category_name][$module_name]['#disabled'] = true;
          }
        }
      }
    }
  }
}

/**
 * Implementation of hook_form_alter().
 */
function unl_form_alter(&$form, $form_state, $form_id) {
  // Make new menu items expanded by default.
  if ($form_id == 'menu_edit_item' && $form['mlid']['#value'] == 0) {
    $form['expanded']['#default_value'] = TRUE;
  }
  if ($form_id == 'system_site_information_settings') {
    $form['site_information']['https'] = array(
      '#type' => 'checkbox',
      '#title' => 'SSL Enabled',
      '#default_value' => variable_get('https', FALSE),
    );
    if (conf_path() != 'sites/default') {
      $alternate_uris = unl_get_alternate_base_uris();
      $base_urls = array('_null' => '--Select One--');
      foreach ($alternate_uris as $alternate_uri) {
        $base_urls[$alternate_uri] = $alternate_uri;
      };
      $form['site_information']['unl_primary_base_url'] = array(
        '#title' => 'Primary Base URL',
        '#type' => 'select',
        '#options' => $base_urls,
        '#default_value' => variable_get('unl_primary_base_url'),
      );
      $form['#submit'][] = 'unl_system_settings_form_submit';
    }
  // Modifications for non-administrators
  $admin_role_id = unl_shared_variable_get('user_admin_role', -1);
  if (!in_array($admin_role_id, array_keys($GLOBALS['user']->roles))) {
    switch ($form_id) {
      // Don't allow editing of non-custom content types on admin/structure/types, i.e. don't allow subsites to edit the content types coming from modules or the UNL shared content types
//       case 'node_type_form' :
//       case 'field_ui_field_overview_form' :
//       case 'field_ui_display_overview_form' :
//         if (!$form['custom']['#value']) {
//           drupal_access_denied();
//           exit;
//         }
//         break;
      // Add additional validation on admin/people/permissions/roles/edit/%
      case 'user_admin_role' :
        $form['#validate'][] = 'unl_user_admin_role_validate';
        break;
      // Hide administrator role on admin/people/permissions/roles
      case 'user_admin_roles' :
        foreach ($form['roles'] as $key => $role) {
          if (isset($role['#role']->rid) && $role['#role']->rid == $admin_role_id) {
            unset($form['roles'][$key]);
          }
        break;
      // Hide administrator column on admin/people/permissions
      case 'user_admin_permissions' :
        if (!user_access('unl grant all permissions')) {
          // Remove permissions this user doesn't have from the headings list.
          foreach ($form['permission'] as $permission => $sub_form) {
            if (is_int($permission)) {
              continue;
            }
            if (!user_access($permission)) {
              unset($form['permission'][$permission]);
            }
          }

          // Remove any empty permission section headings.
          $permission_sections = array_keys($form['permission']);
          foreach ($permission_sections as $index => $permission_section) {
            if (!is_int($permission_section)) {
              continue;
            }
            if (!isset($permission_sections[$index + 1]) || is_int($permission_sections[$index + 1])) {
              unset($form['permission'][$permission_section]);
            }
          }

          // Remove the permissions this user doesn't have from the checkboxes list.
          foreach ($form['checkboxes'] as $role_id => $sub_form) {
            foreach ($sub_form['#options'] as $permission => $value) {
              if (!user_access($permission)) {
                unset($form['checkboxes'][$role_id]['#options'][$permission]);
              }
            }

        // Unset the administrator checkbox column if user can't administer administrator permissions
        if (!user_access('unl administer administrator permissions')) {
          unset($form['role_names'][$admin_role_id]);
          unset($form['role_names']['#value'][$admin_role_id]);
          unset($form['checkboxes'][$admin_role_id]);

        // Make these settings unavailable even if they are enabled for the user
        $administrator_permissions = array(
          'unl administer administrator permissions',
          'unl site creation',
          'administer modules',
          'administer themes',
          'administer software updates',
          'administer imce',
          'administer filters',
        );
        foreach ($form['permission'] as $permission => $sub_form) {
          if (in_array($permission, $administrator_permissions)) {
            unset($form['permission'][$permission]);
        foreach ($form['checkboxes'] as $admin_role_id => $sub_form) {
          foreach ($sub_form['#options'] as $permission => $value) {
            if (in_array($permission, $administrator_permissions)) {
              unset($form['checkboxes'][$admin_role_id]['#options'][$permission]);
            }
          }
        }
        break;
      default :
        break;
  /**
   * On the node edit form, hide the "Provide a menu link" checkbox since we'll
   * be using the menu to build a site hierarchy.  Instead, add a button that will
   * determine whether or not the menu link is visible or not.
    $form['menu']['#title'] = 'Site hierarchy';
    $form['menu']['enabled']['#default_value'] = TRUE;
    $form['menu']['enabled']['#prefix'] = '<div style="display: none;">';
    $form['menu']['enabled']['#suffix'] = '</div>';
    $form['menu']['link']['link_title']['#required'] = TRUE;
    $mlid = $form['menu']['link']['mlid']['#value'];
    if ($mlid) {
      $menu_link = menu_link_load($mlid);
      $default_visible = ($menu_link['hidden'] ? 0 : 1);
    }
    else {
      $default_visible = 0;
    }
    $form['menu']['visible'] = array(
      '#type' => 'checkbox',
      '#title' => 'Display in menu',
      '#default_value' => $default_visible,
      '#weight' => 0,
    );
    $form['actions']['submit']['#submit'][] = 'unl_node_form_submit';
    // Also turn on revisioning by default
    $form['revision_information']['revision']['#default_value'] = TRUE;
    unset($form['revision_information']['revision']['#states']);
    // Also hide the "Promoted to front page" option
    $form['options']['promote']['#prefix'] = '<div style="display:none;">';
    $form['options']['promote']['#suffix'] = '</div>';
  // Add the Roles checkboxes to the user edit form for users with ability to 'Administer users' but not 'Administer permissions' (Code below partially taken from user.module)
  if (in_array($form_id, array('user_register_form', 'user_profile_form')) && user_access('administer users') && !user_access('administer permissions')) {
    $roles = array_map('check_plain', user_roles(TRUE));
    // Unset the adminsitrator checkbox, validation code that prevents a user who is not an administrator from granting the administrator role is in the unl_cas module
    unset($roles[$admin_role_id]);
    $form['account']['roles']['#options'] = $roles;
    $form['account']['roles']['#access'] = !empty($roles);
 * Implementation of hook_node_form_submit().
  // When a node is modified, update its menu link to be hidden or not based on the user input.
  $menu_data = $form_state['values']['menu'];

  if ($menu_data['mlid']) {
    $menu_link = menu_link_load($menu_data['mlid']);
  }
  else {
    list($parent_menu_name, $parent_mlid) = explode(':', $menu_data['parent']);
    $menu_links = menu_load_links($parent_menu_name);
    foreach ($menu_links as $menu_link) {
      if ($menu_link['plid'] != $parent_mlid) {
        continue;
      }
      if ($menu_link['link_path'] != 'node/' . $form_state['values']['nid']) {
        continue;
      }
      break;
    }
  }
  $menu_link['hidden'] = $menu_data['visible'] ? 0 : 1;
  menu_link_save($menu_link);
/**
 * Implementation of hook_system_settings_form_submit().
 */
function unl_system_settings_form_submit($form, &$form_state) {
  variable_set('https', (bool) $form_state['values']['https']);
  if ($form_state['values']['unl_primary_base_url'] != '_null') {
    variable_set('unl_primary_base_url', $form_state['values']['unl_primary_base_url']);
  }
  else {
    variable_del('unl_primary_base_url');
  }
/**
 * Implementation of hook_theme().
 */
function unl_theme() {
  return array(
    'unl_table' => array(
/**
 * Implementation of hook_url_outbound_alter().
 */
function unl_url_outbound_alter(&$path, &$options, $original_path) {
  $path_parts = parse_url($path);
  if (isset($path_parts['scheme']) || $path == 'user/cas') {
    return;
  }
  $user = $GLOBALS['user'];
  $user_roles = array_keys($user->roles);
  $generic_user = TRUE;
  foreach ($user_roles as $user_role) {
    if (in_array($user_role, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
      continue;
    }
    $generic_user = FALSE;
  }
  if (isset($options['https'])) {
    return;
  }
  $options['https'] = (bool) (variable_get('https', 0) && !$generic_user);
}
/**
 * Custom function for implementing user_access for multiple permissions.
 * Feature request: http://drupal.org/node/216897
 */
function unl_user_access($permissions, $account = NULL) {
  foreach ($permissions as $permission) {
    if (substr($permission, 0, 1) == '!') {
      $permission = substr($permission, 1);
      $result = !user_access($permission, $account);
    }
    else {
      $result = user_access($permission, $account);
    }
    if (!$result) {
      return FALSE;
    }
  }
  return TRUE;
}
 * Custom function for additional validation on the user_admin_role form (admin/people/permissions/roles/edit/%)
 * to prevent a user from deleting the administrator role. (This is not needed if permissions are shared and only administrators can edit roles.)
 */
function unl_user_admin_role_validate($form, &$form_state) {
  $admin_role_id = unl_shared_variable_get('user_admin_role', -1);

  if ($form_state['values']['op'] == t('Delete role')) {
    $role = user_role_load_by_name($form_state['values']['name']);
    if ($role && $role->rid == $admin_role_id) {
      form_set_error('name', t('The role name %name can not be deleted. Seriously dude. Seriously.', array('%name' => $form_state['values']['name'])));
    }
  }
}

/**
 * Implementation of hook_cron().
 */
function unl_cron() {
  _unl_cron_migration_step();
  _unl_cron_import_wdn_registry_sites();
}

/**
 * If a site is being migrated via cron jobs, do some work towards that migration.
 */
function _unl_cron_migration_step() {
  // We don't want this running as system user, only the web user.
  if (PHP_SAPI == 'cli') {
    return;
  }
  $queue = DrupalQueue::get('unl_migration');
  if ($queue->numberOfItems() > 0) {
    require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'unl_migration.php';
    $item = $queue->claimItem(120);
    $queue->deleteItem($item);
    if (unl_migration_queue_step($item->data)) {
      unl_send_site_created_email();
    }
/**
 * Checks the wdn registry for any sites that need to be imported and does so.
 */
function _unl_cron_import_wdn_registry_sites() {
  // We don't want this running as system user, only the web user.
  if (PHP_SAPI == 'cli') {
    return;
  }
  // We don't want this running on sub-sites.
  if (conf_path() != 'sites/default') {
    return;
  }
  $wdn_registry_info = array(
    'database' => variable_get('unl_wdn_registry_database'),
    'username' => variable_get('unl_wdn_registry_username'),
    'password' => variable_get('unl_wdn_registry_password'),
    'host'     => variable_get('unl_wdn_registry_host'),
    'driver'   => 'mysql',
  );
  if (!$wdn_registry_info['database']) {
    return;
  }
  Database::addConnectionInfo('wdn_registry', 'default', $wdn_registry_info);
  try {
    db_set_active('wdn_registry');
    $data = db_select('site_request', 'r')
      ->fields('r')
      ->where('`url` IS NULL')
      ->execute()
      ->fetchAll();
    db_set_active();
  }
  catch (Exception $e) {
    db_set_active();
    return;
  }
  $sites_to_create = array();
  foreach ($data as $site) {
    $path = unl_sanitize_url_part($site->department) . '/' . unl_sanitize_url_part($site->site_name);
    $db_prefix = unl_create_db_prefix($site->department . '/' . $site->site_name);

    $sites_to_create[$site->id] = array(
      'site_path'      => $path,
      'uri'            => url($path),
      'clean_url'      => TRUE,
      'db_prefix'      => $db_prefix,
      'site_admin'     => $site->site_admin ? $site->site_admin : '',
      'migration_url'  => $site->migration_url ? $site->migration_url : '',
      'migration_path' => $site->migration_path ? $site->migration_path : '',
      'department'     => $site->department,
    );
  }
  foreach ($sites_to_create as $wdn_site_id => $site_to_create) {
    try {
      db_insert('unl_sites')->fields($site_to_create)->execute();
    }
    catch (PDOException $e) {
      // Ignore duplicate records.
      if ($e->getCode() != 23000) {
        throw $e;

    db_set_active('wdn_registry');
    if (variable_get('unl_wdn_registry_production')) {
      db_update('site_request')
        ->fields(array('url' => $site_to_create['uri']))
        ->condition('id', $wdn_site_id)
        ->execute();
    }
    db_set_active();
/**
 * Custom function that creates a db_prefix short enough to not go over MySQL's max table name length.
 */
function unl_create_db_prefix($site_name) {
  $parent_prefix = '_' . $GLOBALS['databases']['default']['default']['prefix'];
  $site_name = strtolower($site_name);
  $site_name = preg_replace('/[^[a-z0-9]/', '_', $site_name);
  $site_name = explode('_', $site_name);
  foreach ($site_name as $site_word) {
    $site_words[$site_word] = strlen($site_word);
  }
  do {
    $db_prefix = array();
    $found = FALSE;
    foreach ($site_words as $site_word => $length) {
      $db_prefix[] = substr($site_word, 0, $length);
      if (max($site_words) == $length && !$found) {
        $found = TRUE;
        $site_words[$site_word] = $length-1;
      }
    }
    $db_prefix = implode('_', $db_prefix);
    $db_prefix = preg_replace('/_+/', '_', $db_prefix);
    $db_prefix = preg_replace('/(^_)|(_$)/', '', $db_prefix);
  } while (strlen($db_prefix . '_' . $parent_prefix) > 32);
  return $db_prefix;
}
/**
 * Custom function to sanitize user created URLs
 */
function unl_sanitize_url_part($url_part) {
  $url_part = strtolower($url_part);
  $url_part = preg_replace('/[^a-z0-9]/', '-', $url_part);
  $url_part = preg_replace('/-+/', '-', $url_part);
  $url_part = preg_replace('/(^-)|(-$)/', '', $url_part);
/**
 * Custom function.
 */
function unl_get_alternate_base_uris() {
  $shared_prefix = unl_get_shared_db_prefix();
  if (is_array($GLOBALS['databases']['default']['default']['prefix'])) {
    $db_prefix = $GLOBALS['databases']['default']['default']['prefix']['default'];
    $db_prefix = substr($db_prefix, 0, 0 - strlen($shared_prefix) - 1);
  }
  else {
    return array();
  }
  $rows = db_query(
    "SELECT s.uri, a.base_uri, a.path "
    . "FROM {$shared_prefix}unl_sites AS s "
    . "LEFT JOIN {$shared_prefix}unl_sites_aliases AS a "
    . "  ON s.site_id = a.site_id "
    . "WHERE db_prefix=:db_prefix",
    array(':db_prefix' => $db_prefix)
  )->fetchAll();
  if (count($rows) < 1) {
    return array();
  }
  $uris = array($rows[0]->uri);
  foreach ($rows as $row) {
    if ($row->base_uri . $row->path) {
      $uris[] = $row->base_uri . $row->path;
/**
 * Implementation of hook_init().
 */
function unl_init() {
  $primary_base_url = variable_get('unl_primary_base_url');
  if ($primary_base_url) {
    if (substr($primary_base_url, -1) != '/') {
      $primary_base_url .= '/';
    }

    $current_url_schema = parse_url(url(), PHP_URL_SCHEME);
    $primary_base_url_schema = parse_url($primary_base_url, PHP_URL_SCHEME);
    $primary_base_url = $current_url_schema . substr($primary_base_url, strlen($primary_base_url_schema));

    if (conf_path() != 'sites/default' && $primary_base_url != url() && PHP_SAPI != 'cli') {
      drupal_goto($primary_base_url . current_path());
    }
  if (variable_get('unl_use_base_tag', TRUE)) {
    $base_tag = array(
      '#type' => 'html_tag',
      '#tag' => 'base',
      '#attributes' => array(
        'href' => url('<front>', array('absoule' => TRUE)),
      ),
    );
    drupal_add_html_head($base_tag, 'base');
  }
  drupal_add_js(array('unl' => array('use_base_tag' => variable_get('unl_use_base_tag', TRUE))), 'setting');
  _unl_handle_directory_index();
}

/**
 * Custom function called by unl_init() to redirect users from
 * a non-existant some/path/index.html to an existing some/path.
 */
function _unl_handle_directory_index() {
  $path = current_path();
  if (!in_array(basename($path), array('index.html', 'index.htm', 'index.shtml'))) {
    return;
  }
  if (drupal_lookup_path('source', $path)) {
    return;
  }
  if (drupal_lookup_path('source', dirname($path))) {
    drupal_goto(dirname($path));
    return;
  }
  if (dirname($path) == '.') {
    drupal_goto('<front>');
    return;
  }
/**
 * Implementation of hook_mail().
 */
function unl_mail($key, &$message, $params) {
  if ($key == 'site_created') {
    $site = $params['site'];
    $uri = $site->uri;
    $site_admin = $site->site_admin;
    $department = $site->department;
    $message['subject'] = 'New UNLcms site for ' . $department;
    $message['body'][] = <<<EOF
To $site_admin,

Thank you for registering your site at UNLcms. You may now log in using your myUNL information by clicking the link below or copying and pasting it to your browser:
$uri
You must log in in order manage your web site and edit the content. The "Login" link is at the top of the page and you log in using your myUNL information.
For information on how to manage your site & content, please view the online how-to videos found in the menu at the top of the following page, within the category of "Get Help":
http://unlcms.unl.edu

When this new site was created, an attempt was made to copy the content from your current site to this new site. You will want to review all of the content to verify that it is complete and that it is presented correctly.  This import process is dependent on the current's site using and adherence to UNL Templates.

Once your content has been finalized and your are ready to go public with your new site, please contact us to activate the proper public URL (cleaner and shorter). This current URL you've been given will not be indexed or found in search engines until the proper public URL has been established.

Please let us know if you have suggestions or questions.

Thank you,
EOF;

function unl_send_site_created_email($site = NULL) {
  $shared_prefix = unl_get_shared_db_prefix();

  // If no site was specified, get the current site.
  if (!$site) {
    if (!is_array($GLOBALS['databases']['default']['default']['prefix'])) {
      return;
    }
    $db_prefix = $GLOBALS['databases']['default']['default']['prefix']['default'];
    $db_prefix = substr($db_prefix, 0, 0 - strlen($shared_prefix) - 1);
    $data = db_query(
      "SELECT * "
      . "FROM {$shared_prefix}unl_sites "
      . "WHERE db_prefix = :prefix ",
      array(':prefix' => $db_prefix)
    )->fetchAll();
    if (count($data) == 0) {
      return;
    }
    $site = $data[0];
  }
  $unl_site_created_email_address = unl_shared_variable_get('unl_site_created_email_address');
  $unl_site_created_alert_admins = unl_shared_variable_get('unl_site_created_alert_admins');
  $recipients = array();
  if ($unl_site_created_email_address) {
    $recipients[] = $unl_site_created_email_address;
  }
  if ($unl_site_created_alert_admins) {
    $role = user_role_load_by_name('Site Admin');
    $select = db_select('users_roles', 'r');
    $select->fields('r', array('uid'));
    $select->condition('r.rid', $role->rid);
    $uids = $select->execute()->fetchCol();
    $users = user_load_multiple($uids);
    foreach ($users as $user) {
      if (!$user->mail) {
        continue;
      }
      $recipients[] = $user->mail;
    }
  }

  foreach ($recipients as $recipient) {
    drupal_mail('unl', 'site_created', $recipient, language_default(), array('site' => $site), unl_shared_variable_get('site_mail'));
  }
}

/**
 * Custom function that outputs a simple "I'm still alive" page to check to see that drupal is working.
 */
function unl_still_alive() {
  header('Content-type: text/plain');
  echo '200 Still Alive';
}

/**
 * Custom function to return the current admin theme for use with hook_menu_alter().
 */
function _unl_get_admin_theme(){
  return variable_get('admin_theme', '0');
}

/**
 * Custom function for imce access on content administration pages since imce_user_page_access()
 * can't be used because only one file can be included in a hook_menu item ($items['admin/content/filebrowser'])
 */
function _unl_imce_file_browser_access() {
  global $user;
  $profile = imce_user_profile($user);
  return $profile['usertab'];
}

/**
 * Implements hook_block_view_alter()
 * @param array $data
 * @param stdClass $block
 */
function unl_block_view_alter(&$data, $block) {
  if ($block->module == 'system' && $block->delta == 'main-menu') {
    return unl_block_view_system_main_menu_alter($data, $block);
  }
}

/**
 * Tries to implement hook_block_view_MODULE_DELTA_alter, but since the delta contains a -,
 * this is actually called from unl_block_view_alter() for now.
 * Used to determine if a "sub-menu" should be used instead of the normal menu.
 * @param array $data
 * @param stdClass $block
 */
function unl_block_view_system_main_menu_alter(&$data, $block) {
  $current_menu_link = _unl_get_current_menu_link();
  if (!$current_menu_link) {
    return;
  }
  $submenu = _unl_get_current_submenu($data['content'], $current_menu_link->mlid);
  if ($submenu && $submenu['#original_link']['depth'] > 1) {
    $data['content'] = $submenu['#below'];
  }
  $data['content'] = _unl_limit_menu_depth($data['content'], 2);
}

/**
 * Return the mlid of the currently selected menu item.
 * If the current page has no menu item, use return the mlid of its parent instead.
 */
function _unl_get_current_menu_link() {
  $result = db_select('menu_links')
    ->fields('menu_links')
    ->condition('menu_name', 'main-menu')
    ->condition('link_path', current_path())
    ->execute()
    ->fetch();
  if (!$result) {
    return FALSE;
  }
  while (($result->hidden || $result->depth % 2 !== 0 || !$result->has_children) && $result->depth > 1) {
    $result = db_select('menu_links')
      ->fields('menu_links')
      ->condition('menu_name', 'main-menu')
      ->condition('mlid', $result->plid)
      ->execute()
      ->fetch();
  }
  return $result;
}

/**
 * Find the the submenu we are currently "drilled-down" to.
 * @param array $menu_links
 * @param int $current_mlid
 */
function _unl_get_current_submenu($menu_links, $current_mlid) {
  foreach (element_children($menu_links) as $index) {
    $menu_item = $menu_links[$index];
    if ($menu_item['#original_link']['mlid'] == $current_mlid) {
      return $menu_item;
    }
    $sub_menu = _unl_get_current_submenu($menu_item['#below'], $current_mlid);
    if ($sub_menu) {
      return $sub_menu;
    }
  }
  return FALSE;
}

/**
 * Remove any menu items that are more than $depth levels below the current root.
 * @param array $menu_links
 * @param int $depth
 */
function _unl_limit_menu_depth($menu_links, $depth) {
  if ($depth == 0) {
    return array();
  }
  foreach (element_children($menu_links) as $index) {
    $menu_links[$index]['#below'] = _unl_limit_menu_depth($menu_links[$index]['#below'], $depth - 1);
  }
/**
 * Implements hook_block_info()
 */
function unl_block_info() {
  $blocks = array();
  $blocks['my_sites'] = array(
    'info' => 'My Sites',
    'cache' => DRUPAL_CACHE_PER_USER,
  return $blocks;
}

/**
 * Implements hook_block_view()
 */
function unl_block_view($delta = '') {
  switch ($delta) {
    case 'my_sites':
      return unl_block_view_my_sites();
      break;
    default:
      return array();
  }
}

/**
 * Implements hook_block_view('my_sites').
 * Displays the list of sites/roles for the current user.
 */
function unl_block_view_my_sites()
{
  if (user_is_anonymous()) {
    return array();
  }
  require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'unl_site_creation.php';

  $block = array();
  $block['content'] = _unl_get_user_audit_content($GLOBALS['user']->name);
/**
 * Implements hook_stream_wrappers_alter().
 */
function unl_stream_wrappers_alter(&$wrappers) {
  if (variable_get('unl_clean_file_url')) {
    $wrappers['public']['class'] = 'UnlPublicStreamWrapper';
  }
}
class UnlPublicStreamWrapper extends DrupalPublicStreamWrapper {
  function getExternalUrl() {
    $url = $GLOBALS['base_url'];
    if (!variable_get('unl_clean_file_url')) {
      $url .= '/' . self::getDirectoryPath();
    }
    $path = str_replace('\\', '/', $this->getTarget());
    $url .= '/' . drupal_encode_path($path);
    return $url;
  }
}
/**
 * Implements hook_query_alter()
 * Currently used to filter out users with no roles at "admin/people".
 */
function unl_query_alter(QueryAlterableInterface $query)
{
  // If this query is coming from the "People" admin page
  if (current_path() == 'admin/people') {
    // Find the prefix for the "users" table
    $usersTableAlias = NULL;
    foreach ($query->getTables() as $alias => $table) {
      if ($table['table'] == 'users') {
        $usersTableAlias = $alias; 
      }
    }
    // If we actually find a users table
    if ($usersTableAlias) {
      // Join it with the users_roles tables so that only users with roles are seleceted.
      $query->join('users_roles', 'unl_distinct_prefix_r', $usersTableAlias . '.uid = unl_distinct_prefix_r.uid');
    }
  }
}