From 99b55bfcac0820a8a8d3761b5cd8d23153f7687b Mon Sep 17 00:00:00 2001 From: Eric Rasmussen <ericrasmussen1@gmail.com> Date: Wed, 30 May 2012 10:33:36 -0500 Subject: [PATCH] [gh-390] Fix UNL site list Replace the run-at-request complicated JOIN db query with a cron task that fills in name and access in two new unl_sites db fields. --- sites/all/modules/unl/cron.php | 73 ++++++++++++-- sites/all/modules/unl/unl.install | 41 +++++++- sites/all/modules/unl/unl_site_creation.php | 103 ++++---------------- 3 files changed, 121 insertions(+), 96 deletions(-) diff --git a/sites/all/modules/unl/cron.php b/sites/all/modules/unl/cron.php index 2e8965ec..8670589b 100644 --- a/sites/all/modules/unl/cron.php +++ b/sites/all/modules/unl/cron.php @@ -28,6 +28,7 @@ unl_remove_page_aliases(); unl_add_sites(); unl_add_aliases(); unl_add_page_aliases(); +unl_update_unl_sites(); function unl_add_sites() { $query = db_query('SELECT * FROM {unl_sites} WHERE installed=0'); @@ -215,7 +216,7 @@ function unl_add_site($site_path, $uri, $clean_url, $db_prefix, $site_id) { if ($site_mail) { $command .= " --site-mail=$site_mail"; } - + $result = shell_exec($command); echo $result; if (stripos($result, 'Drush command terminated abnormally due to an unrecoverable error.') !== FALSE) { @@ -275,7 +276,7 @@ function unl_add_alias($site_uri, $base_uri, $path, $alias_id) { $alias_uri = $base_uri . $path; $real_config_dir = unl_get_sites_subdir($site_uri); $alias_config_dir = unl_get_sites_subdir($alias_uri, FALSE); - + unl_add_alias_to_sites_php($alias_config_dir, $real_config_dir, $alias_id); if ($path) { unl_add_site_to_htaccess($alias_id, $path, TRUE); @@ -289,7 +290,7 @@ function unl_remove_alias($base_uri, $path, $alias_id) { * to the new method of creating aliases. */ unlink(DRUPAL_ROOT . '/sites/' . $alias_config_dir); - + unl_remove_alias_from_sites_php($alias_id); unl_remove_site_from_htaccess($alias_id, TRUE); } @@ -318,7 +319,7 @@ function unl_add_site_to_htaccess($site_id, $site_path, $is_alias) { } unl_require_writable(DRUPAL_ROOT . '/.htaccess'); - + $stub_token = ' # %UNL_CREATION_TOOL_STUB%'; $htaccess = file_get_contents(DRUPAL_ROOT . '/.htaccess'); $stub_pos = strpos($htaccess, $stub_token); @@ -346,7 +347,7 @@ function unl_remove_site_from_htaccess($site_id, $is_alias) { } unl_require_writable(DRUPAL_ROOT . '/.htaccess'); - + $htaccess = file_get_contents(DRUPAL_ROOT . '/.htaccess'); $site_start_token = "\n # %UNL_START_{$site_or_alias}_ID_{$site_id}%"; $site_end_token = " # %UNL_END_{$site_or_alias}_ID_{$site_id}%\n"; @@ -366,7 +367,7 @@ function unl_remove_site_from_htaccess($site_id, $is_alias) { function unl_add_page_alias_to_htaccess($site_id, $host, $path, $to_uri) { unl_require_writable(DRUPAL_ROOT . '/.htaccess'); - + $stub_token = ' # %UNL_CREATION_TOOL_STUB%'; $htaccess = file_get_contents(DRUPAL_ROOT . '/.htaccess'); $stub_pos = strpos($htaccess, $stub_token); @@ -387,7 +388,7 @@ function unl_add_page_alias_to_htaccess($site_id, $host, $path, $to_uri) { function unl_remove_page_alias_from_htaccess($site_id) { unl_require_writable(DRUPAL_ROOT . '/.htaccess'); - + $htaccess = file_get_contents(DRUPAL_ROOT . '/.htaccess'); $site_start_token = "\n # %UNL_START_PAGE_ALIAS_ID_{$site_id}%"; $site_end_token = " # %UNL_END_PAGE_ALIAS_ID_{$site_id}%\n"; @@ -407,7 +408,7 @@ function unl_remove_page_alias_from_htaccess($site_id) { function unl_add_alias_to_sites_php($alias_site_dir, $real_site_dir, $alias_id) { unl_require_writable(DRUPAL_ROOT . '/sites/sites.php'); - + $stub_token = '# %UNL_CREATION_TOOL_STUB%'; $sites_php = file_get_contents(DRUPAL_ROOT . '/sites/sites.php'); $stub_pos = strpos($sites_php, $stub_token); @@ -426,7 +427,7 @@ function unl_add_alias_to_sites_php($alias_site_dir, $real_site_dir, $alias_id) function unl_remove_alias_from_sites_php($alias_id) { unl_require_writable(DRUPAL_ROOT . '/sites/sites.php'); - + $sites_php = file_get_contents(DRUPAL_ROOT . '/sites/sites.php'); $site_start_token = "\n# %UNL_START_ALIAS_ID_{$alias_id}%"; $site_end_token = "# %UNL_END_ALIAS_ID_{$alias_id}%\n"; @@ -449,3 +450,57 @@ function unl_require_writable($path) { throw new Exception('The file "' . $path . '" needs to be writable and is not.'); } } + +/** + * Updates the name and access fields in the default site unl_sites table for display on admin/sites/unl + */ +function unl_update_unl_sites() { + // Get all sites in production + $query = db_query('SELECT * FROM {unl_sites} WHERE installed=2'); + + // Get all custom made roles (roles other than authenticated, anonymous, administrator) + $roles = user_roles(TRUE); + unset($roles[DRUPAL_AUTHENTICATED_RID]); + unset($roles[variable_get('user_admin_role')]); + + // Setup alternate db connection so we can query other sites' tables without a prefix being attached + $database_noprefix = array( + 'database' => $GLOBALS['databases']['default']['default']['database'], + 'username' => $GLOBALS['databases']['default']['default']['username'], + 'password' => $GLOBALS['databases']['default']['default']['password'], + 'host' => $GLOBALS['databases']['default']['default']['host'], + 'port' => $GLOBALS['databases']['default']['default']['port'], + 'driver' => $GLOBALS['databases']['default']['default']['driver'], + ); + Database::addConnectionInfo('UNLNoPrefix', 'default', $database_noprefix); + + // The master prefix that was specified during initial drupal install + $master_prefix = $GLOBALS['databases']['default']['default']['prefix']; + + while ($row = $query->fetchAssoc()) { + // Switch to alt db connection + db_set_active('UNLNoPrefix'); + + // Get site name + $table = $row['db_prefix'].'_'.$master_prefix.'variable'; + $name = db_query("SELECT value FROM ".$table." WHERE name = 'site_name'")->fetchField(); + + // Get last access timestamp (by a non-administrator) + $table_users = $row['db_prefix'].'_'.$master_prefix.'users u'; + $table_users_roles = $row['db_prefix'].'_'.$master_prefix.'users_roles r'; + if (!empty($roles)) { + $access = db_query('SELECT u.access FROM '.$table_users.', '.$table_users_roles.' WHERE u.uid = r.uid AND u.access > 0 AND r.rid IN (' . implode(',', array_keys($roles)) . ') ORDER BY u.access DESC')->fetchColumn(); + } else { + $access = 0; + } + + // Restore default db connection + db_set_active(); + + // Update unl_sites table of the default site + db_update('unl_sites') + ->fields(array('name' => @unserialize($name), 'access' => (int)$access)) + ->condition('site_id', $row['site_id']) + ->execute(); + } +} diff --git a/sites/all/modules/unl/unl.install b/sites/all/modules/unl/unl.install index 613e7c0a..395d5d12 100644 --- a/sites/all/modules/unl/unl.install +++ b/sites/all/modules/unl/unl.install @@ -5,7 +5,7 @@ function unl_schema() { $schema['unl_sites'] = array( 'description' => 'Table of tables to be programatically created', 'fields' => array( - 'site_id' => array( + 'site_id' => array( 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, @@ -38,6 +38,20 @@ function unl_schema() { 'not null' => TRUE, 'default' => '', ), + 'name' => array( + 'description' => 'Site name entered on the site configuration page.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'access' => array( + 'description' => 'Timestamp for previous time a non-admin role accessed the site.', + 'type' => 'int', + 'length' => 11, + 'not null' => TRUE, + 'default' => 0, + ), 'site_admin' => array( 'type' => 'varchar', 'length' => 255, @@ -153,7 +167,7 @@ function unl_update_7100() { $table = array( 'description' => 'Table of tables to be programatically created', 'fields' => array( - 'site_id' => array( + 'site_id' => array( 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, @@ -364,8 +378,7 @@ function unl_update_7109() { /** * Updates unl sites and site aliases to have trailing slashes. */ -function unl_update_7110() -{ +function unl_update_7110() { db_query("UPDATE {unl_sites} SET site_path = CONCAT(site_path, '/') WHERE SUBSTRING(site_path, -1) != '/'"); db_query("UPDATE {unl_sites} SET uri = CONCAT(uri, '/') WHERE SUBSTRING(uri, -1) != '/'"); db_query("UPDATE {unl_sites_aliases} SET base_uri = CONCAT(base_uri, '/') WHERE SUBSTRING(base_uri, -1) != '/'"); @@ -389,3 +402,23 @@ function unl_update_7112() { ); variable_set('unl_module_whitelist', $modules); } + +/** + * Add name and access fields to unl_sites table to hold site name and last access timestamp. + */ +function unl_update_7113() { + db_add_field('unl_sites', 'name', array( + 'description' => 'Site name entered on the site configuration page.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + )); + db_add_field('unl_sites', 'access', array( + 'description' => 'Timestamp for previous time a non-admin role accessed the site.', + 'type' => 'int', + 'length' => 11, + 'not null' => TRUE, + 'default' => 0, + )); +} diff --git a/sites/all/modules/unl/unl_site_creation.php b/sites/all/modules/unl/unl_site_creation.php index a4fc7b82..2e5aa139 100644 --- a/sites/all/modules/unl/unl_site_creation.php +++ b/sites/all/modules/unl/unl_site_creation.php @@ -95,32 +95,19 @@ function unl_site_create_submit($form, &$form_state) { * Site List appears on admin/sites/unl, admin/sites/unl/sites */ function unl_site_list($form, &$form_state) { - // Get all the custom made roles - $roles = user_roles(TRUE); - unset($roles[DRUPAL_AUTHENTICATED_RID]); - unset($roles[variable_get('user_admin_role')]); - $roles_in = implode(',', array_keys($roles)); //For use in the DB query - - // Setup alternate db connection so we can query other sites' tables without a prefix being attached - global $databases; - $database_noprefix = array( - 'database' => $databases['default']['default']['database'], - 'username' => $databases['default']['default']['username'], - 'password' => $databases['default']['default']['password'], - 'host' => $databases['default']['default']['host'], - 'port' => $databases['default']['default']['port'], - 'driver' => $databases['default']['default']['driver'], - ); - Database::addConnectionInfo('UNLNoPrefix', 'default', $database_noprefix); - db_set_active('UNLNoPrefix'); - $header = array( 'uri' => array( 'data' => t('Default Path'), 'field' => 's.uri', ), - 'site_name' => t('Site Name'), - 'last_access' => t('Last Access'), + 'name' => array( + 'data' => t('Site Name'), + 'field' => 's.name', + ), + 'access' => array( + 'data' => t('Last Access'), + 'field' => 's.access', + ), 'installed' => array( 'data' => t('Status'), 'field' => 's.installed', @@ -128,70 +115,19 @@ function unl_site_list($form, &$form_state) { 'operations' => t('Operations'), ); - // The master prefix that was specified during initial drupal install - $master_prefix = $databases['default']['default']['prefix']; - - // Get all the db prefixes for every UNL site sorted by uri - $prefixes = db_query('SELECT db_prefix FROM ' . $master_prefix . 'unl_sites ORDER BY uri')->fetchCol(); - if (isset($_GET['sort']) && $_GET['sort'] == 'desc' && (!isset($_GET['order']) || (isset($_GET['order']) && $_GET['order'] !== 'Status'))) { - $prefixes = array_reverse($prefixes); - } - - // Get a portion of the prefixes based on the page - $prefixes = new ArrayIterator($prefixes); - $count = 50; - $offset = (isset($_GET['page']) ? (int)$_GET['page'] : 0) * $count; - $prefixIterator = new LimitIterator($prefixes, $offset, $count); - - // Prepare the CASE expression for the following query - $case_expression = "CASE"; - foreach ($prefixIterator as $key => $prefix) { - if (db_table_exists($prefix.'_'.$master_prefix.'variable')) { - $case_expression .= " WHEN {u}.db_prefix = '".$prefix."' THEN p".$key.".value"; - } - } - $case_expression .= " ELSE '* Scheduled for creation (or Error)' END"; - - // Combines the site_id from the unl_sites table with the corresponding site_name from [unl_sites.db_prefix]_variable table - $subquery = db_select($master_prefix.'unl_sites', 'u'); - $subquery->addField('u', 'site_id', 'site_id'); - $subquery->addExpression($case_expression, 'site_name'); - foreach ($prefixIterator as $key => $prefix) { - if (db_table_exists($prefix.'_'.$master_prefix.'variable')) { - $subquery->leftJoin($prefix.'_'.$master_prefix.'variable', 'p'.$key, 'p'.$key.'.name = :site_name', array('site_name'=>'site_name')); - } - } - - // The query that will be displayed - uses the subquery above in a JOIN - $sites = db_select($master_prefix.'unl_sites', 's'); - $sites->join($subquery, 'i', 'i.site_id=s.site_id'); - $sites = $sites - ->fields('s', array('site_id', 'db_prefix', 'installed', 'site_path', 'uri')) - ->fields('i', array('site_name')) - ->extend('TableSort')->extend('PagerDefault')->limit($count) + $sites = db_select('unl_sites', 's') + ->fields('s', array('site_id', 'db_prefix', 'installed', 'site_path', 'uri', 'name', 'access')) + ->extend('TableSort') ->orderByHeader($header) ->execute() ->fetchAll(); - // Generate an array of Last Access timestamps for each site based on time last accessed by someone in a non-admin role - foreach ($sites as $site) { - if (db_table_exists($site->db_prefix.'_'.$master_prefix.'users') && - db_table_exists($site->db_prefix.'_'.$master_prefix.'users_roles') && - !empty($roles_in)) { - $query = 'SELECT u.access FROM '.$site->db_prefix.'_'.$master_prefix.'users u, '.$site->db_prefix.'_'.$master_prefix.'users_roles r WHERE u.uid = r.uid AND u.access > 0 AND r.rid IN ('.$roles_in.') ORDER BY u.access DESC'; - $last_access[$site->site_id] = db_query($query)->fetchColumn(); - } - } - - // Restore default db connection - db_set_active(); - - // Setup the form + $options = array(); foreach ($sites as $site) { $options[$site->site_id] = array( 'uri' => theme('unl_site_details', array('site_path' => $site->site_path, 'uri' => $site->uri, 'db_prefix' => $site->db_prefix)), - 'site_name' => @unserialize($site->site_name), - 'last_access' => (isset($last_access[$site->site_id]) && $last_access[$site->site_id]) ? t('@time ago', array('@time' => format_interval(REQUEST_TIME - $last_access[$site->site_id]))) : t('never'), + 'site_name' => $site->name, + 'last_access' => (isset($site->access) && $site->access > 0) ? t('@time ago', array('@time' => format_interval(REQUEST_TIME - $site->access))) : t('never'), 'installed' => _unl_get_install_status_text($site->installed), 'operations' => array( 'data' => array( @@ -211,7 +147,7 @@ function unl_site_list($form, &$form_state) { $form['unl_sites'] = array( '#type' => 'fieldset', - '#title' => t('Existing Sites: ') . count($prefixes), + '#title' => t('Existing Sites: ') . count($sites), ); $form['unl_sites']['site_list'] = array( '#theme' => 'table', @@ -219,16 +155,17 @@ function unl_site_list($form, &$form_state) { '#rows' => $options, '#empty' => t('No sites available.'), ); - $form['unl_sites']['pager'] = array('#markup' => theme('pager', array('tags' => NULL))); + return $form; } /** - * Implements theme_CUSTOM() which works with unl_theme() + * Implements theme_CUSTOM() which works with unl_theme(). + * This themes the Default Path column on the UNL Sites tables at admin/sites/unl */ function theme_unl_site_details($variables) { $output = '<div><a href="' . $variables['uri'] . '">' . $variables['site_path'] . '</a></div>'; - $output .= '<div style="display:none;">Database Prefix: ' . $variables['db_prefix'] . '_' . $GLOBALS['databases']['default']['default']['prefix'] . '</div>'; + $output .= '<div class="db_prefix" style="display:none;">Database Prefix: ' . $variables['db_prefix'] . '_' . $GLOBALS['databases']['default']['default']['prefix'] . '</div>'; return $output; } @@ -884,7 +821,7 @@ function theme_unl_table($variables) { $form['#rows'][$row_index][$column_index] = drupal_render($form['rows'][$row_index][$column_index]); } } - + return theme('table', $form); } -- GitLab