PluginProbe
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) / 1.0.1
Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) v1.0.1
9.1.2 9.1.1 9.1.0 9.0.2 9.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 All 153 releases
wp-analytify / lib / Google / Cache / File.php

File.php in Analytify – Google Analytics Dashboard For WordPress (GA4 analytics tracking) 1.0.1, at lib/Google/Cache/File.php

146 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Copyright 2008 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 require_once ANALYTIFY_LIB_PATH . "Google/Cache/Abstract.php";
19 require_once ANALYTIFY_LIB_PATH . "Google/Cache/Exception.php";
20
21 /*
22 * This class implements a basic on disk storage. While that does
23 * work quite well it's not the most elegant and scalable solution.
24 * It will also get you into a heap of trouble when you try to run
25 * this in a clustered environment.
26 *
27 * @author Chris Chabot <chabotc@google.com>
28 */
29 class Analytify_Google_Cache_File extends Analytify_Google_Cache_Abstract
30 {
31 const MAX_LOCK_RETRIES = 10;
32 private $path;
33 private $fh;
34
35 public function __construct(Analytify_Google_Client $client)
36 {
37 $this->path = $client->getClassConfig($this, 'directory');
38 }
39
40 public function get($key, $expiration = false)
41 {
42 $storageFile = $this->getCacheFile($key);
43 $data = false;
44
45 if (!file_exists($storageFile)) {
46 return false;
47 }
48
49 if ($expiration) {
50 $mtime = filemtime($storageFile);
51 if ((time() - $mtime) >= $expiration) {
52 $this->delete($key);
53 return false;
54 }
55 }
56
57 if ($this->acquireReadLock($storageFile)) {
58 $data = fread($this->fh, filesize($storageFile));
59 $data = unserialize($data);
60 $this->unlock($storageFile);
61 }
62
63 return $data;
64 }
65
66 public function set($key, $value)
67 {
68 $storageFile = $this->getWriteableCacheFile($key);
69 if ($this->acquireWriteLock($storageFile)) {
70 // We serialize the whole request object, since we don't only want the
71 // responseContent but also the postBody used, headers, size, etc.
72 $data = serialize($value);
73 $result = fwrite($this->fh, $data);
74 $this->unlock($storageFile);
75 }
76 }
77
78 public function delete($key)
79 {
80 $file = $this->getCacheFile($key);
81 if (file_exists($file) && !unlink($file)) {
82 throw new Analytify_Google_Cache_Exception("Cache file could not be deleted");
83 }
84 }
85
86 private function getWriteableCacheFile($file)
87 {
88 return $this->getCacheFile($file, true);
89 }
90
91 private function getCacheFile($file, $forWrite = false)
92 {
93 return $this->getCacheDir($file, $forWrite) . '/' . md5($file);
94 }
95
96 private function getCacheDir($file, $forWrite)
97 {
98 // use the first 2 characters of the hash as a directory prefix
99 // this should prevent slowdowns due to huge directory listings
100 // and thus give some basic amount of scalability
101 $storageDir = $this->path . '/' . substr(md5($file), 0, 2);
102 if ($forWrite && ! is_dir($storageDir)) {
103 if (! mkdir($storageDir, 0755, true)) {
104 throw new Analytify_Google_Cache_Exception("Could not create storage directory: $storageDir");
105 }
106 }
107 return $storageDir;
108 }
109
110 private function acquireReadLock($storageFile)
111 {
112 return $this->acquireLock(LOCK_SH, $storageFile);
113 }
114
115 private function acquireWriteLock($storageFile)
116 {
117 $rc = $this->acquireLock(LOCK_EX, $storageFile);
118 if (!$rc) {
119 $this->delete($storageFile);
120 }
121 return $rc;
122 }
123
124 private function acquireLock($type, $storageFile)
125 {
126 $mode = $type == LOCK_EX ? "w" : "r";
127 $this->fh = fopen($storageFile, $mode);
128 $count = 0;
129 while (!flock($this->fh, $type | LOCK_NB)) {
130 // Sleep for 10ms.
131 usleep(10000);
132 if (++$count < self::MAX_LOCK_RETRIES) {
133 return false;
134 }
135 }
136 return true;
137 }
138
139 public function unlock($storageFile)
140 {
141 if ($this->fh) {
142 flock($this->fh, LOCK_UN);
143 }
144 }
145 }
146