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