1: <?php
2: /**
3: * LICENSE (BSD)
4: *
5: * Copyright (c) 2012, Gerd Christian Kunze
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions are
10: * met:
11: *
12: * * Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: *
15: * * Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * * Neither the name of Gerd Christian Kunze nor the names of the
20: * contributors may be used to endorse or promote products derived from
21: * this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24: * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34: *
35: * Cache
36: * 11.09.2012 12:32
37: */
38: namespace MOC\Core;
39: use MOC\Api;
40: use MOC\Generic\Device\Core;
41:
42: /**
43: *
44: */
45: class Cache implements Core {
46: /**
47: * Get Singleton/Instance
48: *
49: * @static
50: * @return Cache
51: */
52: public static function InterfaceInstance() {
53: $Instance = new Cache();
54: $Instance->CacheDirectory = Drive::InterfaceInstance()->Directory()->Handle( __DIR__.'/../Data/Cache' );
55: $Instance->Identifier( uniqid( __METHOD__, true ) );
56: $Instance->Timeout( 60 );
57: return $Instance;
58: }
59:
60: /**
61: * Get Changelog
62: *
63: * @static
64: * @return Changelog
65: */
66: public static function InterfaceChangelog() {
67: return Api::Core()->Changelog()->Create( __CLASS__ )
68: ->Build()->Clearance( '03.06.2013 14:43', 'Development' )
69: ;
70: }
71:
72: /**
73: * Get Dependencies
74: *
75: * @static
76: * @return Depending
77: */
78: public static function InterfaceDepending() {
79: return Api::Core()->Depending();
80: }
81:
82: /** @var Drive\Directory $CacheDirectory */
83: private $CacheDirectory = null;
84:
85: /** @var int $CacheTimeout */
86: private $CacheTimeout = 60;
87: /** @var string $CacheIdentifier */
88: private $CacheIdentifier = '';
89: /** @var string $CacheGroup */
90: private $CacheGroup = '';
91: /** @var string $CacheExtension */
92: private $CacheExtension = 'cache';
93:
94: /**
95: * @return Drive\Directory
96: */
97: public function Directory() {
98: return $this->CacheDirectory;
99: }
100:
101: /**
102: * @param int $Seconds
103: *
104: * @return int|Cache
105: */
106: public function Timeout( $Seconds = null ) {
107: if( null !== $Seconds ) {
108: $this->CacheTimeout = time() + $Seconds;
109: return $this;
110: } return $this->CacheTimeout;
111: }
112: /**
113: * @param mixed $Name
114: *
115: * @return string|Cache
116: */
117: public function Group( $Name = null ) {
118: if( null !== $Name ) {
119: $this->CacheGroup = sha1( serialize( $Name ) );
120: return $this;
121: } return $this->CacheGroup;
122: }
123: /**
124: * @param string $Extension
125: *
126: * @return string|Cache
127: */
128: public function Extension( $Extension = null ) {
129: if( null !== $Extension ) {
130: $this->CacheExtension = $Extension;
131: return $this;
132: } return $this->CacheExtension;
133: }
134: /**
135: * @param mixed $Data
136: *
137: * @return string|Cache
138: */
139: public function Identifier( $Data = null ) {
140: if( null !== $Data ) {
141: $this->CacheIdentifier = sha1( serialize( $Data ) );
142: return $this;
143: } return $this->CacheIdentifier;
144: }
145:
146: /**
147: * @return bool|Drive\File
148: */
149: public function Get() {
150: $CacheList = $this->CacheLocation()->FileList();
151: /** @var Drive\File $Cache */
152: foreach( (array)$CacheList as $Cache ) {
153: if( $this->CacheIdentifier( $Cache ) == $this->Identifier() ) {
154: if( $this->CacheTimestamp( $Cache ) > time() ) {
155: if( $this->CacheExtension( $Cache ) == $this->Extension() ) {
156: return $Cache;
157: }
158: } else {
159: $this->Purge();
160: }
161: }
162: }
163: return false;
164: }
165:
166: /**
167: * @param mixed $Data
168: *
169: * @return Drive\File
170: */
171: public function Set( $Data ) {
172: $Cache = Drive::InterfaceInstance()
173: ->File()
174: ->Handle( $this->CacheLocation()->Location().'/'.$this->Identifier().'.'.$this->Timeout().'.'.$this->Extension() )
175: ->Content( $Data );
176: $Cache->Save();
177: return $Cache;
178: }
179:
180: public function Purge() {
181: $CacheList = $this->Directory()->FileListRecursive();
182: $Directory = null;
183: /** @var Drive\File $Cache */
184: foreach( (array)$CacheList as $Cache ) {
185: // Get Cache Location
186: if( $Directory === null ) {
187: $Directory = Drive::InterfaceInstance()->Directory()->Handle( $Cache->Path() );
188: }
189: if( $Directory->Location() != $Cache->Path() ) {
190: if( $Directory->IsEmpty() ) {
191: $Directory->Remove();
192: }
193: $Directory = Drive::InterfaceInstance()->Directory()->Handle( $Cache->Path() );
194: }
195: // Remove Cache
196: if( time() > $this->CacheTimestamp( $Cache ) ) {
197: $Cache->Remove();
198: }
199: }
200: }
201:
202: /**
203: * Cache-File Name-Convention
204: * [Identifier].[Timestamp].[Extension]
205: */
206:
207: /**
208: * @param Drive\File $File
209: *
210: * @return int
211: */
212: private function CacheExtension( Drive\File $File ) {
213: return $File->Extension();
214: }
215: /**
216: * @param Drive\File $File
217: *
218: * @return int
219: */
220: private function CacheTimestamp( Drive\File $File ) {
221: $Name = explode( '.', $File->Name() );
222: if( isset( $Name[1] ) ) {
223: return $Name[1];
224: }
225: return $File->Time();
226: }
227: /**
228: * @param Drive\File $File
229: *
230: * @return int
231: */
232: private function CacheIdentifier( Drive\File $File ) {
233: $Name = explode( '.', $File->Name() );
234: return $Name[0];
235: }
236: /**
237: * @return Drive\Directory
238: */
239: private function CacheLocation() {
240: return Drive::InterfaceInstance()->Directory()->Handle(
241: $this->Directory()->Location().'/'.$this->CacheGroup
242: );
243: }
244:
245: /**
246: * @return string
247: */
248: function __toString() {
249: return '';
250: }
251: }
252: