Bitrix-D7  20.5.0
taggedcache.php
См. документацию.
1 <?php
2 /**
3  * Bitrix Framework
4  * @package bitrix
5  * @subpackage main
6  * @copyright 2001-2014 Bitrix
7  */
8 
9 namespace Bitrix\Main\Data;
10 
11 use Bitrix\Main;
12 
14 {
15  protected $compCacheStack = [];
16  protected $salt = false;
17  protected $cacheTag = [];
18  protected $wasTagged = false;
19  protected $isMySql = false;
20  protected $pool = false;
21 
22  public function __construct()
23  {
24  $this->isMySql = (static::getDbType() === "MYSQL");
25  $this->pool = Main\Application::getInstance()->getConnectionPool();
26  }
27 
28  protected static function getDbType()
29  {
30  static $type = null;
31  if ($type === null)
32  {
33  $cm = Main\Application::getInstance()->getConnectionPool();
34  $type = $cm->getDefaultConnectionType();
35  }
36  return $type;
37  }
38 
39  protected function initDbCache($path)
40  {
41  if (!isset($this->cacheTag[$path]))
42  {
43  $this->cacheTag[$path] = [];
44 
46  $sqlHelper = $con->getSqlHelper();
47 
48  $this->pool->useMasterOnly(true);
49 
50  $rs = $con->query("
51  SELECT TAG
52  FROM b_cache_tag
53  WHERE SITE_ID = '".$sqlHelper->forSql(SITE_ID, 2)."'
54  AND CACHE_SALT = '".$sqlHelper->forSql($this->salt, 4)."'
55  AND RELATIVE_PATH = '".$sqlHelper->forSql($path)."'
56  ");
57 
58  while ($ar = $rs->fetch())
59  {
60  $this->cacheTag[$path][$ar["TAG"]] = true;
61  }
62 
63  $this->pool->useMasterOnly(false);
64  }
65  }
66 
67  protected function initCompSalt()
68  {
69  if ($this->salt === false)
70  {
71  $this->salt = Cache::getSalt();
72  }
73  }
74 
75  public function startTagCache($relativePath)
76  {
77  array_unshift($this->compCacheStack, [$relativePath, []]);
78  }
79 
80  public function endTagCache()
81  {
82  $this->initCompSalt();
83 
84  if ($this->wasTagged)
85  {
86  $this->pool->useMasterOnly(true);
87 
89  $sqlHelper = $con->getSqlHelper();
90 
91  // TODO: SITE_ID
92  $siteIdForSql = $sqlHelper->forSql(SITE_ID, 2);
93  $cacheSaltForSql = $this->salt;
94 
95  $strSqlPrefix = "
96  INSERT ".($this->isMySql ? "IGNORE": "")." INTO b_cache_tag (SITE_ID, CACHE_SALT, RELATIVE_PATH, TAG)
97  VALUES
98  ";
99  $maxValuesLen = $this->isMySql ? 2048: 0;
100  $strSqlValues = "";
101 
102  foreach ($this->compCacheStack as $arCompCache)
103  {
104  $path = $arCompCache[0];
105  if ($path <> '')
106  {
107  $this->initDbCache($path);
108  $sqlRELATIVE_PATH = $sqlHelper->forSql($path, 255);
109 
110  $sql = ",\n('".$siteIdForSql."', '".$cacheSaltForSql."', '".$sqlRELATIVE_PATH."',";
111 
112  foreach ($arCompCache[1] as $tag => $t)
113  {
114  if (!isset($this->cacheTag[$path][$tag]))
115  {
116  $strSqlValues .= $sql." '".$sqlHelper->forSql($tag, 100)."')";
117  if (mb_strlen($strSqlValues) > $maxValuesLen)
118  {
119  $con->queryExecute($strSqlPrefix.mb_substr($strSqlValues, 2));
120  $strSqlValues = "";
121  }
122  $this->cacheTag[$path][$tag] = true;
123  }
124  }
125  }
126  }
127  if ($strSqlValues <> '')
128  {
129  $con->queryExecute($strSqlPrefix.mb_substr($strSqlValues, 2));
130  }
131 
132  $this->pool->useMasterOnly(false);
133  }
134 
135  array_shift($this->compCacheStack);
136  }
137 
138  public function abortTagCache()
139  {
140  array_shift($this->compCacheStack);
141  }
142 
143  public function registerTag($tag)
144  {
145  if (!empty($this->compCacheStack))
146  {
147  $this->compCacheStack[0][1][$tag] = true;
148  $this->wasTagged = true;
149  }
150  }
151 
152  public function clearByTag($tag)
153  {
154  $this->pool->useMasterOnly(true);
155 
157  $sqlHelper = $con->getSqlHelper();
158 
159  if ($tag === true)
160  {
161  $sqlWhere = " WHERE TAG <> '*'";
162  }
163  else
164  {
165  $sqlWhere = " WHERE TAG = '".$sqlHelper->forSql($tag)."'";
166  }
167 
168  $dirs = [];
169  $rs = $con->query("SELECT * FROM b_cache_tag".$sqlWhere);
170  while ($ar = $rs->fetch())
171  {
172  $dirs[$ar["RELATIVE_PATH"]] = $ar;
173  }
174 
175  $con->queryExecute("DELETE FROM b_cache_tag".$sqlWhere);
176 
177  $cache = Cache::createInstance();
178  foreach ($dirs as $path => $ar)
179  {
180  $con->queryExecute("
181  DELETE FROM b_cache_tag
182  WHERE SITE_ID = '".$sqlHelper->forSql($ar["SITE_ID"])."'
183  AND CACHE_SALT = '".$sqlHelper->forSql($ar["CACHE_SALT"])."'
184  AND RELATIVE_PATH = '".$sqlHelper->forSql($ar["RELATIVE_PATH"])."'
185  ");
186 
187  $cache->cleanDir($path);
188  unset($this->cacheTag[$path]);
189  }
190 
191  $this->pool->useMasterOnly(false);
192  }
193 }
static getInstance()
Returns current instance of the Application.
static getConnection($name="")
Static method returns database connection for the specified name.
static createInstance($params=[])
startTagCache($relativePath)
Definition: taggedcache.php:75