Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / memcache / src / Driver / MemcacheDriverFactory.php
1 <?php
2
3 namespace Drupal\memcache\Driver;
4
5 use Drupal\memcache\Connection\MemcacheConnection;
6 use Drupal\memcache\Connection\MemcachedConnection;
7 use Drupal\memcache\MemcacheSettings;
8 use Drupal\memcache\MemcacheException;
9
10 /**
11  * Factory class for creation of Memcache objects.
12  */
13 class MemcacheDriverFactory {
14
15   /**
16    * The settings object.
17    *
18    * @var \Drupal\memcache\MemcacheSettings
19    */
20   protected $settings;
21
22   /**
23    * The connection class reference.
24    *
25    * @var string
26    */
27   protected $connectionClass;
28
29   /**
30    * The driver class reference.
31    *
32    * @var string
33    */
34   protected $driverClass;
35
36   /**
37    * Whether to connect to memcache using a persistent connection.
38    *
39    * @var bool
40    */
41   protected $persistent;
42
43   /**
44    * An array of Memcache connections keyed by bin.
45    *
46    * @var \Drupal\memcache\Connection\MemcacheConnectionInterface[]
47    */
48   protected $connections = [];
49
50   /**
51    * An array of configured servers.
52    *
53    * @var array
54    */
55   protected $servers = [];
56
57   /**
58    * An array of configured bins.
59    *
60    * @var string[]
61    */
62   protected $bins = [];
63
64   /**
65    * An array of failed connections to configured servers keyed by server name.
66    *
67    * @var bool[]
68    */
69   protected $failedConnectionCache = [];
70
71   /**
72    * Constructs a MemcacheDriverFactory object.
73    *
74    * @param \Drupal\memcache\MemcacheSettings $settings
75    *   The settings object.
76    */
77   public function __construct(MemcacheSettings $settings) {
78     $this->settings = $settings;
79
80     $this->initialize();
81   }
82
83   /**
84    * Returns a Memcache object based on settings and the bin requested.
85    *
86    * @param string $bin
87    *   The bin which is to be used.
88    * @param bool $flush
89    *   Rebuild the bin/server/cache mapping.
90    *
91    * @return \Drupal\memcache\DrupalMemcacheInterface|bool
92    *   A Memcache object.
93    */
94   public function get($bin = NULL, $flush = FALSE) {
95     if ($flush) {
96       $this->flush();
97     }
98
99     if (empty($this->connections) || empty($this->connections[$bin])) {
100       // If there is no cluster for this bin in $bins, cluster is
101       // 'default'.
102       $cluster = empty($this->bins[$bin]) ? 'default' : $this->bins[$bin];
103
104       // If this bin isn't in our $bins configuration array, and the
105       // 'default' cluster is already initialized, map the bin to 'default'
106       // because we always map the 'default' bin to the 'default' cluster.
107       if (empty($this->bins[$bin]) && !empty($this->connections['default'])) {
108         $this->connections[$bin] = &$this->connections['default'];
109       }
110       else {
111         // Create a new Memcache object. Each cluster gets its own Memcache
112         // object.
113         /** @var \Drupal\memcache\Connection\MemcacheConnectionInterface $memcache */
114         $memcache = new $this->connectionClass($this->settings);
115
116         // A variable to track whether we've connected to the first server.
117         $init = FALSE;
118
119         // Link all the servers to this cluster.
120         foreach ($this->servers as $s => $c) {
121           if ($c == $cluster && !isset($this->failedConnectionCache[$s])) {
122             if ($memcache->addServer($s, $this->persistent) && !$init) {
123               $init = TRUE;
124             }
125
126             if (!$init) {
127               $this->failedConnectionCache[$s] = FALSE;
128             }
129           }
130         }
131
132         if ($init) {
133           // Map the current bin with the new Memcache object.
134           $this->connections[$bin] = $memcache;
135
136           // Now that all the servers have been mapped to this cluster, look for
137           // other bins that belong to the cluster and map them too.
138           foreach ($this->bins as $b => $c) {
139             if (($c == $cluster) && ($b != $bin)) {
140               // Map this bin and cluster by reference.
141               $this->connections[$b] = &$this->connections[$bin];
142             }
143           }
144         }
145         else {
146           throw new MemcacheException('Memcache instance could not be initialized. Check memcache is running and reachable');
147         }
148       }
149     }
150
151     return empty($this->connections[$bin]) ? FALSE : new $this->driverClass($this->settings, $this->connections[$bin]->getMemcache(), $bin);
152   }
153
154   /**
155    * Initializes memcache settings.
156    */
157   protected function initialize() {
158     // If an extension is specified in settings.php, use that when available.
159     $preferred = $this->settings->get('extension', NULL);
160
161     if (isset($preferred) && class_exists($preferred)) {
162       $extension = $preferred;
163     }
164     // If no extension is set, default to Memcached.
165     elseif (class_exists('Memcached')) {
166       $extension = \Memcached::class;
167     }
168     elseif (class_exists('Memcache')) {
169       $extension = \Memcache::class;
170     }
171     else {
172       throw new MemcacheException('No Memcache extension found');
173     }
174
175     // @todo Make driver class configurable?
176     $this->connectionClass = MemcachedConnection::class;
177     $this->driverClass = MemcachedDriver::class;
178
179     if ($extension === \Memcache::class) {
180       $this->connectionClass = MemcacheConnection::class;
181       $this->driverClass = MemcacheDriver::class;
182     }
183
184     // Values from settings.php.
185     $this->servers = $this->settings->get('servers', ['127.0.0.1:11211' => 'default']);
186     $this->bins = $this->settings->get('bins', ['default' => 'default']);
187
188     // Indicate whether to connect to memcache using a persistent connection.
189     // Note: this only affects the Memcache PECL extension, and does not affect
190     // the Memcached PECL extension.  For a detailed explanation see:
191     // http://drupal.org/node/822316#comment-4427676
192     $this->persistent = $this->settings->get('persistent', FALSE);
193   }
194
195   /**
196    * Flushes the memcache bin/server/cache mappings and closes connections.
197    */
198   protected function flush() {
199     foreach ($this->connections as $cluster) {
200       $cluster->close();
201     }
202
203     $this->connections = [];
204   }
205
206 }