[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/symfony/http-foundation/Session/Storage/Handler/ -> MongoDbSessionHandler.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
  13  
  14  /**
  15   * Session handler using the mongodb/mongodb package and MongoDB driver extension.
  16   *
  17   * @author Markus Bachmann <markus.bachmann@bachi.biz>
  18   *
  19   * @see https://packagist.org/packages/mongodb/mongodb
  20   * @see https://php.net/mongodb
  21   */
  22  class MongoDbSessionHandler extends AbstractSessionHandler
  23  {
  24      private $mongo;
  25  
  26      /**
  27       * @var \MongoCollection
  28       */
  29      private $collection;
  30  
  31      /**
  32       * @var array
  33       */
  34      private $options;
  35  
  36      /**
  37       * Constructor.
  38       *
  39       * List of available options:
  40       *  * database: The name of the database [required]
  41       *  * collection: The name of the collection [required]
  42       *  * id_field: The field name for storing the session id [default: _id]
  43       *  * data_field: The field name for storing the session data [default: data]
  44       *  * time_field: The field name for storing the timestamp [default: time]
  45       *  * expiry_field: The field name for storing the expiry-timestamp [default: expires_at].
  46       *
  47       * It is strongly recommended to put an index on the `expiry_field` for
  48       * garbage-collection. Alternatively it's possible to automatically expire
  49       * the sessions in the database as described below:
  50       *
  51       * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions
  52       * automatically. Such an index can for example look like this:
  53       *
  54       *     db.<session-collection>.ensureIndex(
  55       *         { "<expiry-field>": 1 },
  56       *         { "expireAfterSeconds": 0 }
  57       *     )
  58       *
  59       * More details on: https://docs.mongodb.org/manual/tutorial/expire-data/
  60       *
  61       * If you use such an index, you can drop `gc_probability` to 0 since
  62       * no garbage-collection is required.
  63       *
  64       * @param \MongoDB\Client $mongo   A MongoDB\Client instance
  65       * @param array           $options An associative array of field options
  66       *
  67       * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
  68       * @throws \InvalidArgumentException When "database" or "collection" not provided
  69       */
  70      public function __construct($mongo, array $options)
  71      {
  72          if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) {
  73              @trigger_error(sprintf('Using %s with the legacy mongo extension is deprecated as of 3.4 and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.', __CLASS__), \E_USER_DEPRECATED);
  74          }
  75  
  76          if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
  77              throw new \InvalidArgumentException('MongoClient or Mongo instance required.');
  78          }
  79  
  80          if (!isset($options['database']) || !isset($options['collection'])) {
  81              throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
  82          }
  83  
  84          $this->mongo = $mongo;
  85  
  86          $this->options = array_merge([
  87              'id_field' => '_id',
  88              'data_field' => 'data',
  89              'time_field' => 'time',
  90              'expiry_field' => 'expires_at',
  91          ], $options);
  92      }
  93  
  94      /**
  95       * {@inheritdoc}
  96       */
  97      public function close()
  98      {
  99          return true;
 100      }
 101  
 102      /**
 103       * {@inheritdoc}
 104       */
 105      protected function doDestroy($sessionId)
 106      {
 107          $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove';
 108  
 109          $this->getCollection()->$methodName([
 110              $this->options['id_field'] => $sessionId,
 111          ]);
 112  
 113          return true;
 114      }
 115  
 116      /**
 117       * {@inheritdoc}
 118       */
 119      public function gc($maxlifetime)
 120      {
 121          $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteMany' : 'remove';
 122  
 123          $this->getCollection()->$methodName([
 124              $this->options['expiry_field'] => ['$lt' => $this->createDateTime()],
 125          ]);
 126  
 127          return true;
 128      }
 129  
 130      /**
 131       * {@inheritdoc}
 132       */
 133      protected function doWrite($sessionId, $data)
 134      {
 135          $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
 136  
 137          $fields = [
 138              $this->options['time_field'] => $this->createDateTime(),
 139              $this->options['expiry_field'] => $expiry,
 140          ];
 141  
 142          $options = ['upsert' => true];
 143  
 144          if ($this->mongo instanceof \MongoDB\Client) {
 145              $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY);
 146          } else {
 147              $fields[$this->options['data_field']] = new \MongoBinData($data, \MongoBinData::BYTE_ARRAY);
 148              $options['multiple'] = false;
 149          }
 150  
 151          $methodName = $this->mongo instanceof \MongoDB\Client ? 'updateOne' : 'update';
 152  
 153          $this->getCollection()->$methodName(
 154              [$this->options['id_field'] => $sessionId],
 155              ['$set' => $fields],
 156              $options
 157          );
 158  
 159          return true;
 160      }
 161  
 162      /**
 163       * {@inheritdoc}
 164       */
 165      public function updateTimestamp($sessionId, $data)
 166      {
 167          $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
 168  
 169          if ($this->mongo instanceof \MongoDB\Client) {
 170              $methodName = 'updateOne';
 171              $options = [];
 172          } else {
 173              $methodName = 'update';
 174              $options = ['multiple' => false];
 175          }
 176  
 177          $this->getCollection()->$methodName(
 178              [$this->options['id_field'] => $sessionId],
 179              ['$set' => [
 180                  $this->options['time_field'] => $this->createDateTime(),
 181                  $this->options['expiry_field'] => $expiry,
 182              ]],
 183              $options
 184          );
 185  
 186          return true;
 187      }
 188  
 189      /**
 190       * {@inheritdoc}
 191       */
 192      protected function doRead($sessionId)
 193      {
 194          $dbData = $this->getCollection()->findOne([
 195              $this->options['id_field'] => $sessionId,
 196              $this->options['expiry_field'] => ['$gte' => $this->createDateTime()],
 197          ]);
 198  
 199          if (null === $dbData) {
 200              return '';
 201          }
 202  
 203          if ($dbData[$this->options['data_field']] instanceof \MongoDB\BSON\Binary) {
 204              return $dbData[$this->options['data_field']]->getData();
 205          }
 206  
 207          return $dbData[$this->options['data_field']]->bin;
 208      }
 209  
 210      /**
 211       * Return a "MongoCollection" instance.
 212       *
 213       * @return \MongoCollection
 214       */
 215      private function getCollection()
 216      {
 217          if (null === $this->collection) {
 218              $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
 219          }
 220  
 221          return $this->collection;
 222      }
 223  
 224      /**
 225       * Return a Mongo instance.
 226       *
 227       * @return \Mongo|\MongoClient|\MongoDB\Client
 228       */
 229      protected function getMongo()
 230      {
 231          return $this->mongo;
 232      }
 233  
 234      /**
 235       * Create a date object using the class appropriate for the current mongo connection.
 236       *
 237       * Return an instance of a MongoDate or \MongoDB\BSON\UTCDateTime
 238       *
 239       * @param int $seconds An integer representing UTC seconds since Jan 1 1970.  Defaults to now.
 240       *
 241       * @return \MongoDate|\MongoDB\BSON\UTCDateTime
 242       */
 243      private function createDateTime($seconds = null)
 244      {
 245          if (null === $seconds) {
 246              $seconds = time();
 247          }
 248  
 249          if ($this->mongo instanceof \MongoDB\Client) {
 250              return new \MongoDB\BSON\UTCDateTime($seconds * 1000);
 251          }
 252  
 253          return new \MongoDate($seconds);
 254      }
 255  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1