1<?php 2/** 3 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) 4 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) 5 * 6 * Licensed under The MIT License 7 * For full copyright and license information, please see the LICENSE.txt 8 * Redistributions of files must retain the above copyright notice. 9 * 10 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) 11 * @link https://cakephp.org CakePHP(tm) Project 12 * @since 3.0.0 13 * @license https://opensource.org/licenses/mit-license.php MIT License 14 */ 15namespace Cake\Database\Schema; 16 17use Cake\Cache\Cache; 18use Cake\Datasource\ConnectionInterface; 19 20/** 21 * Extends the schema collection class to provide caching 22 */ 23class CachedCollection extends Collection 24{ 25 /** 26 * The name of the cache config key to use for caching table metadata, 27 * of false if disabled. 28 * 29 * @var string|bool 30 */ 31 protected $_cache = false; 32 33 /** 34 * Constructor. 35 * 36 * @param \Cake\Datasource\ConnectionInterface $connection The connection instance. 37 * @param string|bool $cacheKey The cache key or boolean false to disable caching. 38 */ 39 public function __construct(ConnectionInterface $connection, $cacheKey = true) 40 { 41 parent::__construct($connection); 42 $this->setCacheMetadata($cacheKey); 43 } 44 45 /** 46 * {@inheritDoc} 47 */ 48 public function describe($name, array $options = []) 49 { 50 $options += ['forceRefresh' => false]; 51 $cacheConfig = $this->getCacheMetadata(); 52 $cacheKey = $this->cacheKey($name); 53 54 if (!empty($cacheConfig) && !$options['forceRefresh']) { 55 $cached = Cache::read($cacheKey, $cacheConfig); 56 if ($cached !== false) { 57 return $cached; 58 } 59 } 60 61 $table = parent::describe($name, $options); 62 63 if (!empty($cacheConfig)) { 64 Cache::write($cacheKey, $table, $cacheConfig); 65 } 66 67 return $table; 68 } 69 70 /** 71 * Get the cache key for a given name. 72 * 73 * @param string $name The name to get a cache key for. 74 * @return string The cache key. 75 */ 76 public function cacheKey($name) 77 { 78 $cachePrefix = $this->_connection->configName(); 79 $config = $this->_connection->config(); 80 if (isset($config['cacheKeyPrefix'])) { 81 $cachePrefix = $config['cacheKeyPrefix']; 82 } 83 84 return $cachePrefix . '_' . $name; 85 } 86 87 /** 88 * Sets the cache config name to use for caching table metadata, or 89 * disables it if false is passed. 90 * 91 * @param bool $enable Whether or not to enable caching 92 * @return $this 93 */ 94 public function setCacheMetadata($enable) 95 { 96 if ($enable === true) { 97 $enable = '_cake_model_'; 98 } 99 100 $this->_cache = $enable; 101 102 return $this; 103 } 104 105 /** 106 * Gets the cache config name to use for caching table metadata, false means disabled. 107 * 108 * @return string|bool 109 */ 110 public function getCacheMetadata() 111 { 112 return $this->_cache; 113 } 114 115 /** 116 * Sets the cache config name to use for caching table metadata, or 117 * disables it if false is passed. 118 * If called with no arguments it returns the current configuration name. 119 * 120 * @deprecated 3.4.0 Use setCacheMetadata()/getCacheMetadata() 121 * @param bool|null $enable Whether or not to enable caching 122 * @return string|bool 123 */ 124 public function cacheMetadata($enable = null) 125 { 126 deprecationWarning( 127 'CachedCollection::cacheMetadata() is deprecated. ' . 128 'Use CachedCollection::setCacheMetadata()/getCacheMetadata() instead.' 129 ); 130 if ($enable !== null) { 131 $this->setCacheMetadata($enable); 132 } 133 134 return $this->getCacheMetadata(); 135 } 136} 137