SessionServiceProvider.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /**
  3. * @package Grav\Common\Service
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Service;
  9. use Grav\Common\Config\Config;
  10. use Grav\Common\Debugger;
  11. use Grav\Common\Session;
  12. use Grav\Common\Uri;
  13. use Grav\Common\Utils;
  14. use Grav\Framework\Session\Messages;
  15. use Pimple\Container;
  16. use Pimple\ServiceProviderInterface;
  17. /**
  18. * Class SessionServiceProvider
  19. * @package Grav\Common\Service
  20. */
  21. class SessionServiceProvider implements ServiceProviderInterface
  22. {
  23. /**
  24. * @param Container $container
  25. * @return void
  26. */
  27. public function register(Container $container)
  28. {
  29. // Define session service.
  30. $container['session'] = static function ($c) {
  31. /** @var Config $config */
  32. $config = $c['config'];
  33. /** @var Uri $uri */
  34. $uri = $c['uri'];
  35. // Get session options.
  36. $enabled = (bool)$config->get('system.session.enabled', false);
  37. $cookie_secure = $config->get('system.session.secure', false)
  38. || ($config->get('system.session.secure_https', true) && $uri->scheme(true) === 'https');
  39. $cookie_httponly = (bool)$config->get('system.session.httponly', true);
  40. $cookie_lifetime = (int)$config->get('system.session.timeout', 1800);
  41. $cookie_domain = $config->get('system.session.domain');
  42. $cookie_path = $config->get('system.session.path');
  43. $cookie_samesite = $config->get('system.session.samesite', 'Lax');
  44. if (null === $cookie_domain) {
  45. $cookie_domain = $uri->host();
  46. if ($cookie_domain === 'localhost') {
  47. $cookie_domain = '';
  48. }
  49. }
  50. if (null === $cookie_path) {
  51. $cookie_path = '/' . trim(Uri::filterPath($uri->rootUrl(false)), '/');
  52. }
  53. // Session cookie path requires trailing slash.
  54. $cookie_path = rtrim($cookie_path, '/') . '/';
  55. // Activate admin if we're inside the admin path.
  56. $is_admin = false;
  57. if ($config->get('plugins.admin.enabled')) {
  58. $admin_base = '/' . trim($config->get('plugins.admin.route'), '/');
  59. // Uri::route() is not processed yet, let's quickly get what we need.
  60. $current_route = str_replace(Uri::filterPath($uri->rootUrl(false)), '', parse_url($uri->url(true), PHP_URL_PATH));
  61. // Test to see if path starts with a supported language + admin base
  62. $lang = Utils::pathPrefixedByLangCode($current_route);
  63. $lang_admin_base = '/' . $lang . $admin_base;
  64. // Check no language, simple language prefix (en) and region specific language prefix (en-US).
  65. if (Utils::startsWith($current_route, $admin_base) || Utils::startsWith($current_route, $lang_admin_base)) {
  66. $cookie_lifetime = $config->get('plugins.admin.session.timeout', 1800);
  67. $enabled = $is_admin = true;
  68. }
  69. }
  70. // Fix for HUGE session timeouts.
  71. if ($cookie_lifetime > 99999999999) {
  72. $cookie_lifetime = 9999999999;
  73. }
  74. $session_prefix = $c['inflector']->hyphenize($config->get('system.session.name', 'grav-site'));
  75. $session_uniqueness = $config->get('system.session.uniqueness', 'path') === 'path' ? substr(md5(GRAV_ROOT), 0, 7) : md5($config->get('security.salt'));
  76. $session_name = $session_prefix . '-' . $session_uniqueness;
  77. if ($is_admin && $config->get('system.session.split', true)) {
  78. $session_name .= '-admin';
  79. }
  80. // Define session service.
  81. $options = [
  82. 'name' => $session_name,
  83. 'cookie_lifetime' => $cookie_lifetime,
  84. 'cookie_path' => $cookie_path,
  85. 'cookie_domain' => $cookie_domain,
  86. 'cookie_secure' => $cookie_secure,
  87. 'cookie_httponly' => $cookie_httponly,
  88. 'cookie_samesite' => $cookie_samesite
  89. ] + (array) $config->get('system.session.options');
  90. $session = new Session($options);
  91. $session->setAutoStart($enabled);
  92. return $session;
  93. };
  94. // Define session message service.
  95. $container['messages'] = function ($c) {
  96. if (!isset($c['session']) || !$c['session']->isStarted()) {
  97. /** @var Debugger $debugger */
  98. $debugger = $c['debugger'];
  99. $debugger->addMessage('Inactive session: session messages may disappear', 'warming');
  100. return new Messages();
  101. }
  102. /** @var Session $session */
  103. $session = $c['session'];
  104. if (!$session->messages instanceof Messages) {
  105. $session->messages = new Messages();
  106. }
  107. return $session->messages;
  108. };
  109. }
  110. }