diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index c14ab53..399fd38 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -387,6 +387,13 @@ function conf_path($require_settings = TRUE, $reset = FALSE) { return $conf; } + // Check for a simpletest override. + if ($simpletest_conf_path = _drupal_simpletest_conf_path()) { + $conf = $simpletest_conf_path; + return $conf; + } + + // Otherwise, use the normal $conf_path. $script_name = $_SERVER['SCRIPT_NAME']; if (!$script_name) { $script_name = $_SERVER['SCRIPT_FILENAME']; @@ -397,6 +404,49 @@ function conf_path($require_settings = TRUE, $reset = FALSE) { } /** + * Determines whether to use an overridden value for conf_path(). + * + * Simpletest may provide a secondary, test-specific settings.php file to load + * after (and therefore override variables set by) the primary one used by the + * parent site. If the child settings.php does not override $conf_path, then + * this function returns FALSE and conf_path() returns the directory of the + * primary settings.php. If the child settings.php does override $conf_path, + * then _drupal_load_test_overrides() sets the 'simpletest_conf_path' setting, + * and this function returns that to conf_path(), causing installations and + * upgrades to act on that one. + * + * @return string|false + * The overridden $conf_path, or FALSE if the $conf_path should not currently + * be overridden. + * + * @see conf_path() + * @see _drupal_load_test_overrides() + */ +function _drupal_simpletest_conf_path() { + // Ensure that the settings object is available. conf_path() is called once + // before the Settings class is included, and at that point it should still + // load the primary $conf_path. + if (!class_exists('Drupal\Component\Utility\Settings', FALSE)) { + return FALSE; + } + + // If no $simpletest_conf_path is set, use the normal $conf_path. + if (!($simpletest_conf_path = settings()->get('simpletest_conf_path'))) { + return FALSE; + } + + // Ensure that this is actually a simpletest request. We can't check this + // before the settings object is available. + if (!drupal_valid_test_ua()) { + return FALSE; + } + + // Otherwise, when the $simpletest_conf_path is set in a valid test request, + // return that path. + return $simpletest_conf_path; +} + +/** * Finds the appropriate configuration directory for a given host and path. * * Finds a matching configuration directory file by stripping the website's @@ -474,11 +524,7 @@ function find_conf_path($http_host, $script_name, $require_settings = TRUE) { function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) { global $config_directories; - if ($test_prefix = drupal_valid_test_ua()) { - // @see Drupal\simpletest\WebTestBase::setUp() - $path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config_' . $type; - } - elseif (!empty($config_directories[$type])) { + if (!empty($config_directories[$type])) { // Allow a configuration directory path to be outside of webroot. if (empty($config_directories[$type]['absolute'])) { $path = conf_path() . '/files/' . $config_directories[$type]['path']; @@ -2554,7 +2600,7 @@ function drupal_valid_test_ua($new_prefix = NULL) { return $test_prefix; } - if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);(.+);(.+);(.+)$/", $_SERVER['HTTP_USER_AGENT'], $matches)) { + if ($drupal_hash_salt && isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);(.+);(.+);(.+)$/", $_SERVER['HTTP_USER_AGENT'], $matches)) { list(, $prefix, $time, $salt, $hmac) = $matches; $check_string = $prefix . ';' . $time . ';' . $salt; // We use the salt from settings.php to make the HMAC key, since @@ -2566,6 +2612,7 @@ function drupal_valid_test_ua($new_prefix = NULL) { // and the HMAC must match. if ($time_diff >= 0 && $time_diff <= 5 && $hmac == drupal_hmac_base64($check_string, $key)) { $test_prefix = $prefix; + _drupal_load_test_overrides($test_prefix); return $test_prefix; } } @@ -2575,6 +2622,43 @@ function drupal_valid_test_ua($new_prefix = NULL) { } /** + * Overrides low level and environment specific configuration. + * + * Very strictly for internal use only. + * + * Loads settings.php from the simpletest public files + * directory. These files can change the global $conf, the global + * $config_directories, the return value of conf_path() and + * settings(). + * + * @param $test_prefix + * The simpletest prefix. + */ +function _drupal_load_test_overrides($test_prefix) { + global $conf, $config_directories; + + // Do not use the parent site's config directories. Use only the child site's. + // @see Drupal\simpletest\TestBase::prepareConfigDirectories() + $path_prefix = 'simpletest/' . substr($test_prefix, 10); + $config_directories = array(); + foreach (array(CONFIG_ACTIVE_DIRECTORY, CONFIG_STAGING_DIRECTORY) as $type) { + $config_directories[$type] = array('path' => $path_prefix . '/config_' . $type); + } + + $filename = conf_path() . '/files/' . $path_prefix . '/settings.php'; + if (file_exists($filename)) { + $settings = settings()->getAll(); + $conf_path = &drupal_static('conf_path'); + // This can override $conf, $conf_path, $settings and $config_directories. + include $filename; + // Keep the overriden $conf_path alive across drupal_static_reset() calls. + // @see conf_path() + $settings['simpletest_conf_path'] = $conf_path; + new Settings($settings); + } +} + +/** * Generates a user agent string with a HMAC and timestamp for simpletest. */ function drupal_generate_test_ua($prefix) { diff --git a/core/includes/errors.inc b/core/includes/errors.inc index 5fc4b7d..f29def7 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -153,7 +153,7 @@ function _drupal_render_exception_safe($exception) { * TRUE if an error should be displayed. */ function error_displayable($error = NULL) { - $error_level = config('system.logging')->get('error_level'); + $error_level = _drupal_get_error_level(); $updating = (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update'); $all_errors_displayed = ($error_level == ERROR_REPORTING_DISPLAY_ALL) || ($error_level == ERROR_REPORTING_DISPLAY_VERBOSE); @@ -254,7 +254,7 @@ function _drupal_log_error($error, $fatal = FALSE) { $message = format_string('%type: !message in %function (line %line of %file).', $error); // Check if verbose error reporting is on. - $error_level = config('system.logging')->get('error_level'); + $error_level = _drupal_get_error_level(); if ($error_level == ERROR_REPORTING_DISPLAY_VERBOSE) { // First trace is the error itself, already contained in the message. @@ -287,6 +287,29 @@ function _drupal_log_error($error, $fatal = FALSE) { } /** + * Returns the current error level. + * + * This function should only be used to get the current error level pre + * DRUPAL_BOOTSTRAP_KERNEL or before Drupal is installed. In all other + * situations the following code is preferred: + * @code + * Drupal::config('system.logging')->get('error_level'); + * @endcode + * + * @return string + * The current error level. + */ +function _drupal_get_error_level() { + try { + return Drupal::config('system.logging')->get('error_level'); + } + catch (Exception $e) { + // During very early install the cache_config table does not exist. + return ERROR_REPORTING_DISPLAY_ALL; + } +} + +/** * Gets the last caller from a backtrace. * * @param $backtrace diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index df688ab..a5c5c22 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1,5 +1,6 @@ getNamespaceName(); @@ -1057,8 +1064,11 @@ function install_settings_form_validate($form, &$form_state) { $database['driver'] = $driver; // TODO: remove when PIFR will be updated to use 'db_prefix' instead of - // 'prefix' in the database settings form. - $database['prefix'] = $database['db_prefix']; + // 'prefix' in the database settings form with the non-interactive + // installer. + if (!$test_prefix) { + $database['prefix'] = $database['db_prefix']; + } unset($database['db_prefix']); $form_state['storage']['database'] = $database; @@ -1118,14 +1128,34 @@ function install_settings_form_submit($form, &$form_state) { global $install_state; // Update global settings array and save. - $settings['databases'] = (object) array( - 'value' => array('default' => array('default' => $form_state['storage']['database'])), - 'required' => TRUE, - ); - $settings['drupal_hash_salt'] = (object) array( - 'value' => drupal_hash_base64(drupal_random_bytes(55)), - 'required' => TRUE, - ); + $settings = array(); + $database = $form_state['storage']['database']; + if ($test_prefix = drupal_valid_test_ua()) { + // This is test specific code, however it is very small and contained. + foreach ($form_state['storage']['database'] as $k => $v) { + if ($k != 'password') { + $settings['databases']['default']['default'][$k] = (object) array( + 'value' => $v, + 'required' => TRUE, + ); + } + } + } + else { + // Because of the test specific code above, this assignment here must be + // kept simple and must not call any functions to avoid creating a tested + // and a non-tested code path. + $settings['databases']['default']['default'] = (object) array( + 'value' => $database, + 'required' => TRUE, + ); + } + if (!$test_prefix) { + $settings['drupal_hash_salt'] = (object) array( + 'value' => drupal_hash_base64(drupal_random_bytes(55)), + 'required' => TRUE, + ); + } drupal_rewrite_settings($settings); @@ -1609,7 +1639,7 @@ function install_already_done_error() { global $base_url; drupal_set_title(st('Drupal already installed')); - return st('', array('@base-url' => $base_url)); + return st('', array('@base-url' => $base_url)); } /** diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index 37775e6..cda4109 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -50,7 +50,17 @@ function _drupal_maintenance_theme() { // Stark otherwise. Since there is no low-level access to configuration // currently, we only consult settings.php and fall back to Bartik // otherwise, as it looks generic enough and way more user-friendly. - $custom_theme = variable_get('maintenance_theme', config('system.theme')->get('default')) ?: 'bartik'; + $custom_theme = variable_get('maintenance_theme'); + if (!$custom_theme) { + $config = Drupal::config('system.theme'); + // A broken install might not return an object. + if (is_object($config)) { + $custom_theme = $config->get('default'); + } + } + if (!$custom_theme) { + $custom_theme = 'bartik'; + } } // Ensure that system.module is loaded. diff --git a/core/lib/Drupal/Core/SystemListingInfo.php b/core/lib/Drupal/Core/SystemListingInfo.php index b2e42e1..989b0f2 100644 --- a/core/lib/Drupal/Core/SystemListingInfo.php +++ b/core/lib/Drupal/Core/SystemListingInfo.php @@ -28,7 +28,7 @@ protected function profiles($directory) { // For SimpleTest to be able to test modules packaged together with a // distribution we need to include the profile of the parent site (in // which test runs are triggered). - if (drupal_valid_test_ua()) { + if (drupal_valid_test_ua() && !drupal_installation_attempted()) { $testing_profile = config('simpletest.settings')->get('parent_profile'); if ($testing_profile && $testing_profile != $profile) { $searchdir[] = drupal_get_path('profile', $testing_profile) . '/' . $directory; diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 5cca38a..b24bba3 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -859,6 +859,36 @@ protected function setUp() { } /** + * Writes a test-specific settings.php file for the child site. + * + * The child site loads this after the parent site's settings.php, so settings + * here override those. + * + * @param $settings An array of settings to write out, in the format expected + * by drupal_rewrite_settings(). + * + * @see _drupal_load_test_overrides() + * @see drupal_rewrite_settings() + */ + protected function writeSettings($settings) { + // drupal_rewrite_settings() sets the in-memory global variables in addition + // to writing the file. We'll want to restore the original globals. + foreach (array_keys($settings) as $variable_name) { + $original_globals[$variable_name] = isset($GLOBALS[$variable_name]) ? $GLOBALS[$variable_name] : NULL; + } + + include_once DRUPAL_ROOT . '/core/includes/install.inc'; + $filename = $this->public_files_directory . '/settings.php'; + file_put_contents($filename, " $value) { + $GLOBALS[$variable_name] = $value; + } + } + + /** * Reset all data structures after having enabled new modules. * * This method is called by Drupal\simpletest\WebTestBase::setUp() after enabling @@ -1328,9 +1358,9 @@ protected function drupalPost($path, $edit, $submit, array $options = array(), a $this->fail(t('Failed to set field @name to @value', array('@name' => $name, '@value' => $value))); } if (!$ajax && isset($submit)) { - $this->assertTrue($submit_matches, t('Found the @submit button', array('@submit' => $submit))); + $this->assertTrue($submit_matches, format_string('Found the @submit button', array('@submit' => $submit))); } - $this->fail(t('Found the requested form fields at @path', array('@path' => $path))); + $this->fail(format_string('Found the requested form fields at @path', array('@path' => $path))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/InstallerTest.php b/core/modules/system/lib/Drupal/system/Tests/InstallerTest.php new file mode 100644 index 0000000..5afb59e --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/InstallerTest.php @@ -0,0 +1,138 @@ + 'Installer tests', + 'description' => 'Tests the interactive installer.', + 'group' => 'Devilry', + ); + } + + protected function setUp() { + global $conf; + + // When running tests through the Simpletest UI (vs. on the command line), + // Simpletest's batch conflicts with the installer's batch. Batch API does + // not support the concept of nested batches (in which the nested is not + // progressive), so we need to temporarily pretend there was no batch. + // Backup the currently running Simpletest batch. + $this->originalBatch = batch_get(); + + // Create the database prefix for this test. + $this->prepareDatabasePrefix(); + + // Prepare the environment for running tests. + $this->prepareEnvironment(); + if (!$this->setupEnvironment) { + return FALSE; + } + + // Reset all statics and variables to perform tests in a clean environment. + $conf = array(); + drupal_static_reset(); + + // Change the database prefix. + // All static variables need to be reset before the database prefix is + // changed, since Drupal\Core\Utility\CacheArray implementations attempt to + // write back to persistent caches when they are destructed. + $this->changeDatabasePrefix(); + if (!$this->setupDatabasePrefix) { + return FALSE; + } + $variable_groups = array( + 'system.file' => array( + 'path.private' => $this->private_files_directory, + 'path.temporary' => $this->temp_files_directory, + ), + 'locale.settings' => array( + 'translation.path' => $this->translation_files_directory, + ), + ); + foreach ($variable_groups as $config_base => $variables) { + foreach ($variables as $name => $value) { + NestedArray::setValue($GLOBALS['conf'], array_merge(array($config_base), explode('.', $name)), $value); + } + } + $GLOBALS['conf']['file_public_path'] = $this->public_files_directory; + $settings['conf_path'] = (object) array( + 'value' => $this->public_files_directory, + 'required' => TRUE, + ); + $settings['config_directories'] = (object) array( + 'value' => array(), + 'required' => TRUE, + ); + $this->writeSettings($settings); + + $this->drupalGet('core/install.php?langcode=en&profile=minimal'); + $this->drupalPost(NULL, array(), 'Save and continue'); + // Reload config directories. + include $this->public_files_directory . '/settings.php'; + $prefix = substr($this->public_files_directory, strlen(conf_path() . '/files/')); + foreach ($config_directories as $type => $data) { + $GLOBALS['config_directories'][$type]['path'] = $prefix . '/files/' . $data['path']; + } + $this->rebuildContainer(); + + foreach ($variable_groups as $config_base => $variables) { + $config = config($config_base); + foreach ($variables as $name => $value) { + $config->set($name, $value); + } + $config->save(); + } + variable_set('file_public_path', $this->public_files_directory); + + // Use the test mail class instead of the default mail handler class. + config('system.mail')->set('interface.default', 'Drupal\Core\Mail\VariableLog')->save(); + + drupal_set_time_limit($this->timeLimit); + // Temporary fix so that when running from run-tests.sh we don't get an + // empty current path which would indicate we're on the home page. + $path = current_path(); + if (empty($path)) { + _current_path('run-tests'); + } + $this->setup = TRUE; + } + + protected function refreshVariables() { + if (!empty($this->setup)) { + parent::refreshVariables(); + } + } + + protected function drupalGet($path, array $options = array(), array $headers = array()) { + + // We re-using a CURL connection here. If that connection still has certain + // options set, it might change the GET into a POST. Make sure we clear out + // previous options. + $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $this->getAbsoluteUrl($path), CURLOPT_NOBODY => FALSE, CURLOPT_HTTPHEADER => $headers)); + $this->refreshVariables(); // Ensure that any changes to variables in the other thread are picked up. + + // Replace original page output with new output from redirected page(s). + if ($new = $this->checkForMetaRefresh()) { + $out = $new; + } + $this->verbose('GET request to: ' . $path . + '
Ending URL: ' . $this->getUrl() . + '
' . $out); + return $out; + } + + function testInstaller() { + $this->drupalGet('user'); + } +} \ No newline at end of file diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php new file mode 100644 index 0000000..2ac0b68 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalAnonymousUpgradePathTest.php @@ -0,0 +1,48 @@ + 'Basic minimal profile upgrade, free access', + 'description' => 'Basic upgrade path tests for a minimal profile install with a bare database and update_free_access set to TRUE.', + 'group' => 'Upgrade path', + ); + } + + /** + * Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::setUp(). + */ + public function setUp() { + parent::setUp(); + + $settings['settings']['update_free_access'] = (object) array( + 'value' => TRUE, + 'required' => TRUE, + ); + $this->writeSettings($settings); + } + + /** + * Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::prepareD8Session(). + */ + protected function prepareD8Session() { + // We are not logged in, nothing to do. + } + + /** + * Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::assertSessionKept(). + */ + protected function assertSessionKept() { + // We are not logged in, nothing to do. + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalNoConfigUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalNoConfigUpgradePathTest.php new file mode 100644 index 0000000..36a3a03 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalNoConfigUpgradePathTest.php @@ -0,0 +1,65 @@ + 'Basic minimal profile upgrade, no config', + 'description' => 'Basic upgrade path tests for a minimal profile install with a bare database and config directory not pre-created.', + 'group' => 'Upgrade path', + ); + } + + /** + * Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::setUp(). + */ + public function setUp() { + parent::setUp(); + + $settings['conf_path'] = (object) array( + 'value' => $this->public_files_directory, + 'required' => TRUE, + ); + $settings['config_directories'] = (object) array( + 'value' => array(), + 'required' => TRUE, + ); + $this->writeSettings($settings); + } + + /** + * Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::refreshVariables(). + */ + protected function refreshVariables() { + // Refresh the variables only if the site was already upgraded. + if ($this->upgradedSite) { + // update.php puts the new, randomized config directries in this file. + include $this->public_files_directory . '/settings.php'; + $GLOBALS['config_directories'] = array(); + foreach ($config_directories as $type => $data) { + // update.php runs as the child site, so writes the paths relative to + // that "$conf_path/files", but here, we're running as the parent site, + // so need to make the paths relative to our "conf_path()/files". + // + // Example: + // - Parent site conf_path(): 'sites/default' + // - Child site $conf_path: 'sites/default/files/simpletest/123456' + // - Child site $data['path']: 'config_xyz' + // - Desired result: 'simpletest/123456/files/config_xyz' + // + // @see config_get_config_directory() + $GLOBALS['config_directories'][$type]['path'] = substr($conf_path, strlen(conf_path() . '/files/')) . '/files/' . $data['path']; + } + parent::refreshVariables(); + } + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php index 9c51bee..ab58790 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BareMinimalUpgradePathTest.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\system\Tests\Upgrade\BareMinimalUpgradePathTest. + * Contains \Drupal\system\Tests\Upgrade\BareMinimalUpgradePathTest. */ namespace Drupal\system\Tests\Upgrade; @@ -43,12 +43,7 @@ public function testBasicMinimalUpgrade() { $this->assertResponse(200); // Verify that we are still logged in. - $this->drupalGet('user'); - $this->clickLink(t('Edit')); - $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), 'We are still logged in as admin at the end of the upgrade.'); - - // Logout and verify that we can login back in with our initial password. - $this->drupalLogout(); + $this->assertSessionKept(); $this->drupalLogin((object) array( 'uid' => 1, 'name' => 'admin', @@ -95,4 +90,14 @@ public function testBasicMinimalUpgrade() { $this->assertEqual(array('default' => 'Drupal\Core\Mail\PhpMail'), config('system.mail')->get('interface'), 'Default mail configuration set.'); } + /** + * Asserts that the session was kept during update. Also, log out. + */ + protected function assertSessionKept() { + $this->drupalGet('user'); + $this->clickLink(t('Edit')); + $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), 'We are still logged in as admin at the end of the upgrade.'); + $this->drupalLogout(); + } + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php index 74c9923..c809829 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php @@ -73,7 +73,7 @@ protected function checkRequirements() { * @see Drupal\simpletest\WebTestBase::changeDatabasePrefix() * @see Drupal\simpletest\WebTestBase::prepareEnvironment() */ - protected function setUp() { + public function setUp() { global $user, $conf; // Load the Update API. diff --git a/core/modules/system/system.install b/core/modules/system/system.install index a93a124..445b27c 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -397,7 +397,9 @@ function system_requirements($phase) { } } else { - if (file_default_scheme() == 'public') { + // This function can be called before the config_cache table has been + // created. + if ($phase == 'install' || file_default_scheme() == 'public') { $requirements['file system']['value'] = $t('Writable (public download method)'); } else { diff --git a/core/modules/user/user.module b/core/modules/user/user.module index bdf5862..46f8807 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -719,6 +719,12 @@ function user_format_name($account) { function user_template_preprocess_default_variables_alter(&$variables) { global $user; + // If this function is called from the installer after Drupal has been + // installed then $user will not be set. + if (!is_object($user)) { + return; + } + $variables['user'] = clone $user; // Remove password and session IDs, since themes should not need nor see them. unset($variables['user']->pass, $variables['user']->sid, $variables['user']->ssid);