1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Cache
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Joomla Cache output type object
14 *
15 * @since 11.1
16 */
17 class JCacheControllerOutput extends JCacheController
18 {
19 /**
20 * Cache data ID
21 *
22 * @var string
23 * @since 11.1
24 */
25 protected $_id;
26
27 /**
28 * Cache data group
29 *
30 * @var string
31 * @since 11.1
32 */
33 protected $_group;
34
35 /**
36 * Object to test locked state
37 *
38 * @var stdClass
39 * @since 11.1
40 * @deprecated 4.0
41 */
42 protected $_locktest = null;
43
44 /**
45 * Start the cache
46 *
47 * @param string $id The cache data ID
48 * @param string $group The cache data group
49 *
50 * @return boolean
51 *
52 * @since 11.1
53 * @deprecated 4.0
54 */
55 public function start($id, $group = null)
56 {
57 JLog::add(
58 __METHOD__ . '() is deprecated.',
59 JLog::WARNING,
60 'deprecated'
61 );
62
63 // If we have data in cache use that.
64 $data = $this->cache->get($id, $group);
65
66 $this->_locktest = new stdClass;
67 $this->_locktest->locked = null;
68 $this->_locktest->locklooped = null;
69
70 if ($data === false)
71 {
72 $this->_locktest = $this->cache->lock($id, $group);
73
74 if ($this->_locktest->locked == true && $this->_locktest->locklooped == true)
75 {
76 $data = $this->cache->get($id, $group);
77 }
78 }
79
80 if ($data !== false)
81 {
82 $data = unserialize(trim($data));
83 echo $data;
84
85 if ($this->_locktest->locked == true)
86 {
87 $this->cache->unlock($id, $group);
88 }
89
90 return true;
91 }
92
93 // Nothing in cache... let's start the output buffer and start collecting data for next time.
94 if ($this->_locktest->locked == false)
95 {
96 $this->_locktest = $this->cache->lock($id, $group);
97 }
98
99 ob_start();
100 ob_implicit_flush(false);
101
102 // Set id and group placeholders
103 $this->_id = $id;
104 $this->_group = $group;
105
106 return false;
107 }
108
109 /**
110 * Stop the cache buffer and store the cached data
111 *
112 * @return boolean True if the cache data was stored
113 *
114 * @since 11.1
115 * @deprecated 4.0
116 */
117 public function end()
118 {
119 JLog::add(
120 __METHOD__ . '() is deprecated.',
121 JLog::WARNING,
122 'deprecated'
123 );
124
125 // Get data from output buffer and echo it
126 $data = ob_get_clean();
127 echo $data;
128
129 // Get the ID and group and reset the placeholders
130 $id = $this->_id;
131 $group = $this->_group;
132 $this->_id = null;
133 $this->_group = null;
134
135 // Get the storage handler and store the cached data
136 $ret = $this->cache->store(serialize($data), $id, $group);
137
138 if ($this->_locktest->locked == true)
139 {
140 $this->cache->unlock($id, $group);
141 }
142
143 return $ret;
144 }
145
146 /**
147 * Get stored cached data by ID and group
148 *
149 * @param string $id The cache data ID
150 * @param string $group The cache data group
151 *
152 * @return mixed Boolean false on no result, cached object otherwise
153 *
154 * @since 11.1
155 */
156 public function get($id, $group = null)
157 {
158 $data = $this->cache->get($id, $group);
159
160 if ($data === false)
161 {
162 $locktest = $this->cache->lock($id, $group);
163
164 // If locklooped is true try to get the cached data again; it could exist now.
165 if ($locktest->locked === true && $locktest->locklooped === true)
166 {
167 $data = $this->cache->get($id, $group);
168 }
169
170 if ($locktest->locked === true)
171 {
172 $this->cache->unlock($id, $group);
173 }
174 }
175
176 // Check again because we might get it from second attempt
177 if ($data !== false)
178 {
179 // Trim to fix unserialize errors
180 $data = unserialize(trim($data));
181 }
182
183 return $data;
184 }
185
186 /**
187 * Store data to cache by ID and group
188 *
189 * @param mixed $data The data to store
190 * @param string $id The cache data ID
191 * @param string $group The cache data group
192 * @param boolean $wrkarounds True to use wrkarounds
193 *
194 * @return boolean True if cache stored
195 *
196 * @since 11.1
197 */
198 public function store($data, $id, $group = null, $wrkarounds = true)
199 {
200 $locktest = $this->cache->lock($id, $group);
201
202 if ($locktest->locked === false && $locktest->locklooped === true)
203 {
204 // We can not store data because another process is in the middle of saving
205 return false;
206 }
207
208 $result = $this->cache->store(serialize($data), $id, $group);
209
210 if ($locktest->locked === true)
211 {
212 $this->cache->unlock($id, $group);
213 }
214
215 return $result;
216 }
217 }
218