Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezstaticcache.php
Go to the documentation of this file.
1 <?php
29 class eZStaticCache implements ezpStaticCache
30 {
31 public $staticStorageDir;
35 const USER_AGENT = 'eZ Publish static cache generator';
36
37 private static $actionList = array();
38
45 private $hostName;
46
52 private $staticStorage;
53
59 private $maxCacheDepth;
60
66 private $cachedURLArray = array();
67
73 private $cachedSiteAccesses = array();
74
80 private $alwaysUpdate;
81
85 public function __construct()
86 {
87 $ini = eZINI::instance( 'staticcache.ini');
88 $this->hostName = $ini->variable( 'CacheSettings', 'HostName' );
89 $this->staticStorageDir = $ini->variable( 'CacheSettings', 'StaticStorageDir' );
90 $this->maxCacheDepth = $ini->variable( 'CacheSettings', 'MaxCacheDepth' );
91 $this->cachedURLArray = $ini->variable( 'CacheSettings', 'CachedURLArray' );
92 $this->cachedSiteAccesses = $ini->variable( 'CacheSettings', 'CachedSiteAccesses' );
93 $this->alwaysUpdate = $ini->variable( 'CacheSettings', 'AlwaysUpdateArray' );
94 }
95
102 public function hostName()
103 {
104 return $this->hostName;
105 }
106
112 public function storageDirectory()
113 {
114 return $this->staticStorageDir;
115 }
116
122 public function maxCacheDepth()
123 {
124 return $this->maxCacheDepth;
125 }
126
132 public function cachedSiteAccesses()
133 {
134 return $this->cachedSiteAccesses;
135 }
136
142 public function cachedURLArray()
143 {
144 return $this->cachedURLArray;
145 }
146
155 function alwaysUpdateURLArray()
156 {
157 return $this->alwaysUpdate;
158 }
159
167 public function generateAlwaysUpdatedCache( $quiet = false, $cli = false, $delay = true )
168 {
169 foreach ( $this->alwaysUpdate as $uri )
170 {
171 if ( !$quiet and $cli )
172 $cli->output( "caching: $uri ", false );
173 $this->storeCache( $uri, $this->staticStorageDir, array(), false, $delay );
174 if ( !$quiet and $cli )
175 $cli->output( "done" );
176 }
177 }
178
188 public function generateNodeListCache( $nodeList )
189 {
190 $db = eZDB::instance();
191
192 foreach ( $nodeList as $uri )
193 {
194 if ( is_array( $uri ) )
195 {
196 if ( !isset( $uri['node_id'] ) )
197 {
198 eZDebug::writeError( "node_id is not set for uri entry " . var_export( $uri ) . ", will need to perform extra query to get node_id" );
199 $node = eZContentObjectTreeNode::fetchByURLPath( $uri['path_identification_string'] );
200 $nodeID = (int)$node->attribute( 'node_id' );
201 }
202 else
203 {
204 $nodeID = (int)$uri['node_id'];
205 }
206 }
207 else
208 {
209 $nodeID = (int)$uri;
210 }
211 $elements = eZURLAliasML::fetchByAction( 'eznode', $nodeID, true, true, true );
212 foreach ( $elements as $element )
213 {
214 $path = $element->getPath();
215 $this->cacheURL( '/' . $path );
216 }
217 }
218 }
219
228 public function generateCache( $force = false, $quiet = false, $cli = false, $delay = true )
229 {
230 $staticURLArray = $this->cachedURLArray();
231 $db = eZDB::instance();
232 $configSettingCount = count( $staticURLArray );
233 $currentSetting = 0;
234
235 // This contains parent elements which must checked to find new urls and put them in $generateList
236 // Each entry contains:
237 // - url - Url of parent
238 // - glob - A glob string to filter direct children based on name
239 // - org_url - The original url which was requested
240 // - parent_id - The element ID of the parent (optional)
241 // The parent_id will be used to quickly fetch the children, if not it will use the url
242 $parentList = array();
243 // A list of urls which must generated, each entry is a string with the url
244 $generateList = array();
245 foreach ( $staticURLArray as $url )
246 {
247 $currentSetting++;
248 if ( strpos( $url, '*') === false )
249 {
250 $generateList[] = $url;
251 }
252 else
253 {
254 $queryURL = ltrim( str_replace( '*', '', $url ), '/' );
255 $dir = dirname( $queryURL );
256 if ( $dir == '.' )
257 $dir = '';
258 $glob = basename( $queryURL );
259 $parentList[] = array( 'url' => $dir,
260 'glob' => $glob,
261 'org_url' => $url );
262 }
263 }
264
265 // As long as we have urls to generate or parents to check we loop
266 while ( count( $generateList ) > 0 || count( $parentList ) > 0 )
267 {
268 // First generate single urls
269 foreach ( $generateList as $generateURL )
270 {
271 if ( !$quiet and $cli )
272 $cli->output( "caching: $generateURL ", false );
273 $this->cacheURL( $generateURL, false, !$force, $delay );
274 if ( !$quiet and $cli )
275 $cli->output( "done" );
276 }
277 $generateList = array();
278
279 // Then check for more data
280 $newParentList = array();
281 foreach ( $parentList as $parentURL )
282 {
283 if ( isset( $parentURL['parent_id'] ) )
284 {
285 $elements = eZURLAliasML::fetchByParentID( $parentURL['parent_id'], true, true, false );
286 foreach ( $elements as $element )
287 {
288 $path = '/' . $element->getPath();
289 $generateList[] = $path;
290 $newParentList[] = array( 'parent_id' => $element->attribute( 'id' ) );
291 }
292 }
293 else
294 {
295 if ( !$quiet and $cli and $parentURL['glob'] )
296 $cli->output( "wildcard cache: " . $parentURL['url'] . '/' . $parentURL['glob'] . "*" );
297 $elements = eZURLAliasML::fetchByPath( $parentURL['url'], $parentURL['glob'] );
298 foreach ( $elements as $element )
299 {
300 $path = '/' . $element->getPath();
301 $generateList[] = $path;
302 $newParentList[] = array( 'parent_id' => $element->attribute( 'id' ) );
303 }
304 }
305 }
306 $parentList = $newParentList;
307 }
308 }
309
318 public function cacheURL( $url, $nodeID = false, $skipExisting = false, $delay = true )
319 {
320 // Check if URL should be cached
321 if ( substr_count( $url, "/") >= $this->maxCacheDepth )
322 return false;
323
324 $doCacheURL = false;
325 foreach ( $this->cachedURLArray as $cacheURL )
326 {
327 if ( $url == $cacheURL )
328 {
329 $doCacheURL = true;
330 break;
331 }
332 else if ( strpos( $cacheURL, '*') !== false )
333 {
334 if ( strpos( $url, str_replace( '*', '', $cacheURL ) ) === 0 )
335 {
336 $doCacheURL = true;
337 break;
338 }
339 }
340 }
341
342 if ( $doCacheURL == false )
343 {
344 return false;
345 }
346
347 $this->storeCache( $url, $this->staticStorageDir, $nodeID ? array( "/content/view/full/$nodeID" ) : array(), $skipExisting, $delay );
348
349 return true;
350 }
351
362 private function storeCache( $url, $staticStorageDir, $alternativeStaticLocations = array(), $skipUnlink = false, $delay = true )
363 {
364 $dirs = array();
365
366 foreach ( $this->cachedSiteAccesses as $cachedSiteAccess )
367 {
368 $dirs[] = $this->buildCacheDirPath( $cachedSiteAccess );
369 }
370
371 foreach ( $dirs as $dirParts )
372 {
373 foreach ( $dirParts as $dirPart )
374 {
375 $dir = $dirPart['dir'];
376 $siteURL = $dirPart['site_url'];
377
378 $cacheFiles = array();
379
380 $cacheFiles[] = $this->buildCacheFilename( $staticStorageDir, $dir . $url );
381 foreach ( $alternativeStaticLocations as $location )
382 {
383 $cacheFiles[] = $this->buildCacheFilename( $staticStorageDir, $dir . $location );
384 }
385
386 // Store new content
387 $content = false;
388 foreach ( $cacheFiles as $file )
389 {
390 if ( !$skipUnlink || !file_exists( $file ) )
391 {
392 // Deprecated since 4.4, will be removed in future version
393 $fileName = "http://{$this->hostName}{$dir}{$url}";
394
395 // staticcache.ini.[CacheSettings].HostName has been deprecated since version 4.4
396 // hostname is read from site.ini.[SiteSettings].SiteURL per siteaccess
397 // defined in staticcache.ini.[CacheSettings].CachedSiteAccesses
398 if ( !$this->hostName )
399 {
400 $fileName = "http://{$siteURL}{$url}";
401 }
402
403 if ( $delay )
404 {
405 $this->addAction( 'store', array( $file, $fileName ) );
406 }
407 else
408 {
409 // Generate content, if required
410 if ( $content === false )
411 {
412 if ( eZHTTPTool::getDataByURL( $fileName, true, eZStaticCache::USER_AGENT ) )
413 $content = eZHTTPTool::getDataByURL( $fileName, false, eZStaticCache::USER_AGENT );
414 }
415 if ( $content === false )
416 {
417 eZDebug::writeError( "Could not grab content (from $fileName), is the hostname correct and Apache running?", 'Static Cache' );
418 }
419 else
420 {
421 eZStaticCache::storeCachedFile( $file, $content );
422 }
423 }
424 }
425 }
426 }
427 }
428 }
429
437 private function buildCacheFilename( $staticStorageDir, $url )
438 {
439 $file = "{$staticStorageDir}{$url}/index.html";
440 $file = preg_replace( '#//+#', '/', $file );
441 return $file;
442 }
443
451 private function buildCacheDirPath( $siteAccess )
452 {
453 $dirParts = array();
454
455 $ini = eZINI::instance();
456
457 $matchOderArray = $ini->variableArray( 'SiteAccessSettings', 'MatchOrder' );
458
459 foreach ( $matchOderArray as $matchOrderItem )
460 {
461 switch ( $matchOrderItem )
462 {
463 case 'host_uri':
464 foreach ( $ini->variable( 'SiteAccessSettings', 'HostUriMatchMapItems' ) as $hostUriMatchMapItem )
465 {
466 $parts = explode( ';', $hostUriMatchMapItem );
467
468 if ( $parts[2] === $siteAccess )
469 {
470 $dirParts[] = $this->buildCacheDirPart( ( $parts[0] ? '/' . $parts[0] : '' ) .
471 ( $parts[1] ? '/' . $parts[1] : '' ), $siteAccess );
472 }
473 }
474 break;
475 case 'host':
476 foreach ( $ini->variable( 'SiteAccessSettings', 'HostMatchMapItems' ) as $hostMatchMapItem )
477 {
478 $parts = explode( ';', $hostMatchMapItem );
479
480 if ( $parts[1] === $siteAccess )
481 {
482 $dirParts[] = $this->buildCacheDirPart( ( $parts[0] ? '/' . $parts[0] : '' ), $siteAccess );
483 }
484 }
485 break;
486 default:
487 $dirParts[] = $this->buildCacheDirPart( '/' . $siteAccess, $siteAccess );
488 break;
489 }
490 }
491
492 return $dirParts;
493 }
494
502 private function buildCacheDirPart( $dir, $siteAccess )
503 {
504 return array( 'dir' => $dir,
505 'access_name' => $siteAccess,
506 'site_url' => eZSiteAccess::getIni( $siteAccess, 'site.ini' )->variable( 'SiteSettings', 'SiteURL' ) );
507 }
508
516 static function storeCachedFile( $file, $content )
517 {
518 $dir = dirname( $file );
519 if ( !is_dir( $dir ) )
520 {
521 eZDir::mkdir( $dir, false, true );
522 }
523
524 $oldumask = umask( 0 );
525
526 $tmpFileName = $file . '.' . md5( $file. uniqid( "ezp". getmypid(), true ) );
527
528 // Remove files, this might be necessary for Windows
529 @unlink( $tmpFileName );
530
531 // Write the new cache file with the data attached
532 $fp = fopen( $tmpFileName, 'w' );
533 if ( $fp )
534 {
535 $comment = ( eZINI::instance( 'staticcache.ini' )->variable( 'CacheSettings', 'AppendGeneratedTime' ) === 'true' ) ? "<!-- Generated: " . date( 'Y-m-d H:i:s' ). " -->\n\n" : null;
536
537 fwrite( $fp, $content . $comment );
538 fclose( $fp );
539 eZFile::rename( $tmpFileName, $file, false, eZFile::CLEAN_ON_FAILURE | eZFile::APPEND_DEBUG_ON_FAILURE );
540
541 $perm = eZINI::instance()->variable( 'FileSettings', 'StorageFilePermissions' );
542 chmod( $file, octdec( $perm ) );
543 }
544
545 umask( $oldumask );
546 }
547
554 function removeURL( $url )
555 {
556 $dir = eZDir::path( array( $this->staticStorageDir, $url ) );
557
558 @unlink( $dir . "/index.html" );
559 @rmdir( $dir );
560 }
561
569 private function addAction( $action, $parameters )
570 {
571 self::$actionList[] = array( $action, $parameters );
572 }
573
577 static function executeActions()
578 {
579 if ( empty( self::$actionList ) )
580 {
581 return;
582 }
583
584 $fileContentCache = array();
585 $doneDestList = array();
586
587 $ini = eZINI::instance( 'staticcache.ini');
588 $clearByCronjob = ( $ini->variable( 'CacheSettings', 'CronjobCacheClear' ) == 'enabled' );
589
590 if ( $clearByCronjob )
591 {
592 $db = eZDB::instance();
593 }
594
595 foreach ( self::$actionList as $action )
596 {
597 list( $action, $parameters ) = $action;
598
599 switch( $action ) {
600 case 'store':
601 list( $destination, $source ) = $parameters;
602
603 if ( isset( $doneDestList[$destination] ) )
604 continue 2;
605
606 if ( $clearByCronjob )
607 {
608 $param = $db->escapeString( $destination . ',' . $source );
609 $db->query( 'INSERT INTO ezpending_actions( action, param ) VALUES ( \'static_store\', \''. $param . '\' )' );
610 $doneDestList[$destination] = 1;
611 }
612 else
613 {
614 if ( !isset( $fileContentCache[$source] ) )
615 {
616 if ( eZHTTPTool::getDataByURL( $source, true, eZStaticCache::USER_AGENT ) )
617 $fileContentCache[$source] = eZHTTPTool::getDataByURL( $source, false, eZStaticCache::USER_AGENT );
618 else
619 $fileContentCache[$source] = false;
620 }
621 if ( $fileContentCache[$source] === false )
622 {
623 eZDebug::writeError( "Could not grab content (from $source), is the hostname correct and Apache running?", 'Static Cache' );
624 }
625 else
626 {
627 eZStaticCache::storeCachedFile( $destination, $fileContentCache[$source] );
628 $doneDestList[$destination] = 1;
629 }
630 }
631 break;
632 }
633 }
634 self::$actionList = array();
635 }
636 }
637
638 ?>
eZContentObjectTreeNode\fetchByURLPath
static fetchByURLPath( $pathString, $asObject=true)
Definition: ezcontentobjecttreenode.php:2943
eZDB\instance
static instance( $databaseImplementation=false, $databaseParameters=false, $forceNewInstance=false)
Definition: ezdb.php:117
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDir\mkdir
static mkdir( $dir, $perm=false, $recursive=false)
Definition: ezdir.php:73
eZDir\path
static path( $names, $includeEndSeparator=false, $type=self::SEPARATOR_UNIX)
Definition: ezdir.php:237
eZFile\CLEAN_ON_FAILURE
const CLEAN_ON_FAILURE
Definition: ezfile.php:31
eZFile\rename
static rename( $srcFile, $destFile, $mkdir=false, $flags=0)
Definition: ezfile.php:152
eZFile\APPEND_DEBUG_ON_FAILURE
const APPEND_DEBUG_ON_FAILURE
Definition: ezfile.php:32
eZHTTPTool\getDataByURL
static getDataByURL( $url, $justCheckURL=false, $userAgent=false, $forceGetRequest=false)
Definition: ezhttptool.php:739
eZSiteAccess\getIni
static getIni( $siteAccess, $settingFile='site.ini')
Definition: ezsiteaccess.php:631
eZStaticCache
Definition: ezstaticcache.php:30
eZStaticCache\addAction
addAction( $action, $parameters)
Definition: ezstaticcache.php:569
eZStaticCache\$actionList
static $actionList
Definition: ezstaticcache.php:37
eZStaticCache\$staticStorageDir
$staticStorageDir
Definition: ezstaticcache.php:31
eZStaticCache\generateAlwaysUpdatedCache
generateAlwaysUpdatedCache( $quiet=false, $cli=false, $delay=true)
Definition: ezstaticcache.php:167
eZStaticCache\cachedSiteAccesses
cachedSiteAccesses()
Definition: ezstaticcache.php:132
eZStaticCache\$staticStorage
$staticStorage
Definition: ezstaticcache.php:52
eZStaticCache\executeActions
static executeActions()
Definition: ezstaticcache.php:577
eZStaticCache\cachedURLArray
cachedURLArray()
Definition: ezstaticcache.php:142
eZStaticCache\storageDirectory
storageDirectory()
Definition: ezstaticcache.php:112
eZStaticCache\storeCache
storeCache( $url, $staticStorageDir, $alternativeStaticLocations=array(), $skipUnlink=false, $delay=true)
Definition: ezstaticcache.php:362
eZStaticCache\cacheURL
cacheURL( $url, $nodeID=false, $skipExisting=false, $delay=true)
Definition: ezstaticcache.php:318
eZStaticCache\generateNodeListCache
generateNodeListCache( $nodeList)
Definition: ezstaticcache.php:188
eZStaticCache\$maxCacheDepth
$maxCacheDepth
Definition: ezstaticcache.php:59
eZStaticCache\buildCacheDirPath
buildCacheDirPath( $siteAccess)
Definition: ezstaticcache.php:451
eZStaticCache\maxCacheDepth
maxCacheDepth()
Definition: ezstaticcache.php:122
eZStaticCache\$alwaysUpdate
$alwaysUpdate
Definition: ezstaticcache.php:80
eZStaticCache\$cachedSiteAccesses
$cachedSiteAccesses
Definition: ezstaticcache.php:73
eZStaticCache\buildCacheFilename
buildCacheFilename( $staticStorageDir, $url)
Definition: ezstaticcache.php:437
eZStaticCache\buildCacheDirPart
buildCacheDirPart( $dir, $siteAccess)
Definition: ezstaticcache.php:502
eZStaticCache\alwaysUpdateURLArray
alwaysUpdateURLArray()
Definition: ezstaticcache.php:155
eZStaticCache\$hostName
$hostName
Definition: ezstaticcache.php:45
eZStaticCache\generateCache
generateCache( $force=false, $quiet=false, $cli=false, $delay=true)
Definition: ezstaticcache.php:228
eZStaticCache\USER_AGENT
const USER_AGENT
Definition: ezstaticcache.php:35
eZStaticCache\storeCachedFile
static storeCachedFile( $file, $content)
Definition: ezstaticcache.php:516
eZStaticCache\__construct
__construct()
Definition: ezstaticcache.php:85
eZStaticCache\removeURL
removeURL( $url)
Definition: ezstaticcache.php:554
eZStaticCache\$cachedURLArray
$cachedURLArray
Definition: ezstaticcache.php:66
eZStaticCache\hostName
hostName()
Definition: ezstaticcache.php:102
eZURLAliasML\fetchByAction
static fetchByAction( $actionName, $actionValue, $maskLanguages=false, $onlyPrioritized=false, $includeRedirections=false)
Definition: ezurlaliasml.php:967
eZURLAliasML\fetchByParentID
static fetchByParentID( $id, $maskLanguages=false, $onlyPrioritized=false, $includeRedirections=true)
Definition: ezurlaliasml.php:1049
eZURLAliasML\fetchByPath
static fetchByPath( $uriString, $glob=false)
Definition: ezurlaliasml.php:1253
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.