Skip to content

Plugin Drupal7

BlacklistPermissions

BlackList Permissions

Class: Drutiny\Plugin\Drupal7\Audit\BlacklistPermissions
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:BlackListPermissions BlackList Permissions

Parameters

Name Type Description Default
permissions array An array of permissions to ensure are not available to non-administrator roles null

Tokens

Name Type Description Default
permissions array An array of permissions to ensure are not available to non-administrator roles null
Source
  public function audit(Sandbox $sandbox) {
    $perms = $sandbox->getParameter('permissions');

    if (empty($perms)) {
      return TRUE;
    }

    $where = [];
    foreach ($perms as $perm) {
      $where[] = 'rp.permission = \'' . $perm . '\'';
    }

    // We don't care about the 'administrator' role having access.
    $variable = $sandbox->drush(['format' => 'json'])->variableGet('user_admin_role');
    $user_admin_role = $variable['user_admin_role'];

    try {
      $output = $sandbox->drush()->sqlQuery('SELECT r.rid, r.name, rp.permission FROM role r INNER JOIN role_permission rp ON rp.rid = r.rid WHERE r.rid != ' . $user_admin_role . ' AND (' . implode(' OR ', $where) . ');');
      $output = array_filter($output);
    }
    catch (\Exception $e) {
      $sandbox->logger()->info(get_class($e) . ': ' . $e->getMessage());
      return FALSE;
    }

    if (empty($output)) {
      return TRUE;
    }

    $black_roles = [];
    foreach ($output as $line) {
      list($rid, $role, $permission) = explode("\t", $line);
      $black_roles[$role][] = $permission;
    }

    $roles = [];

    foreach ($black_roles as $role => $perms) {
      $roles[] = [
        'role' => $role,
        'perms' => $perms,
      ];
    }

    $sandbox->setParameter('roles', $roles);

    return FALSE;
  }

CronLast

Check a configuration is set correctly.

Class: Drutiny\Plugin\Drupal7\Audit\CronLast
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:CronLast Cron running regularly
Source
  public function audit(Sandbox $sandbox) {

    try {
      $vars = $sandbox->drush([
        'format' => 'json'
        ])->variableGet();

      if (!isset($vars['cron_last'])) {
        return FALSE;
      }

      $sandbox->setParameter('cron_last', date('l jS \of F Y h:i:s A', $vars['cron_last']));

      $time_diff = time() - $vars['cron_last'];
      // Fail if cron hasn't run in the last 24 hours.
      if ($time_diff > 86400) {
        return FALSE;
      }
      return TRUE;
    }
    catch (DrushFormatException $e) {
      return Audit::ERROR;
    }
  }

DuplicateModules

Duplicate modules.

Class: Drutiny\Plugin\Drupal7\Audit\DuplicateModules
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:NoDuplicateModules Duplicate modules
Source
  public function audit(Sandbox $sandbox) {
    $config = $sandbox->drush(['format' => 'json'])->status();
    $docroot = $config['root'];

    $command = <<<CMD
find $docroot -name '*.module' -type f |\
grep -Ev 'drupal_system_listing_(in)?compatible_test' |\
grep -oe '[^/]*\.module' | grep -Ev '^\.module' | cut -d'.' -f1 | sort |\
uniq -c | sort -nr | awk '{print $2": "$1}'
CMD;

    $output = $sandbox->exec($command);
    $duplicateModules = array_filter(Yaml::parse($output), function ($count) {
      return $count > 1;
    });

    $modules = [];
    foreach ($duplicateModules as $module => $count) {
      $modules[] = [
        'module' => $module,
        'count' => $count,
      ];
    }

    $sandbox->setParameter('modules', $modules);
    return count($modules) === 0;
  }

EntityReferenceAutocomplete

Entity reference autocomplete

Class: Drutiny\Plugin\Drupal7\Audit\EntityReferenceAutocomplete
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:entityreference EntityReference Autocomplete Performance

Parameters

Name Type Description Default
threshold integer The limit of references allowed 100
errors_count integer The number of errors found 0

Tokens

Name Type Description Default
threshold integer The limit of references allowed 100
errors array An array of errors if any { }
errors_count integer The number of errors found 0
Source
  public function audit(Sandbox $sandbox)
  {

    $errors = $sandbox->drush()->evaluate(function () {
      $results = db_query("SELECT fc.field_name, fc.data as field_info, fci.data as field_instance_info
        FROM {field_config} fc
        JOIN {field_config_instance} fci ON fc.id = fci.field_id
        WHERE fc.type = 'entityreference'");

      $errors = [];
      foreach ($results as $record) {
        if (!$record->field_info = unserialize($record->field_info)) {
          continue;
        }

        // Correct configuration is to use an autocomplete as this will limit
        // the number of referenced entities from being rendered.
        if (strpos($record->field_instance_info['widget']['type'], 'autocomplete') > -1) {
          continue;
        }

        $record->field_instance_info = unserialize($record->field_instance_info);
        if (!$record->field_instance_info = unserialize($record->field_instance_info)) {
          continue;
        }

        $args = [];

        $handler_settings = isset($record->field_info['settings']['handler_settings']) ? $record->field_info['settings']['handler_settings'] : NULL;

        // Attempt to find the node types in the $field_info.
        if (isset($handler_settings['target_bundles'])) {
          $args = array_keys($handler_settings['target_bundles']);
        }
        elseif (isset($handler_settings['view']['args'])) {
          $args = [];
          foreach ($handler_settings['view']['args'] as $arg) {
            // If we're using views we can pass multiple entity types in
            // contextually separated by a +.
            $args = array_merge($args, explode('+', $arg));
          }
        }

        switch ($record->field_info['settings']['target_type']) {
          case 'node':
            $count = db_query("SELECT count(*) as count FROM {node} node WHERE node.type in (" . $args . ")");
            break;

          case 'taxonomy_term':
            $count = db_query("SELECT count(*) as count FROM {taxonomy_term_data}")->fetchField();
            break;
        }

        if ($count > $sandbox->getParameter('threshold', 100)) {
          $errors[] = "{$record->field_instance_info['label']} `{$record->field_instance['label']}`, found *{$count}* referenced entities.";
        }
      }
      return $errors;
    });

    $sandbox->setParameter('errors', $errors);
    $sandbox->setParameter('errors_count', count($errors));

    return count($errors) == 0;
  }

MissingModules

Missing modules.

Class: Drutiny\Plugin\Drupal7\Audit\MissingModules
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:MissingModules Missing modules

Parameters

Name Type Description Default
key string The name of the variable to compare. null

Tokens

Name Type Description Default
key string The name of the variable to compare. null
Source
  public function audit(Sandbox $sandbox) {
    $rows = $sandbox->drush()->evaluate(function () {
      $rows = [];

      // Grab all the modules in the system table.
      $query = db_query("SELECT filename, type, name FROM {system}");
      // Go through the query and check to see if the module exists in the directory.
      foreach ($query->fetchAll() as $record) {
        if ($record->name == 'default') {
          continue;
        }

        // Grab the checker.
        $check = drupal_get_filename($record->type, $record->name, $record->filename, FALSE);
        // If drupal_get_filename returns null = we got problems.
        if (!is_null($check)) {
          continue;
        }

        // Go ahead and set the row if all is well.
        $rows[$record->name] = array(
          'name' => $record->name,
          'type' => $record->type,
          'filename' => $record->filename,
        );
      }
      return $rows;
    });

    $sandbox->setParameter('messages', array_values(array_map(function ($row) {
      return "Cannot file {$row['type']} `{$row['name']}`. Expected to be in {$row['filename']}.";
    }, $rows)));

    print_r($sandbox->getParameter('messages'));

    return empty($rows);
  }

ModuleDisabled

Generic module is disabled check.

Class: Drutiny\Plugin\Drupal7\Audit\ModuleDisabled
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

This class can remediate failed audits.

Policies

These are the policies that use this class:

Name Title
Drupal-7:acquiaCASDisabled CAS is not installed
Drupal-7:acquiaDevinciDisabled Devinci is not installed
Drupal-7:acquiaR4032LoginDisabled Redirect 403 to User Login is not installed
Drupal-7:acquiaHTMLPurifierDisabled HTML Purifier is not installed
Drupal-7:acquiaBeanDisabled Bean is not installed
Drupal-7:acquiaAdaptiveImageDisabled Adaptive Image is not installed
Drupal-7:acquiaElysiaCronDisabled Elysia Cron is not installed
Drupal-7:acquiaContactImporterDisabled Contact Importer is not installed
Drupal-7:acquiaTCPDFDisabled TCPDF is not installed
Drupal-7:acquiaConfigMgmtDisabled Configuration Management is not installed
Drupal-7:acquiaCFPurgeDisabled CloudFlare Purge is not installed
Drupal-7:acquiaRadioactivityDisabled Radioactivity is not installed
Drupal-7:acquiaOptimizeDBDisabled Optimize DB is not installed
Drupal-7:acquiaShibAuthDisabled Shibboleth Authentication is not installed
Drupal-7:acquiaWURFLDisabled WURFL is not installed
Drupal-7:acquiaHTTPRLDisabled HTTPRL is not installed
Drupal-7:acquiaSerialDisabled Serial is not installed
Drupal-7:acquiaPrintDisabled Print is not installed
Drupal-7:acquiaVarnishModuleDisabled Varnish Module is not installed
Drupal-7:acquiaBoostDisabled Boost is not installed
Drupal-7:acquiaSearch404Disabled Search 404 is not installed
Drupal-7:acquiaAuthcacheDisabled Authcache is not installed
Drupal-7:acquiaApacheSolrFileDisabled Apache Solr File is not installed
Drupal-7:acquiaCiviCRMDisabled CiviCRM is not installed
Drupal-7:acquiaAPCDisabled APC is not installed
Drupal-7:acquiaLinkCheckerDisabled Link Checker is not installed
Drupal-7:acquiaFilefieldSourcesDisabled Filefield Sources is not installed
Drupal-7:acquiaWYSIWYGCKFinderDisabled WYSIWYG CKFinder is not installed
Drupal-7:acquiaWorkbenchModerationDisabled Workbench Moderation is not installed
Drupal-7:acquiaNodeViewCountDisabled Node view count is not installed
Drupal-7:acquiaAutoSlaveDisabled AutoSlave is not installed
Drupal-7:acquiaDBMaintenanceDisabled DB Maintenance is not installed
Drupal-7:acquiaLDAPDisabled Lightweight Directory Access Protocol (LDAP) is not installed
Drupal-7:StatisticsModuleDisabled Statistics
Drupal-7:NoBackupAndMigrate Backup and Migrate is not installed
Drupal-7:roleMemoryLimitDisabled Role Memory Limit is not installed
Drupal-7:memcacheStorageDisabled Memcache Storage is not installed
Drupal-7:DevelDisabled Devel module is not installed
Drupal-7:tbMegaMenuDisabled TB Mega Menu is not installed
Drupal-7:ipGeolocDisabled IP Geolocation is not installed
Drupal-7:h5pDisabled H5P is not installed
Drupal-7:globalFilterDisabled Views Global Filter is not installed
Drupal-7:ViewsUIDisabled Views UI module is not installed
Drupal-7:recaptchaDisabled reCAPTCHA is not installed
Drupal-7:SimpletestModuleDisabled Simpletest
Drupal-7:sessionAPIDisabled Session API is not installed
Drupal-7:PhpModuleDisabled PHP
Drupal-7:smartIPDisabled Smart IP is not installed
Drupal-7:DblogModuleDisabled Database logging disabled
Drupal-7:fbconnectDisabled Facebook Connect is not installed
Drupal-7:textSizeDisabled Text Size is not installed
Drupal-7:OverlayModuleDisabled Overlay module disabled
Drupal-7:fileCacheGlusterDisabled File Cache with Gluster is not installed
Drupal-7:supercookieDisabled Super Cookie is not installed
Drupal-7:ShieldModuleDisabled Shield Disabled
Drupal-7:viewsFilterHarmonizerDisabled Views Filter Harmonizer is not installed
Drupal-7:blockcacheAlterDisabled Block Cache Alter is not installed
Drupal-7:UpdateModuleDisabled Update
Drupal-7:purgeDisabled Purge Module is not installed
Drupal-7:Search404ModuleDisabled Search404 module disabled
Drupal-7:sessionCacheDisabled Session Cache API is not installed

Parameters

Name Type Description Default
module string The module to check is enabled. null

Tokens

Name Type Description Default
module string The module to check is enabled. null
Source
  public function audit(Sandbox $sandbox) {

    $module = $sandbox->getParameter('module');

    try {
      $info = $sandbox->drush(['format' => 'json'])->pmList();
    }
    catch (DrushFormatException $e) {
      return strpos($e->getOutput(), $module . ' was not found.') !== FALSE;
    }

    if (!isset($info[$module])) {
      return TRUE;
    }

    $status = strtolower($info[$module]['status']);

    return ($status != 'enabled');
  }

ModulesEnabled

Generic modules are enabled check.

Class: Drutiny\Plugin\Drupal7\Audit\ModulesEnabled
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

This class can remediate failed audits.

Policies

These are the policies that use this class:

Name Title
Drupal-7:ModulesEnabled Modules enabled

Parameters

Name Type Description Default
modules array List of modules to check that are enabled. null

Tokens

Name Type Description Default
modules array List of modules to check that are enabled. null
Source
  public function audit(Sandbox $sandbox) {
    $modules = $sandbox->getParameter('modules');
    if (empty($modules)) {
      return TRUE;
    }

    $notEnabled = [];
    foreach ($modules as $moduleName) {
      try {
        if (!$sandbox->drush()->moduleEnabled($moduleName)) {
          throw new \Exception($moduleName);
        }
      }
      catch (\Exception $e) {
        $notEnabled[] = $moduleName;
      }
    }
    if (!empty($notEnabled)) {
      $sandbox->setParameter('notEnabled', $notEnabled);
      return FALSE;
    }
    // Seems like the best way to comma separate things.
    else {
      $sandbox->setParameter('enabled', '`' . implode('`, `', $modules) . '`');
    }

    return TRUE;
  }

NoAdministrators

Class: Drutiny\Plugin\Drupal7\Audit\NoAdministrators
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:NoAdmins No Administrators
Source
  public function audit(Sandbox $sandbox) {
    $variable = $sandbox->drush(['format' => 'json'])->vget('user_admin_role');
    $admin_rid = (int) $variable['user_admin_role'];
    $role_list = $sandbox->drush(['format' => 'json'])->roleList();

    $roles = [];
    foreach ($role_list as $role) {
      // Find out the role name of the role ID defined in 'user_admin_role'.
      if ($role['rid'] === $admin_rid) {
        $roles[$admin_rid] = $role['label'];
      }
      elseif ($role['label'] === 'administrator') {
        $roles[$role['rid']] = $role['label'];
      }
    }

    // No administrator roles defined, and no roles called 'administrator' in
    // Drupal.
    if (empty($roles)) {
      return;
    }

    // '0' is disabled.
    // @see https://github.com/drupal/drupal/blob/7.x/modules/user/user.admin.inc#L305
    if (count($roles) === 1 && $admin_rid === 0) {
      return;
    }

    $rows = $sandbox->drush()
    ->sqlQuery("SELECT CONCAT(ur.uid, ',', u.name)
      FROM {users_roles} ur
      LEFT JOIN {users} u ON ur.uid = u.uid
      WHERE ur.uid > 1 AND ur.rid IN (" . implode(',', array_keys($roles)) . ");"
    );

    // Remove blank rows.
    $rows = array_filter($rows);

    // Format rows into token data.
    $rows = array_map(function ($row) {
      $row = trim($row);
      list($uid, $name) = explode(',', $row, 2);
      return "{$name} - [UID {$uid}]";
    }, $rows);

    $sandbox->setParameter('count', count($rows));
    $sandbox->setParameter('issues', $rows);
    $sandbox->setParameter('plural', count($rows) > 1 ? 's' : '');

    return empty($rows);
  }

SearchApiDb

Search API Database.

Class: Drutiny\Plugin\Drupal7\Audit\SearchApiDb
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:SearchApiDb Search API Database
Source
  public function audit(Sandbox $sandbox) {
    if (!$sandbox->drush()->moduleEnabled('search_api_db')) {
      return Audit::NOT_APPLICABLE;
    }

    // Find out if there are active indexes using the db service class.
    $output = $sandbox->drush()->sqlQuery("SELECT COUNT(i.machine_name) as count FROM {search_api_index} i LEFT JOIN {search_api_server} s ON i.server = s.machine_name WHERE i.status > 0 AND s.class = 'search_api_db_service';");
    if (empty($output)) {
      $number_of_db_indexes = 0;
    }
    elseif (count($output) === 1) {
      $number_of_db_indexes = (int) $output[0];
    }
    else {
      $number_of_db_indexes = (int) $output[1];
    }
    $sandbox->setParameter('number_of_db_indexes', $number_of_db_indexes);
    $number_of_db_indexes > 1 ? $sandbox->setParameter('plural_index', 'es') : $sandbox->setParameter('plural_index', '');
    // No database indexes.
    if ($number_of_db_indexes === 0) {
      return Audit::SUCCESS;
    }
    // If the database is in use, find out how many nodes are in it.
    $output = $sandbox->drush()->sqlQuery('SELECT COUNT(item_id) FROM {search_api_db_default_node_index};');
    // There are some differences in running the command on site factory then
    // locally.
    if (count($output) == 1) {
      $nodes_in_search = (int) $output[0];
    }
    else {
      $nodes_in_search = (int) $output[1];
    }
    $sandbox->setParameter('nodes_in_search', $nodes_in_search);
    $max_size = (int) $sandbox->getParameter('max_size');
    if ($nodes_in_search < $max_size) {
      return Audit::WARNING;
    }
    return Audit::FAILURE;
  }

UntrustedRoles

Check untrusted roles for administrative permissions.

Class: Drutiny\Plugin\Drupal7\Audit\UntrustedRoles
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:UntrustedRoles Untrusted Roles with administrative permissions

Parameters

Name Type Description Default
untrusted_roles array The names of untrusted Roles. '[''anonymous user'',''authenticated user'']'

Tokens

Name Type Description Default
untrusted_roles array The names of untrusted Roles. '[''anonymous user'',''authenticated user'']'
Source
  public function audit(Sandbox $sandbox) {
    $rows = $sandbox->drush()->evaluate(function ($roles) {
      $rows = [];
      $all_roles = user_roles();
      $untrusted_roles = array_intersect($all_roles, $roles);

      foreach ($untrusted_roles as $rid => $role_name) {
        $untrusted_permissions = [];

        // Grab all permissions associated with the role.
        $permissions = user_role_permissions([$rid => $role_name]);

        // Check each permission assigned to the untrusted role and determine if
        // it is administrative. Administrative permissions contain the string
        // "administer" in the name.
        $output['permissions'][$role_name] = $permissions;
        foreach ($permissions[$rid] as $permission => $foo) {
          if (strstr($permission, 'administer') !== FALSE ) {
            $untrusted_permissions[] = $permission;

          }
        }

        // Add the untrusted role and administrative permission to an output array
        if (!empty($untrusted_permissions)) {
          $rows[] = [
            'role' => $role_name,
            'permissions' => implode(', ', $untrusted_permissions),
          ];
        }
      }
      return $rows;
    }, [
      'roles' => $sandbox->getParameter('untrusted_roles')
    ]);

    $sandbox->setParameter('rows', $rows);

    return empty($rows) ? AUDIT::SUCCESS : AUDIT::FAIL;
  }

User1

User #1 Locked Down

Class: Drutiny\Plugin\Drupal7\Audit\User1
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

This class can remediate failed audits.

Policies

These are the policies that use this class:

Name Title
Drupal-7:User1LockDown User #1 Locked Down

Parameters

Name Type Description Default
blacklist string The usernames of the the uid:1 user that are considered forbidden. Expression maybe a regular expression to match patterns. null
email string The email that the uid:1 user should have. If an empty string is provided then this check is omitted. null
status integer Ensures the uid:1 user status reflects the same as this argument. Defaults to active (1). 1

Tokens

Name Type Description Default
blacklist string The usernames of the the uid:1 user that are considered forbidden. Expression maybe a regular expression to match patterns. null
email string The email that the uid:1 user should have. If an empty string is provided then this check is omitted. null
status integer Ensures the uid:1 user status reflects the same as this argument. Defaults to active (1). 1
Source
  public function audit(Sandbox $sandbox) {
    // Get the details for user #1.
    $user = $sandbox->drush(['format' => 'json'])->userInformation(1);
    $user = (object) array_pop($user);

    $errors = [];

    // Username.
    $pattern = $sandbox->getParameter('blacklist');
    if (preg_match("#${pattern}#i", $user->name)) {
      $errors[] = "Username '$user->name' is too easy to guess.";
    }
    $sandbox->setParameter('username', $user->name);

    // Email address.
    $email = $sandbox->getParameter('email');
    if (!empty($email) && ($email !== $user->mail)) {
      $errors[] = "Email address '$user->mail' is not set correctly.";
    }

    // Status.
    $status = (bool) $sandbox->getParameter('status');
    if ($status !== (bool) $user->status) {
      $errors[] = 'Status is not set correctly. Should be ' . ($user->status ? 'active' : 'inactive') . '.';
    }

    $sandbox->setParameter('errors', $errors);
    return empty($errors);
  }

VariableCompare

Check a configuration is set correctly.

Class: Drutiny\Plugin\Drupal7\Audit\VariableCompare
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:NoPageCompression No Page Compression
Acquia:SiteFactory:SearchAutoSwitch Acquia Search Auto Switch (D7)
Drupal-7:InstallTaskCompleted Installation Complete
Drupal-7:ErrorLevel Error Level
Drupal-7:SecureHTTPRedirect Secure Pages: HTTP Redirect
Drupal-7:SecurePagesListed Secure Pages Listed
Drupal-7:ViewsSqlSignature Views SQL Signature
Drupal-7:JsAggregation Js Aggregation
Drupal-7:UserRegistrationDisabled User Registration Disabled
Drupal-7:PageCacheMaximumAge Page Cache Control Max Age
Drupal-7:CSSAggregation CSS Aggregation
Drupal-7:CacheLifetime Application Page Cache
Drupal-7:XMLSitemapBaseURL XML sitemap base URL
Drupal-7:SecurePagesConfig:Enabled Secure Pages Config: Enabled
Drupal-7:PoorMansCronDisabled Poor Mans Cron Disabled
Drupal-7:SecurePagesConfig:NoDowngrade Secure Pages Config: No Downgrade
Drupal-7:ImageDerivatives Image Derivatives

Parameters

Name Type Description Default
key string The name of the variable to compare. null
value mixed The value to compare against null
comp_type string The comparison operator to use '=='
required_modules array An optional array of modules required in order to check variables { }
default mixed An optional default value if a value is not found no-value-provided

Tokens

Name Type Description Default
key string The name of the variable to compare. null
value mixed The value to compare against null
comp_type string The comparison operator to use '=='
required_modules array An optional array of modules required in order to check variables { }
default mixed An optional default value if a value is not found no-value-provided
reading mixed The value read from the Drupal variables system null
Source
  public function audit(Sandbox $sandbox) {
    $key = $sandbox->getParameter('key');
    $value = $sandbox->getParameter('value');

    if ($required_modules = $sandbox->getParameter('required_modules')) {
      $required_modules = is_array($required_modules) ? $required_modules : [$required_modules];
      $info = $sandbox->drush(['format' => 'json'])->pmList();
      $missing_modules = array_diff($required_modules, array_keys($info));

      if (!empty($missing_modules)) {
        return Audit::NOT_APPLICABLE;
      }
    }

    try {
      $vars = $sandbox->drush([
        'format' => 'json'
        ])->variableGet();

      if (!isset($vars[$key])) {
        throw new DrushFormatException(__CLASS__ . ": $key is not a set variable.", '');
      }
      $reading = $vars[$key];
    }
    catch (DrushFormatException $e) {
      $sandbox->setParameter('exception', $e->getMessage());

      $default_value = $sandbox->getParameter('default', 'no-value-provided');

      // If no default value was provided then we can not provide an accruate
      // outcome based on the absense of a successful drush command.
      if ($default_value === 'no-value-provided') {
        return FALSE;
      }

      $reading = $default_value;
    }

    $sandbox->setParameter('reading', $reading);

    $comp_type = $sandbox->getParameter('comp_type', '==');
    $sandbox->logger()->info('Comparative config values: ' . var_export([
      'reading' => $reading,
      'value' => $value,
      'expression' => 'reading ' . $comp_type . ' value',
    ], TRUE));

    switch ($comp_type) {
      case 'lt':
      case '<':
        return $reading < $value;
      case 'gt':
      case '>':
        return $reading > $value;
      case 'lte':
      case '<=':
        return $reading <= $value;
      case 'gte':
      case '>=':
        return $reading >= $value;
      case 'ne':
      case '!=':
        return $reading != $value;
      case 'nie':
      case '!==':
        return $reading !== $value;
      case 'matches':
      case '~':
        return strpos($reading, $value) !== FALSE;
      case 'identical':
      case '===':
        return $value === $reading;
      case 'in_array':
        return in_array($reading, $value);
      case 'regex':
        return preg_match("#${value}#", $reading);
      case 'equal':
      case '==':
      default:
        return $value == $reading;
    }
  }

ViewsCache

Views Cache

Class: Drutiny\Plugin\Drupal7\Audit\ViewsCache
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:ViewsCache Views Cache
Source
  public function audit(Sandbox $sandbox) {
    $views = $sandbox->drush()->evaluate(function () {
      $bad_views = [];
      foreach (views_get_all_views() as $view_name => $view) {
        foreach ($view->display as $display_name => $display) {
          if (empty($display->display_options['cache'])) {
            $bad_views[] = "$view_name:$display_name";
            continue;
          }
          $cache = $display->display_options['cache'];
          if ($cache['type'] == 'none') {
            $bad_views[] = "$view_name:$display_name";
          }
        }
      }
      return $bad_views;
    });

    if (empty($views)) {
      return TRUE;
    }

    $sandbox->setParameter('views', $views);
    return FALSE;


    // $valid = 0;
    // $errors = [];
    //
    // // View settings are set per display so we need to query the views display table.
    // $views = $this->context->drush->sqlQuery("SELECT vd.vid, vd.display_title, vd.display_options, vv.name, vv.human_name FROM {views_display} vd JOIN {views_view} vv ON vv.vid = vd.vid");
    //
    // foreach ($views as $view) {
    //   list($display_id, $display_name, $display_options, $view_machine_name, $view_name) = explode("\t", $view);
    //   $display_options = Serializer::unserialize($display_options);
    //
    //   if (empty($display_options['pager']['options']['items_per_page'])) {
    //     continue;
    //   }
    //
    //   if ($display_options['pager']['options']['items_per_page'] > $this->getOption('threshold', 30)) {
    //     $errors[] = "<strong>$view_name</strong> <code>[$display_name]</code> is displaying <code>{$display_options['pager']['options']['items_per_page']}</code>";
    //     continue;
    //   }
    //
    //   $valid++;
    // }
    //
    // $this->setToken('total', $valid);
    // $this->setToken('plural', $valid > 1 ? 's' : '');
    // $this->setToken('error', implode('</li><li>', $errors));
    // $this->setToken('threshold', $this->getOption('threshold', 30));
    // $this->setToken('error_count', count($errors));
    //
    // return empty($errors) ? AuditResponse::AUDIT_SUCCESS : AuditResponse::AUDIT_FAILURE;
  }

ViewsPagination

Views Pagination

Class: Drutiny\Plugin\Drupal7\Audit\ViewsPagination
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:ViewsPagination Views Pagination

Parameters

Name Type Description Default
limit integer The maximum number of rows a view can list null

Tokens

Name Type Description Default
limit integer The maximum number of rows a view can list null
Source
  public function audit(Sandbox $sandbox) {
    $views = $sandbox->drush()->evaluate(function ($limit) {
      $bad_views = [];
      foreach (views_get_all_views() as $view_name => $view) {
        foreach ($view->display as $display_name => $display) {
          if ($display->display_options['pager']['options']['items_per_page'] > $limit) {
            $bad_views[] = "$view_name:$display_name contains " .  $display->display_options['pager']['options']['items_per_page'] . " per page.";
          }
        }
      }
      return $bad_views;
    }, ['limit' => $sandbox->getParameter('limit', 60)]);

    if (empty($views)) {
      return TRUE;
    }

    $sandbox->setParameter('views', $views);
    return FALSE;


    // $valid = 0;
    // $errors = [];
    //
    // // View settings are set per display so we need to query the views display table.
    // $views = $this->context->drush->sqlQuery("SELECT vd.vid, vd.display_title, vd.display_options, vv.name, vv.human_name FROM {views_display} vd JOIN {views_view} vv ON vv.vid = vd.vid");
    //
    // foreach ($views as $view) {
    //   list($display_id, $display_name, $display_options, $view_machine_name, $view_name) = explode("\t", $view);
    //   $display_options = Serializer::unserialize($display_options);
    //
    //   if (empty($display_options['pager']['options']['items_per_page'])) {
    //     continue;
    //   }
    //
    //   if ($display_options['pager']['options']['items_per_page'] > $this->getOption('threshold', 30)) {
    //     $errors[] = "<strong>$view_name</strong> <code>[$display_name]</code> is displaying <code>{$display_options['pager']['options']['items_per_page']}</code>";
    //     continue;
    //   }
    //
    //   $valid++;
    // }
    //
    // $this->setToken('total', $valid);
    // $this->setToken('plural', $valid > 1 ? 's' : '');
    // $this->setToken('error', implode('</li><li>', $errors));
    // $this->setToken('threshold', $this->getOption('threshold', 30));
    // $this->setToken('error_count', count($errors));
    //
    // return empty($errors) ? AuditResponse::AUDIT_SUCCESS : AuditResponse::AUDIT_FAILURE;
  }

ZenRebuildRegistry

Class: Drutiny\Plugin\Drupal7\Audit\ZenRebuildRegistry
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-7

Policies

These are the policies that use this class:

Name Title
Drupal-7:ZenRegistryRebuild Zen rebuild registry disabled
Source
  public function audit(Sandbox $sandbox) {

    $output = $sandbox->drush()->sqlQuery("SELECT * FROM {variable} WHERE name LIKE 'theme_%';");
    $themes_with_rebuild_enabled = [];
    foreach ($output as $row) {
      preg_match('/^theme_([a-zA-Z_]+)_settings/', $row, $matches);

      // 'theme_default' is also a variable we want to exclude.
      if (empty($matches)) {
        continue;
      }

      $theme_name = $matches[1];

      if (preg_match('/zen_rebuild_registry.;i:1/', $row)) {
        $themes_with_rebuild_enabled[] = $theme_name;
      }
    }

    if (count($themes_with_rebuild_enabled) > 0) {
      $sandbox->setParameter('number_of_themes', count($themes_with_rebuild_enabled));
      $sandbox->setParameter('themes', '<code>' . implode('</code>, <code>', $themes_with_rebuild_enabled) . '</code>');
      $sandbox->setParameter('plural', count($themes_with_rebuild_enabled) > 1 ? 's' : '');
      $sandbox->setParameter('prefix', count($themes_with_rebuild_enabled) > 1 ? 'are' : 'is');
      return FALSE;
    }

    return TRUE;
  }