/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php

https://gitlab.com/jjpa2018/dashboard · PHP · 420 lines · 194 code · 52 blank · 174 comment · 11 complexity · a6172f523a17c4ee2cb8176976874507 MD5 · raw file

  1. <?php
  2. namespace Illuminate\Cache;
  3. use Aws\DynamoDb\DynamoDbClient;
  4. use Closure;
  5. use Illuminate\Contracts\Cache\Factory as FactoryContract;
  6. use Illuminate\Contracts\Cache\Store;
  7. use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
  8. use Illuminate\Support\Arr;
  9. use InvalidArgumentException;
  10. /**
  11. * @mixin \Illuminate\Contracts\Cache\Repository
  12. */
  13. class CacheManager implements FactoryContract
  14. {
  15. /**
  16. * The application instance.
  17. *
  18. * @var \Illuminate\Contracts\Foundation\Application
  19. */
  20. protected $app;
  21. /**
  22. * The array of resolved cache stores.
  23. *
  24. * @var array
  25. */
  26. protected $stores = [];
  27. /**
  28. * The registered custom driver creators.
  29. *
  30. * @var array
  31. */
  32. protected $customCreators = [];
  33. /**
  34. * Create a new Cache manager instance.
  35. *
  36. * @param \Illuminate\Contracts\Foundation\Application $app
  37. * @return void
  38. */
  39. public function __construct($app)
  40. {
  41. $this->app = $app;
  42. }
  43. /**
  44. * Get a cache store instance by name, wrapped in a repository.
  45. *
  46. * @param string|null $name
  47. * @return \Illuminate\Contracts\Cache\Repository
  48. */
  49. public function store($name = null)
  50. {
  51. $name = $name ?: $this->getDefaultDriver();
  52. return $this->stores[$name] = $this->get($name);
  53. }
  54. /**
  55. * Get a cache driver instance.
  56. *
  57. * @param string|null $driver
  58. * @return \Illuminate\Contracts\Cache\Repository
  59. */
  60. public function driver($driver = null)
  61. {
  62. return $this->store($driver);
  63. }
  64. /**
  65. * Attempt to get the store from the local cache.
  66. *
  67. * @param string $name
  68. * @return \Illuminate\Contracts\Cache\Repository
  69. */
  70. protected function get($name)
  71. {
  72. return $this->stores[$name] ?? $this->resolve($name);
  73. }
  74. /**
  75. * Resolve the given store.
  76. *
  77. * @param string $name
  78. * @return \Illuminate\Contracts\Cache\Repository
  79. *
  80. * @throws \InvalidArgumentException
  81. */
  82. protected function resolve($name)
  83. {
  84. $config = $this->getConfig($name);
  85. if (is_null($config)) {
  86. throw new InvalidArgumentException("Cache store [{$name}] is not defined.");
  87. }
  88. if (isset($this->customCreators[$config['driver']])) {
  89. return $this->callCustomCreator($config);
  90. } else {
  91. $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
  92. if (method_exists($this, $driverMethod)) {
  93. return $this->{$driverMethod}($config);
  94. } else {
  95. throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
  96. }
  97. }
  98. }
  99. /**
  100. * Call a custom driver creator.
  101. *
  102. * @param array $config
  103. * @return mixed
  104. */
  105. protected function callCustomCreator(array $config)
  106. {
  107. return $this->customCreators[$config['driver']]($this->app, $config);
  108. }
  109. /**
  110. * Create an instance of the APC cache driver.
  111. *
  112. * @param array $config
  113. * @return \Illuminate\Cache\Repository
  114. */
  115. protected function createApcDriver(array $config)
  116. {
  117. $prefix = $this->getPrefix($config);
  118. return $this->repository(new ApcStore(new ApcWrapper, $prefix));
  119. }
  120. /**
  121. * Create an instance of the array cache driver.
  122. *
  123. * @param array $config
  124. * @return \Illuminate\Cache\Repository
  125. */
  126. protected function createArrayDriver(array $config)
  127. {
  128. return $this->repository(new ArrayStore($config['serialize'] ?? false));
  129. }
  130. /**
  131. * Create an instance of the file cache driver.
  132. *
  133. * @param array $config
  134. * @return \Illuminate\Cache\Repository
  135. */
  136. protected function createFileDriver(array $config)
  137. {
  138. return $this->repository(new FileStore($this->app['files'], $config['path'], $config['permission'] ?? null));
  139. }
  140. /**
  141. * Create an instance of the Memcached cache driver.
  142. *
  143. * @param array $config
  144. * @return \Illuminate\Cache\Repository
  145. */
  146. protected function createMemcachedDriver(array $config)
  147. {
  148. $prefix = $this->getPrefix($config);
  149. $memcached = $this->app['memcached.connector']->connect(
  150. $config['servers'],
  151. $config['persistent_id'] ?? null,
  152. $config['options'] ?? [],
  153. array_filter($config['sasl'] ?? [])
  154. );
  155. return $this->repository(new MemcachedStore($memcached, $prefix));
  156. }
  157. /**
  158. * Create an instance of the Null cache driver.
  159. *
  160. * @return \Illuminate\Cache\Repository
  161. */
  162. protected function createNullDriver()
  163. {
  164. return $this->repository(new NullStore);
  165. }
  166. /**
  167. * Create an instance of the Redis cache driver.
  168. *
  169. * @param array $config
  170. * @return \Illuminate\Cache\Repository
  171. */
  172. protected function createRedisDriver(array $config)
  173. {
  174. $redis = $this->app['redis'];
  175. $connection = $config['connection'] ?? 'default';
  176. $store = new RedisStore($redis, $this->getPrefix($config), $connection);
  177. return $this->repository(
  178. $store->setLockConnection($config['lock_connection'] ?? $connection)
  179. );
  180. }
  181. /**
  182. * Create an instance of the database cache driver.
  183. *
  184. * @param array $config
  185. * @return \Illuminate\Cache\Repository
  186. */
  187. protected function createDatabaseDriver(array $config)
  188. {
  189. $connection = $this->app['db']->connection($config['connection'] ?? null);
  190. $store = new DatabaseStore(
  191. $connection,
  192. $config['table'],
  193. $this->getPrefix($config),
  194. $config['lock_table'] ?? 'cache_locks',
  195. $config['lock_lottery'] ?? [2, 100]
  196. );
  197. return $this->repository($store->setLockConnection(
  198. $this->app['db']->connection($config['lock_connection'] ?? $config['connection'] ?? null)
  199. ));
  200. }
  201. /**
  202. * Create an instance of the DynamoDB cache driver.
  203. *
  204. * @param array $config
  205. * @return \Illuminate\Cache\Repository
  206. */
  207. protected function createDynamodbDriver(array $config)
  208. {
  209. $client = $this->newDynamodbClient($config);
  210. return $this->repository(
  211. new DynamoDbStore(
  212. $client,
  213. $config['table'],
  214. $config['attributes']['key'] ?? 'key',
  215. $config['attributes']['value'] ?? 'value',
  216. $config['attributes']['expiration'] ?? 'expires_at',
  217. $this->getPrefix($config)
  218. )
  219. );
  220. }
  221. /**
  222. * Create new DynamoDb Client instance.
  223. *
  224. * @return DynamoDbClient
  225. */
  226. protected function newDynamodbClient(array $config)
  227. {
  228. $dynamoConfig = [
  229. 'region' => $config['region'],
  230. 'version' => 'latest',
  231. 'endpoint' => $config['endpoint'] ?? null,
  232. ];
  233. if (isset($config['key']) && isset($config['secret'])) {
  234. $dynamoConfig['credentials'] = Arr::only(
  235. $config, ['key', 'secret', 'token']
  236. );
  237. }
  238. return new DynamoDbClient($dynamoConfig);
  239. }
  240. /**
  241. * Create a new cache repository with the given implementation.
  242. *
  243. * @param \Illuminate\Contracts\Cache\Store $store
  244. * @return \Illuminate\Cache\Repository
  245. */
  246. public function repository(Store $store)
  247. {
  248. return tap(new Repository($store), function ($repository) {
  249. $this->setEventDispatcher($repository);
  250. });
  251. }
  252. /**
  253. * Set the event dispatcher on the given repository instance.
  254. *
  255. * @param \Illuminate\Cache\Repository $repository
  256. * @return void
  257. */
  258. protected function setEventDispatcher(Repository $repository)
  259. {
  260. if (! $this->app->bound(DispatcherContract::class)) {
  261. return;
  262. }
  263. $repository->setEventDispatcher(
  264. $this->app[DispatcherContract::class]
  265. );
  266. }
  267. /**
  268. * Re-set the event dispatcher on all resolved cache repositories.
  269. *
  270. * @return void
  271. */
  272. public function refreshEventDispatcher()
  273. {
  274. array_map([$this, 'setEventDispatcher'], $this->stores);
  275. }
  276. /**
  277. * Get the cache prefix.
  278. *
  279. * @param array $config
  280. * @return string
  281. */
  282. protected function getPrefix(array $config)
  283. {
  284. return $config['prefix'] ?? $this->app['config']['cache.prefix'];
  285. }
  286. /**
  287. * Get the cache connection configuration.
  288. *
  289. * @param string $name
  290. * @return array
  291. */
  292. protected function getConfig($name)
  293. {
  294. if (! is_null($name) && $name !== 'null') {
  295. return $this->app['config']["cache.stores.{$name}"];
  296. }
  297. return ['driver' => 'null'];
  298. }
  299. /**
  300. * Get the default cache driver name.
  301. *
  302. * @return string
  303. */
  304. public function getDefaultDriver()
  305. {
  306. return $this->app['config']['cache.default'];
  307. }
  308. /**
  309. * Set the default cache driver name.
  310. *
  311. * @param string $name
  312. * @return void
  313. */
  314. public function setDefaultDriver($name)
  315. {
  316. $this->app['config']['cache.default'] = $name;
  317. }
  318. /**
  319. * Unset the given driver instances.
  320. *
  321. * @param array|string|null $name
  322. * @return $this
  323. */
  324. public function forgetDriver($name = null)
  325. {
  326. $name = $name ?? $this->getDefaultDriver();
  327. foreach ((array) $name as $cacheName) {
  328. if (isset($this->stores[$cacheName])) {
  329. unset($this->stores[$cacheName]);
  330. }
  331. }
  332. return $this;
  333. }
  334. /**
  335. * Disconnect the given driver and remove from local cache.
  336. *
  337. * @param string|null $name
  338. * @return void
  339. */
  340. public function purge($name = null)
  341. {
  342. $name = $name ?? $this->getDefaultDriver();
  343. unset($this->stores[$name]);
  344. }
  345. /**
  346. * Register a custom driver creator Closure.
  347. *
  348. * @param string $driver
  349. * @param \Closure $callback
  350. * @return $this
  351. */
  352. public function extend($driver, Closure $callback)
  353. {
  354. $this->customCreators[$driver] = $callback->bindTo($this, $this);
  355. return $this;
  356. }
  357. /**
  358. * Dynamically call the default driver instance.
  359. *
  360. * @param string $method
  361. * @param array $parameters
  362. * @return mixed
  363. */
  364. public function __call($method, $parameters)
  365. {
  366. return $this->store()->$method(...$parameters);
  367. }
  368. }