acquia_commercemanager-8.x-1.122/modules/acm/src/DatabaseSessionStore.php

modules/acm/src/DatabaseSessionStore.php
<?php

namespace Drupal\acm;

use Drupal\acm\User\AccountProxyInterface;
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\TempStore\PrivateTempStore;
use Drupal\Core\TempStore\TempStoreException;

/**
 * Stores and retrieves temporary data for a given owner.
 *
 * This storage should only be used if you're using e-commerce sessions.
 *
 * A DatabaseSessionStore can be used to make temporary, non-cache data
 * available across requests. The data for the DatabaseSessionStore is stored
 * in one key/value collection. DatabaseSessionStore data expires
 * automatically after a given timeframe.
 */
class DatabaseSessionStore extends PrivateTempStore implements SessionStoreInterface {

  /**
   * The key that stores the owner reference.
   *
   * @const OWNER_REFERENCE_NAMESPACE
   */
  const OWNER_REFERENCE_NAMESPACE = 'acm_owner_reference';

  /**
   * The name of the cookie that stores the session id.
   *
   * @const SESSION_ID_COOKIE
   */
  const SESSION_ID_COOKIE = 'acm_sid';

  /**
   * Constructs a new object for accessing data from a key/value store.
   *
   * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
   *   The key/value storage object used for this data. Each storage object
   *   represents a particular collection of data and will contain any number
   *   of key/value pairs.
   * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
   *   The lock object used for this data.
   * @param \Drupal\acm\User\AccountProxyInterface $current_user
   *   The current commerce user account.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param int $expire
   *   The time to live for items, in seconds.
   */
  public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
    $this->storage = $storage;
    $this->lockBackend = $lock_backend;
    $this->currentUser = $current_user;
    $this->requestStack = $request_stack;
    $this->expire = $expire;
  }

  /**
   * {@inheritdoc}
   */
  public function remove($key) {
    $this->delete($key);
  }

  /**
   * {@inheritdoc}
   *
   * Overrides \Drupal\Core\TempStore\PrivateTempStore::get().
   */
  public function get($key, $default = NULL) {
    $value = parent::get($key);

    if (isset($value)) {
      return $value;
    }

    return $default;
  }

  /**
   * {@inheritdoc}
   *
   * Overrides \Drupal\Core\TempStore\PrivateTempStore::set().
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   *   Thrown when a lock for the backend storage could not be acquired.
   */
  public function set($key, $value, $expire = NULL) {
    $key = $this->createkey($key);
    if (!$this->lockBackend->acquire($key)) {
      $this->lockBackend->wait($key);
      if (!$this->lockBackend->acquire($key)) {
        throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
      }
    }

    $value = (object) [
      'owner' => $this->getOwner(),
      'data' => $value,
      'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
    ];

    // Fallback to the default expire.
    if (empty($expire)) {
      $expire = $this->expire;
    }

    $this->storage->setWithExpire($key, $value, $expire);
    $this->lockBackend->release($key);
  }

  /**
   * Stores a reference to the current store owner for a particular user.
   *
   * @param string $uid
   *   The user id to relate to the current store.
   * @param string $owner_id
   *   The store owner to associate this user to.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   *   Thrown when a lock for the backend storage could not be acquired.
   */
  protected function setOwnerReference($uid, $owner_id) {
    $key = $uid . ':' . self::OWNER_REFERENCE_NAMESPACE;
    if (!$this->lockBackend->acquire($key)) {
      $this->lockBackend->wait($key);
      if (!$this->lockBackend->acquire($key)) {
        throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
      }
    }

    $value = (object) [
      'owner' => $uid,
      'data' => $owner_id,
      'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
    ];
    $this->storage->setWithExpire($key, $value, $this->expire);
    $this->lockBackend->release($key);
  }

  /**
   * Gets the reference to the current store owner for a particular user.
   *
   * @param string $uid
   *   The user id to relate to the current store.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   *   Thrown when a lock for the backend storage could not be acquired.
   */
  protected function getOwnerReference($uid) {
    $key = $uid . ':' . self::OWNER_REFERENCE_NAMESPACE;
    if (($object = $this->storage->get($key)) && ($object->owner == $uid)) {
      return $object->data;
    }
  }

  /**
   * {@inheritdoc}
   *
   * Overrides \Drupal\Core\TempStore\PrivateTempStore::getOwner().
   */
  protected function getOwner() {
    $uid = NULL;

    if ($account = $this->currentUser->getAccount()) {
      $uid = $account->id();

      // Check if the user had stored "session" data before loggin in, and use
      // that "session" id as the owner instead of user id.
      if ($owner = $this->getOwnerReference($uid)) {
        return $owner;
      }
    }

    $cookies = $this->getCookies();
    if (!empty($cookies['Drupal_visitor_' . self::SESSION_ID_COOKIE])) {
      $sid = $cookies['Drupal_visitor_' . self::SESSION_ID_COOKIE];
      // If there's a logged in user and a stored "session" id cookie we want
      // to create a reference to it so if they log in on a different computer
      // they can retrieve their "session" data.
      if ($uid) {
        $this->setOwnerReference($uid, $sid);
      }

      return $sid;
    }

    // If user is logged in use their id as the owner.
    if ($uid) {
      return $uid;
    }

    // If we got this far it's an anonymous user (drupal and commerce), so
    // generate a "session" id and save it for later use.
    $sid = $this->generateSessionId();
    $this->setCookie(self::SESSION_ID_COOKIE, $sid);

    return $sid;
  }

  /**
   * Generates a uuid to use as a session id.
   *
   * @return string
   *   The custom session ID.
   */
  protected function generateSessionId() {
    $uuid = \Drupal::service('uuid')->generate();
    return $uuid;
  }

  /**
   * Gets cookies.
   *
   * @return array
   *   The cookies.
   */
  protected function getCookies() {
    $current_request = $this->requestStack->getCurrentRequest();
    if (isset($current_request->cookies)) {
      return $current_request->cookies->all();
    }
    return $_COOKIE;
  }

  /**
   * Sets a cookie.
   *
   * @param string $name
   *   The cookie name.
   * @param string $value
   *   The cookie value.
   */
  protected function setCookie($name, $value = '') {
    if (PHP_SAPI === 'cli') {
      return;
    }

    $current_request = $this->requestStack->getCurrentRequest();
    if (isset($current_request->cookies)) {
      $current_request->cookies->set("Drupal_visitor_{$name}", $value);
    }
    user_cookie_save([
      $name => $value,
    ]);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc