Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezcontentcachemanager.php
Go to the documentation of this file.
1 <?php
24 class eZContentCacheManager
25 {
26 // Clear cache types
27 const CLEAR_NO_CACHE = 0;
28 const CLEAR_NODE_CACHE = 1;
29 const CLEAR_PARENT_CACHE = 2;
30 const CLEAR_RELATING_CACHE = 4;
31 const CLEAR_KEYWORD_CACHE = 8;
32 const CLEAR_SIBLINGS_CACHE = 16;
33 const CLEAR_CHILDREN_CACHE = 32;
34 const CLEAR_ALL_CACHE = 63;
35 const CLEAR_DEFAULT = 15; // CLEAR_NODE_CACHE and CLEAR_PARENT_CACHE and CLEAR_RELATING_CACHE and CLEAR_KEYWORD_CACHE
36
43 private static $additionalNodeIDsPerObject = array();
44
51 public static function addAdditionalNodeIDPerObject( $contentObjectID, $additionalNodeID )
52 {
53 if ( !isset( self::$additionalNodeIDsPerObject[$contentObjectID] ) )
54 {
55 self::$additionalNodeIDsPerObject[$contentObjectID] = array();
56 }
57
58 self::$additionalNodeIDsPerObject[$contentObjectID][] = $additionalNodeID;
59 }
60
67 private static function appendAdditionalNodeIDs( eZContentObject $contentObject, &$nodeIDList )
68 {
69 $contentObjectId = $contentObject->attribute( 'id' );
70 if ( !isset( self::$additionalNodeIDsPerObject[$contentObjectId] ) )
71 return;
72
73 foreach ( self::$additionalNodeIDsPerObject[$contentObjectId] as $nodeID )
74 {
75 $nodeIDList[] = $nodeID;
76 }
77 }
78
85 static function appendParentNodeIDs( $object, $versionNum, &$nodeIDList )
86 {
87 foreach ( $object->parentNodeIDArray() as $parentNodeID )
88 {
89 $nodeIDList[] = $parentNodeID;
90 }
91 }
92
98 static function appendNodeIDs( $nodeList, &$nodeIDList )
99 {
100 foreach ( $nodeList as $node )
101 {
102 $nodeIDList[] = $node->attribute( 'node_id' );
103 }
104 }
105
111 static function fetchNodePathString( $nodeList )
112 {
113 $pathList = array();
114 foreach ( $nodeList as $node )
115 {
116 $pathList[] = $node->attribute( 'path_string' );
117 }
118 return $pathList;
119 }
120
127 static function appendRelatingNodeIDs( $object, &$nodeIDList )
128 {
129 $viewCacheIni = eZINI::instance( 'viewcache.ini' );
130 if ( $viewCacheIni->hasVariable( 'ViewCacheSettings', 'ClearRelationTypes' ) )
131 {
132 $relTypes = $viewCacheIni->variable( 'ViewCacheSettings', 'ClearRelationTypes' );
133
134 if ( !count( $relTypes ) )
135 return;
136
137 $relatedObjects = array();
138
139 $relationsMask = 0;
140 if ( in_array( 'object', $relTypes ) )
141 $relationsMask |= eZContentObject::RELATION_COMMON | eZContentObject::RELATION_EMBED;
142
143 if ( in_array( 'common', $relTypes ) )
144 $relationsMask |= eZContentObject::RELATION_COMMON;
145
146 if ( in_array( 'embedded', $relTypes ) )
147 $relationsMask |= eZContentObject::RELATION_EMBED;
148
149 if ( in_array( 'linked', $relTypes ) )
150 $relationsMask |= eZContentObject::RELATION_LINK;
151
152 if ( in_array( 'attribute', $relTypes ) )
153 $relationsMask |= eZContentObject::RELATION_ATTRIBUTE;
154
155 if ( $relationsMask )
156 {
157 $objects = $object->relatedContentObjectList( false, false, false, false,
158 array( 'AllRelations' => $relationsMask ) );
159 $previousVersionObjects = array();
160 $previousVersion = $object->previousVersion();
161 if ( $previousVersion )
162 {
163 $previousVersionObjects = $object->relatedContentObjectList( $previousVersion, false, false, false,
164 array( 'AllRelations' => $relationsMask ) );
165 }
166 $relatedObjects = array_merge( $relatedObjects, $objects, $previousVersionObjects );
167 }
168
169 $relationsMask = 0;
170 if ( in_array( 'reverse_object', $relTypes ) )
171 $relationsMask |= eZContentObject::RELATION_COMMON | eZContentObject::RELATION_EMBED;
172
173 if ( in_array( 'reverse_common', $relTypes ) )
174 $relationsMask |= eZContentObject::RELATION_COMMON;
175
176 if ( in_array( 'reverse_embedded', $relTypes ) )
177 $relationsMask |= eZContentObject::RELATION_EMBED;
178
179 if ( in_array( 'reverse_linked', $relTypes ) )
180 $relationsMask |= eZContentObject::RELATION_LINK;
181
182 if ( in_array( 'reverse_attribute', $relTypes ) )
183 $relationsMask |= eZContentObject::RELATION_ATTRIBUTE;
184
185 if ( $relationsMask )
186 {
187 $objects = $object->reverseRelatedObjectList( false, false, false,
188 array( 'AllRelations' => $relationsMask ) );
189 $previousVersionObjects = array();
190 $previousVersion = $object->previousVersion();
191 if ( $previousVersion )
192 {
193 $previousVersionObjects = $object->relatedContentObjectList( $previousVersion, false, false, false,
194 array( 'AllRelations' => $relationsMask ) );
195 }
196 $relatedObjects = array_merge( $relatedObjects, $objects, $previousVersionObjects );
197 }
198 }
199 else
200 {
201 $normalRelated = $object->relatedContentObjectArray();
202 $reversedRelated = $object->contentObjectListRelatingThis();
203
204 $relatedObjects = array_merge( $normalRelated, $reversedRelated );
205 }
206
207 foreach ( $relatedObjects as $relatedObject )
208 {
209 $assignedNodes = $relatedObject->assignedNodes( false );
210 foreach ( $assignedNodes as $assignedNode )
211 {
212 $nodeIDList[] = $assignedNode['node_id'];
213 }
214 }
215 $nodeIDList = array_unique( $nodeIDList );
216 }
217
224 static function appendKeywordNodeIDs( $object, $versionNum, &$nodeIDList, $limit = null )
225 {
226 if ( $limit === 0 )
227 return;
228 if ( $versionNum === true )
229 $versionNum = false;
230 $keywordArray = array();
231 $attributes = $object->contentObjectAttributes( true, $versionNum );
232 foreach ( array_keys( $attributes ) as $key ) // Looking for ezkeyword attributes
233 {
234 if ( $attributes[$key] instanceof eZContentObjectAttribute and
235 $attributes[$key]->attribute( 'data_type_string' ) == 'ezkeyword' ) // Found one
236 {
237 $keywordObject = $attributes[$key]->content();
238 if ( $keywordObject instanceof eZKeyword )
239 {
240 foreach ( $keywordObject->attribute( 'keywords' ) as $keyword )
241 {
242 $keywordArray[] = $keyword;
243 }
244 }
245 }
246 }
247
248 // Find all nodes that have the given keywords
249 if ( count( $keywordArray ) > 0 )
250 {
251 $db = eZDB::instance();
252 foreach( $keywordArray as $k => $keyword )
253 {
254 $keywordArray[$k] = "'" . $db->escapeString( $keyword ) . "'";
255 }
256 $keywordString = implode( ', ', $keywordArray );
257 $params = $limit ? array( 'offset' => 0, 'limit' => $limit ) : array();
258 $rows = $db->arrayQuery( "SELECT DISTINCT ezcontentobject_tree.node_id
259 FROM
260 ezcontentobject_tree,
261 ezcontentobject_attribute,
262 ezkeyword_attribute_link,
263 ezkeyword
264 WHERE
265 ezcontentobject_tree.contentobject_id = ezcontentobject_attribute.contentobject_id AND
266 ezcontentobject_attribute.id = ezkeyword_attribute_link.objectattribute_id AND
267 ezkeyword_attribute_link.keyword_id = ezkeyword.id AND
268 ezkeyword.keyword IN ( $keywordString )",
269 $params );
270
271 foreach ( $rows as $row )
272 {
273 $nodeIDList[] = $row['node_id'];
274 }
275 }
276 }
277
278 /*
279 \static
280 For each node in \a $nodeList finds its sibling nodes and adds its ids to
281 the \a $nodeIDList
282 */
283 static function appendSiblingsNodeIDs( &$nodeList, &$nodeIDList )
284 {
285 $params = array( 'Depth' => 1,
286 'AsObject' => false );
287 foreach ( $nodeList as $node )
288 {
289 $siblingNodeList = eZContentObjectTreeNode::subTreeByNodeID( $params, $node->attribute( 'parent_node_id' ) );
290 if ( count( $siblingNodeList ) > 0 )
291 {
292 foreach ( array_keys( $siblingNodeList ) as $siblingKey )
293 {
294 $nodeIDList[] = $siblingNodeList[$siblingKey]['node_id'];
295 }
296 }
297 }
298 }
299
307 public static function appendChildrenNodeIDs( &$nodeList, &$nodeIDList )
308 {
309 $params = array( 'Depth' => 1,
310 'AsObject' => false );
311 foreach ( $nodeList as $node )
312 {
313 $childNodeList = eZContentObjectTreeNode::subTreeByNodeID( $params, $node->attribute( 'node_id' ) );
314 if ( !empty( $childNodeList ) )
315 {
316 foreach ( $childNodeList as $childNode )
317 {
318 $nodeIDList[] = $childNode['node_id'];
319 }
320 }
321 }
322 }
323
324 /*
325 \static
326 Reads 'viewcache.ini' file and determines relation between
327 \a $classID and another class.
328
329 \return An associative array with information on the class, containsL:
330 - dependent_class_identifier - The class identifier of objects that depend on this class
331 - additional_objects - Array of additional arbitrary object ids to clear
332 - max_parents - The maxium number of parent nodes to check, or \c 0 for no limit
333 - clear_cache_type - Bitfield of clear types, see nodeListForObject() for more details
334 - object_filter - Array with object IDs, if there are entries only these objects should be checked.
335 */
336 static function dependencyInfo( $classID, $ignoreINISettings = false )
337 {
338 $ini = eZINI::instance( 'viewcache.ini' );
339 $info = false;
340
341 if ( $ignoreINISettings || $ini->variable( 'ViewCacheSettings', 'SmartCacheClear' ) !== 'disabled' )
342 {
343 if ( $ini->hasGroup( $classID ) )
344 {
345 $info = array();
346 $info['clear_cache_exclusive'] = $ini->variable( 'ViewCacheSettings', 'SmartCacheClear' ) === 'exclusive';
347
348 if ( $ini->hasVariable( $classID, 'DependentClassIdentifier' ) )
349 $info['dependent_class_identifier'] = $ini->variable( $classID, 'DependentClassIdentifier' );
350
351 if ( $ini->hasVariable( $classID, 'MaxParents' ) )
352 $info['max_parents'] = $ini->variable( $classID, 'MaxParents' );
353 else
354 $info['max_parents'] = 0;
355
356 if ( $ini->hasVariable( $classID, 'AdditionalObjectIDs' ) )
357 $info['additional_objects'] = $ini->variable( $classID, 'AdditionalObjectIDs' );
358
359 $info['clear_cache_type'] = 0;
360 if ( $ini->hasVariable( $classID, 'ClearCacheMethod' ) )
361 {
362 $type = $ini->variable( $classID, 'ClearCacheMethod' );
363
364 if ( is_array( $type ) )
365 {
366 if ( in_array( 'none', $type ) )
367 {
368 $info['clear_cache_type'] = self::CLEAR_NO_CACHE;
369 }
370 elseif ( in_array( 'all', $type ) )
371 {
372 $info['clear_cache_type'] = self::CLEAR_ALL_CACHE;
373 }
374 else
375 {
376 if ( in_array( 'object', $type ) )
377 $info['clear_cache_type'] |= self::CLEAR_NODE_CACHE;
378
379 if ( in_array( 'parent', $type ) )
380 $info['clear_cache_type'] |= self::CLEAR_PARENT_CACHE;
381
382 if ( in_array( 'relating', $type ) )
383 $info['clear_cache_type'] |= self::CLEAR_RELATING_CACHE;
384
385 if ( in_array( 'keyword', $type ) )
386 $info['clear_cache_type'] |= self::CLEAR_KEYWORD_CACHE;
387
388 if ( in_array( 'siblings', $type ) )
389 $info['clear_cache_type'] |= self::CLEAR_SIBLINGS_CACHE;
390
391 if ( in_array( 'children', $type ) )
392 $info['clear_cache_type'] |= self::CLEAR_CHILDREN_CACHE;
393 }
394 }
395 }
396 else
397 {
398 $info['clear_cache_type'] = self::CLEAR_DEFAULT;
399 }
400
401 $info['object_filter'] = array();
402 if ( $ini->hasVariable( $classID, 'ObjectFilter' ) )
403 {
404 $info['object_filter'] = $ini->variable( $classID, 'ObjectFilter' );
405 }
406 }
407 }
408
409 return $info;
410 }
411
412 /*
413 Can be used to debug the \a $handledObjectList parameter of nodeListForObject()
414 */
415 static function writeDebugBits( $handledObjectList, $highestBit )
416 {
417 $bitPadLength = (int)( pow( $highestBit, 0.5 ) + 1 );
418 //$bitPadLength = strlen( decbin( $highestBit ) );
419
420 $objectIDList = array_keys( $handledObjectList );
421 $maxObjectID = max( $objectIDList );
422 $padLength = strlen( $maxObjectID ) + 2;
423
424 $msg = '';
425 foreach ( $handledObjectList as $objectID => $clearCacheType )
426 {
427 $bitString = decbin( $clearCacheType );
428 $msg .= str_pad( $objectID, $padLength, ' ', STR_PAD_RIGHT ) . str_pad( $bitString, $bitPadLength, '0', STR_PAD_LEFT );
429 $msg .= "\r\n";
430 }
431
432 eZDebug::writeDebug( $msg, __METHOD__ );
433 }
434
457 static function nodeListForObject( $contentObject, $versionNum, $clearCacheType, &$nodeList, &$handledObjectList )
458 {
459 $contentObjectID = $contentObject->attribute( 'id' );
460
461 if ( isset( $handledObjectList[$contentObjectID] ) )
462 {
463 $handledObjectList[$contentObjectID] |= $clearCacheType;
464 }
465 else
466 {
467 $handledObjectList[$contentObjectID] = $clearCacheType;
468 }
469 //self::writeDebugBits( $handledObjectList, self::CLEAR_SIBLINGS_CACHE );
470
471 $assignedNodes = $contentObject->assignedNodes();
472
473 // determine if $contentObject has dependent objects for which cache should be cleared too.
474 $objectClassIdentifier = $contentObject->attribute( 'class_identifier' );
475 $dependentClassInfo = eZContentCacheManager::dependencyInfo( $objectClassIdentifier );
476
477 if ( $dependentClassInfo['clear_cache_type'] === self::CLEAR_NO_CACHE )
478 {
479 // BC: Allow smart cache clear setting to specify no caching setting
480 $clearCacheType = self::CLEAR_NO_CACHE;
481 }
482 else if ( $dependentClassInfo['clear_cache_exclusive'] === true )
483 {
484 // use class specific smart cache rules exclusivly
485 $clearCacheType = $dependentClassInfo['clear_cache_type'];
486 }
487
488 if ( $clearCacheType === self::CLEAR_NO_CACHE )
489 {
490 // when recursing we will never have to handle this object again for other cache types
491 // because types of caches to clear will always be set to none
492 $handledObjectList[$contentObjectID] = self::CLEAR_ALL_CACHE;
493 }
494
495 if ( $clearCacheType & self::CLEAR_NODE_CACHE )
496 {
497 eZContentCacheManager::appendNodeIDs( $assignedNodes, $nodeList );
498 }
499
500 if ( $clearCacheType & self::CLEAR_PARENT_CACHE )
501 {
502 eZContentCacheManager::appendParentNodeIDs( $contentObject, $versionNum, $nodeList );
503 }
504
505 if ( $clearCacheType & self::CLEAR_RELATING_CACHE )
506 {
507 eZContentCacheManager::appendRelatingNodeIDs( $contentObject, $nodeList );
508 }
509
510 if ( $clearCacheType & self::CLEAR_KEYWORD_CACHE )
511 {
512 $keywordClearLimit = null;
513 $viewcacheini = eZINI::instance( 'viewcache.ini' );
514 if ( is_numeric( $viewcacheini->variable( 'ViewCacheSettings', 'KeywordNodesCacheClearLimit' ) ) )
515 $keywordClearLimit = (int) $viewcacheini->variable( 'ViewCacheSettings', 'KeywordNodesCacheClearLimit' );
516
517 eZContentCacheManager::appendKeywordNodeIDs( $contentObject, $versionNum, $nodeList, $keywordClearLimit );
518 }
519
520 if ( $clearCacheType & self::CLEAR_SIBLINGS_CACHE )
521 {
522 eZContentCacheManager::appendSiblingsNodeIDs( $assignedNodes, $nodeList );
523 }
524
525 if ( $dependentClassInfo['clear_cache_type'] & self::CLEAR_SIBLINGS_CACHE )
526 {
527 if ( !( $clearCacheType & self::CLEAR_SIBLINGS_CACHE ) )
528 {
529 eZContentCacheManager::appendSiblingsNodeIDs( $assignedNodes, $nodeList );
530 $handledObjectList[$contentObjectID] |= self::CLEAR_SIBLINGS_CACHE;
531 }
532
533 // drop 'siblings' bit and process parent nodes.
534 // since 'sibling' mode is affected to the current object
535 $dependentClassInfo['clear_cache_type'] &= ~self::CLEAR_SIBLINGS_CACHE;
536 }
537
538 if ( $clearCacheType & self::CLEAR_CHILDREN_CACHE )
539 {
540 eZContentCacheManager::appendChildrenNodeIDs( $assignedNodes, $nodeList );
541 }
542
543 if ( $dependentClassInfo['clear_cache_type'] & self::CLEAR_CHILDREN_CACHE )
544 {
545 if ( !( $clearCacheType & self::CLEAR_CHILDREN_CACHE ) )
546 {
547 eZContentCacheManager::appendChildrenNodeIDs( $assignedNodes, $nodeList );
548 $handledObjectList[$contentObjectID] |= self::CLEAR_CHILDREN_CACHE;
549 }
550 // drop 'children' bit and process parent nodes.
551 // since 'children' mode is affected to the current object
552 $dependentClassInfo['clear_cache_type'] &= ~self::CLEAR_CHILDREN_CACHE;
553 }
554
555 if ( isset( $dependentClassInfo['additional_objects'] ) )
556 {
557 foreach( $dependentClassInfo['additional_objects'] as $objectID )
558 {
559 // skip if cache type is already handled for this object
560 if ( isset( $handledObjectList[$objectID] ) && $handledObjectList[$objectID] & self::CLEAR_NODE_CACHE )
561 {
562 continue;
563 }
564
565 $object = eZContentObject::fetch( $objectID );
566 if ( $object )
567 {
568 //eZDebug::writeDebug( 'adding additional object ' . $objectID, 'eZContentCacheManager::nodeListForObject() for object ' . $contentObjectID );
569 eZContentCacheManager::nodeListForObject( $object, true, self::CLEAR_NODE_CACHE, $nodeList, $handledObjectList );
570 }
571 }
572 }
573
574 if ( isset( $dependentClassInfo['dependent_class_identifier'] ) )
575 {
576 $maxParents = $dependentClassInfo['max_parents'];
577 $dependentClassIdentifiers = $dependentClassInfo['dependent_class_identifier'];
578 $smartClearType = $dependentClassInfo['clear_cache_type'];
579
580 // getting 'path_string's for all locations.
581 $nodePathList = eZContentCacheManager::fetchNodePathString( $assignedNodes );
582
583 foreach ( $nodePathList as $nodePath )
584 {
585 $step = 0;
586
587 // getting class identifier and node ID for each node in the $nodePath, up to $maxParents
588 $nodeInfoList = eZContentObjectTreeNode::fetchClassIdentifierListByPathString( $nodePath, false, $maxParents );
589
590 // for each node in $nodeInfoList determine if this node belongs to $dependentClassIdentifiers. If
591 // so then clear cache for this node.
592 foreach ( $nodeInfoList as $item )
593 {
594 if ( in_array( $item['class_identifier'], $dependentClassIdentifiers ) )
595 {
596 $object = eZContentObject::fetchByNodeID( $item['node_id'] );
597 if ( !$object instanceof eZContentObject )
598 {
599 continue;
600 }
601 $objectID = $object->attribute( 'id' );
602
603 if ( isset( $handledObjectList[$objectID] ) )
604 {
605 // remove cache types that were already handled
606 $smartClearType &= ~$handledObjectList[$objectID];
607
608 // if there are no cache types remaining, then skip
609 if ( $smartClearType == self::CLEAR_NO_CACHE )
610 {
611 continue;
612 }
613 }
614
615 if ( count( $dependentClassInfo['object_filter'] ) > 0 )
616 {
617 if ( in_array( $objectID, $dependentClassInfo['object_filter'] ) )
618 {
619 //eZDebug::writeDebug( 'adding parent ' . $objectID, 'eZContentCacheManager::nodeListForObject() for object ' . $contentObjectID );
620 eZContentCacheManager::nodeListForObject( $object, true, $smartClearType, $nodeList, $handledObjectList );
621 }
622 }
623 else
624 {
625 //eZDebug::writeDebug( 'adding parent ' . $objectID, 'eZContentCacheManager::nodeListForObject() for object ' . $contentObjectID );
626 eZContentCacheManager::nodeListForObject( $object, true, $smartClearType, $nodeList, $handledObjectList );
627 }
628 }
629 }
630 }
631 }
632
633 self::appendAdditionalNodeIDs( $contentObject, $nodeList );
634
635 //self::writeDebugBits( $handledObjectList, self::CLEAR_SIBLINGS_CACHE );
636 }
637
652 static function nodeList( $objectID, $versionNum )
653 {
654 $nodeList = array();
655
656 $object = eZContentObject::fetch( $objectID );
657 if ( !$object )
658 {
659 return false;
660 }
661
662 eZContentCacheManager::nodeListForObject( $object, $versionNum, self::CLEAR_DEFAULT, $nodeList, $handledObjectList );
663
664 return $nodeList;
665 }
666
676 static function clearObjectViewCache( $objectID, $versionNum = true, $additionalNodeList = false )
677 {
678 eZDebug::accumulatorStart( 'node_cleanup_list', '', 'Node cleanup list' );
679
680 $nodeList = eZContentCacheManager::nodeList( $objectID, $versionNum );
681
682 if ( $nodeList === false and !is_array( $additionalNodeList ) )
683 return false;
684
685 if ( $nodeList === false )
686 {
687 $nodeList = array();
688 }
689
690 if ( is_array( $additionalNodeList ) )
691 {
692 array_splice( $nodeList, count( $nodeList ), 0, $additionalNodeList );
693 }
694
695 $nodeList = array_unique( $nodeList );
696
697 eZDebug::accumulatorStop( 'node_cleanup_list' );
698
699 return self::clearNodeViewCacheArray( $nodeList, array( $objectID ) );
700 }
701
711 public static function clearObjectViewCacheArray( array $objectIDList )
712 {
713 eZDebug::accumulatorStart( 'node_cleanup_list', '', 'Node cleanup list' );
714
715 $nodeList = array();
716
717 foreach ( $objectIDList as $objectID )
718 {
719 $tempNodeList = self::nodeList( $objectID, true );
720
721 if ( $tempNodeList !== false )
722 {
723 $nodeList = array_merge( $nodeList, $tempNodeList );
724 }
725 }
726
727 $nodeList = array_unique( $nodeList );
728
729 eZDebug::accumulatorStop( 'node_cleanup_list' );
730
731 return self::clearNodeViewCacheArray( $nodeList, $objectIDList );
732 }
733
741 public static function clearNodeViewCacheArray( array $nodeList, array|null $contentObjectList = null )
742 {
743 if ( count( $nodeList ) == 0 )
744 {
745 return false;
746 }
747
748 eZDebugSetting::writeDebug( 'kernel-content-edit', count( $nodeList ), "count in nodeList" );
749
750 if ( eZINI::instance()->variable( 'ContentSettings', 'StaticCache' ) === 'enabled' )
751 {
752 $staticCacheHandler = eZExtension::getHandlerClass(
753 new ezpExtensionOptions(
754 array(
755 'iniFile' => 'site.ini',
756 'iniSection' => 'ContentSettings',
757 'iniVariable' => 'StaticCacheHandler',
758 )
759 )
760 );
761
762 $staticCacheHandler->generateAlwaysUpdatedCache();
763 $staticCacheHandler->generateNodeListCache( $nodeList );
764 }
765
766 eZDebug::accumulatorStart( 'node_cleanup', '', 'Node cleanup' );
767
768 eZContentObject::expireComplexViewModeCache();
769 $cleanupValue = eZContentCache::calculateCleanupValue( count( $nodeList ) );
770
771 if ( eZContentCache::inCleanupThresholdRange( $cleanupValue ) )
772 {
773 ezpEvent::getInstance()->notify( 'content/cache', array( $nodeList, $contentObjectList ) );
774 eZContentCache::cleanup( $nodeList );
775 }
776 else
777 {
778 eZDebug::writeDebug( "Expiring all view cache since list of nodes({$cleanupValue}) exceeds site.ini\[ContentSettings]\CacheThreshold", __METHOD__ );
779 ezpEvent::getInstance()->notify( 'content/cache/all' );
780 eZContentObject::expireAllViewCache();
781 }
782
783 eZDebug::accumulatorStop( 'node_cleanup' );
784 return true;
785 }
786
795 public static function clearObjectViewCacheIfNeeded( $objectID, $versionNum = true, $additionalNodeList = false )
796 {
797 if ( eZINI::instance()->variable( 'ContentSettings', 'ViewCaching' ) !== 'enabled' )
798 return;
799
800 if ( is_array( $objectID ) )
801 {
802 if ( $versionNum !== true || $additionalNodeList !== false )
803 {
804 trigger_error( "This method does not support second and third parameters when operating on many objects!" );
805 return false;
806 }
807
808 self::clearObjectViewCacheArray( $objectID );
809 }
810 else
811 {
812 self::clearObjectViewCache( $objectID, $versionNum, $additionalNodeList );
813 }
814 }
815
823 public static function clearTemplateBlockCacheIfNeeded( $objectID )
824 {
825 $ini = eZINI::instance();
826 if ( $ini->variable( 'TemplateSettings', 'TemplateCache' ) === 'enabled' )
827 self::clearTemplateBlockCache( $objectID, true );
828 }
829
838 public static function clearTemplateBlockCache( $objectID, $checkViewCacheClassSettings = false )
839 {
840 // ordinary template block cache
841 eZContentObject::expireTemplateBlockCache();
842
843 if ( empty( $objectID ) )
844 return;
845
846 // subtree template block cache
847 $nodeList = false;
848
849 if ( is_array( $objectID ) )
850 {
851 $objects = eZContentObject::fetchIDArray( $objectID );
852 }
853 else
854 {
855 $objects = array( $objectID => eZContentObject::fetch( $objectID ) );
856 }
857
858 $ini = eZINI::instance( 'viewcache.ini' );
859 foreach ( $objects as $object )
860 {
861 if ( $object instanceof eZContentObject )
862 {
863 $getAssignedNodes = true;
864 if ( $checkViewCacheClassSettings )
865 {
866 $objectClassIdentifier = $object->attribute('class_identifier');
867 if ( $ini->hasVariable( $objectClassIdentifier, 'ClearCacheBlocks' )
868 && $ini->variable( $objectClassIdentifier, 'ClearCacheBlocks' ) === 'disabled' )
869 {
870 $getAssignedNodes = false;
871 }
872 }
873
874 if ( $getAssignedNodes )
875 {
876 $nodeList = array_merge( ( $nodeList !== false ? $nodeList : array() ), $object->assignedNodes() );
877 }
878 }
879 }
880
881 eZSubtreeCache::cleanup( $nodeList );
882 }
883
891 static function generateObjectViewCache( $objectID )
892 {
893 // Generate the view cache
894 $ini = eZINI::instance();
895 $object = eZContentObject::fetch( $objectID );
896 $user = eZUser::currentUser();
897
898 eZDebug::accumulatorStart( 'generate_cache', '', 'Generating view cache' );
899 if ( $ini->variable( 'ContentSettings', 'PreViewCache' ) == 'enabled' )
900 {
901 $preCacheSiteaccessArray = $ini->variable( 'ContentSettings', 'PreCacheSiteaccessArray' );
902
903 $currentSiteAccess = $GLOBALS['eZCurrentAccess'];
904
905 // This is the default view parameters for content/view
906 $viewParameters = array( 'offset' => false,
907 'year' => false,
908 'month' => false,
909 'day' => false,
910 'namefilter' => false );
911 if ( is_array( $preCacheSiteaccessArray ) && count( $preCacheSiteaccessArray ) > 0 )
912 {
913 foreach ( $preCacheSiteaccessArray as $changeToSiteAccess )
914 {
915 $newSiteAccess = $currentSiteAccess;
916 $newSiteAccess['name'] = $changeToSiteAccess;
917 unset( $newSiteAccess['uri_part'] );//eZSiteAccess::load() will take care of setting correct one
918 eZSiteAccess::load( $newSiteAccess );
919
920 $tpl = eZTemplate::factory();
921
922 // Get the sitedesign and cached view preferences for this siteaccess
923 $siteini = eZINI::instance( 'site.ini');
924 $cachedViewPreferences = $siteini->variable( 'ContentSettings', 'CachedViewPreferences' );
925
926 $language = false; // Needs to be specified if you want to generate the cache for a specific language
927 $viewMode = 'full';
928
929 $assignedNodes = $object->assignedNodes();
930 foreach ( $assignedNodes as $node )
931 {
932 // We want to generate the cache for the specified user
933 $previewCacheUsers = $ini->variable( 'ContentSettings', 'PreviewCacheUsers' );
934 foreach ( $previewCacheUsers as $previewCacheUserID )
935 {
936 // If the text is 'anon' we need to fetch the Anonymous user ID.
937 if ( $previewCacheUserID === 'anonymous' )
938 {
939 $previewCacheUserID = $siteini->variable( "UserSettings", "AnonymousUserID" );
940 $previewCacheUser = eZUser::fetch( $previewCacheUserID );
941 }
942 else if ( $previewCacheUserID === 'current' )
943 {
944 $previewCacheUser = $user;
945 }
946 else
947 {
948 $previewCacheUser = eZUser::fetch( $previewCacheUserID );
949 }
950 if ( !$previewCacheUser )
951 continue;
952
953 // Before we generate the view cache we must change the currently logged in user to $previewCacheUser
954 // If not the templates might read in wrong personalized data (preferences etc.)
955 eZUser::setCurrentlyLoggedInUser( $previewCacheUser, $previewCacheUser->attribute( 'contentobject_id' ), eZUser::NO_SESSION_REGENERATE );
956
957 // Cache the current node
958 $cacheFileArray = eZNodeviewfunctions::generateViewCacheFile( $previewCacheUser, $node->attribute( 'node_id' ), false, false, $language, $viewMode, $viewParameters, $cachedViewPreferences );
959 $tmpRes = eZNodeviewfunctions::generateNodeView( $tpl, $node, $node->attribute( 'object' ), $language, $viewMode, false, $cacheFileArray['cache_dir'], $cacheFileArray['cache_path'], true, $viewParameters );
960
961 // Cache the parent node
962 $parentNode = $node->attribute( 'parent' );
963 $objectID = $parentNode->attribute( 'contentobject_id' );
964 // if parent objectID is null or is 0 we should not create cache.
965 if ( $objectID )
966 {
967 $cacheFileArray = eZNodeviewfunctions::generateViewCacheFile( $previewCacheUser, $parentNode->attribute( 'node_id' ), 0, false, $language, $viewMode, $viewParameters, $cachedViewPreferences );
968 $tmpRes = eZNodeviewfunctions::generateNodeView( $tpl, $parentNode, $parentNode->attribute( 'object' ), $language, $viewMode, 0, $cacheFileArray['cache_dir'], $cacheFileArray['cache_path'], true, $viewParameters );
969 }
970 }
971 }
972 }
973 // Restore the old user as the current one
974 eZUser::setCurrentlyLoggedInUser( $user, $user->attribute( 'contentobject_id' ), eZUser::NO_SESSION_REGENERATE );
975
976 // restore siteaccess
977 eZSiteAccess::load( $currentSiteAccess );
978 }
979 }
980
981 if ( $ini->variable( 'ContentSettings', 'StaticCache' ) == 'enabled' )
982 {
983 $nodes = array();
984 $ini = eZINI::instance();
985 $useURLAlias =& $GLOBALS['eZContentObjectTreeNodeUseURLAlias'];
986 $pathPrefix = $ini->variable( 'SiteAccessSettings', 'PathPrefix' );
987
988 // get staticCacheHandler instance
989 $optionArray = array( 'iniFile' => 'site.ini',
990 'iniSection' => 'ContentSettings',
991 'iniVariable' => 'StaticCacheHandler' );
992
993 $options = new ezpExtensionOptions( $optionArray );
994 $staticCacheHandler = eZExtension::getHandlerClass( $options );
995
996 if ( !isset( $useURLAlias ) )
997 {
998 $useURLAlias = $ini->variable( 'URLTranslator', 'Translation' ) == 'enabled';
999 }
1000
1001 eZContentCacheManager::nodeListForObject( $object, true, self::CLEAR_DEFAULT, $nodes, $handledObjectList );
1002
1003 // If no nodes returns it means that ClearCacheMethod = self::CLEAR_NO_CACHE
1004 if ( count( $nodes ) )
1005 {
1006 foreach ( $nodes as $nodeID )
1007 {
1008 if ( $useURLAlias )
1009 {
1010 $oNode = eZContentObjectTreeNode::fetch( $nodeID, false, true );
1011 if ( !isset( $oNode ) )
1012 continue;
1013
1014 $urlAlias = $oNode->urlAlias();
1015 if ( $pathPrefix != '' )
1016 {
1017 $tempAlias = substr( $pathPrefix, strlen( $pathPrefix ) -1 ) == '/'
1018 ? $urlAlias . '/'
1019 : $urlAlias;
1020 if ( strncmp( $tempAlias, $pathPrefix, strlen( $tempAlias) ) == 0 )
1021 $urlAlias = substr( $tempAlias, strlen( $pathPrefix ) );
1022 }
1023 }
1024 else
1025 {
1026 $urlAlias = 'content/view/full/' . $nodeID;
1027 }
1028 $staticCacheHandler->cacheURL( '/' . $urlAlias, $nodeID );
1029 }
1030 $staticCacheHandler->generateAlwaysUpdatedCache();
1031 }
1032 }
1033 eZDebug::accumulatorStop( 'generate_cache' );
1034 }
1035
1040 static function clearContentCacheIfNeededBySectionID( $sectionID )
1041 {
1042 // fetch all objects of this section
1043 $objectList = eZContentObject::fetchList( false, array( 'section_id' => "$sectionID" ) );
1044 // Clear cache
1045 $objectIDList = array();
1046 foreach ( $objectList as $object )
1047 {
1048 $objectIDList[] = $object['id'];
1049 }
1050 self::clearContentCacheIfNeeded( $objectIDList );
1051 return true;
1052 }
1053
1062 public static function clearContentCacheIfNeeded( $objectID, $versionNum = true, $additionalNodeList = false )
1063 {
1064 eZDebug::accumulatorStart( 'check_cache', '', 'Check cache' );
1065
1066 self::clearObjectViewCacheIfNeeded( $objectID, $versionNum, $additionalNodeList );
1067 self::clearTemplateBlockCacheIfNeeded( $objectID );
1068
1069 // Clear cached path strings of content SSL zones.
1070 eZSSLZone::clearCacheIfNeeded();
1071
1072 eZDebug::accumulatorStop( 'check_cache' );
1073 return true;
1074 }
1075
1084 static function clearContentCache( $objectID, $versionNum = true, $additionalNodeList = false )
1085 {
1086 eZDebug::accumulatorStart( 'check_cache', '', 'Check cache' );
1087
1088 if ( is_array( $objectID ) )
1089 {
1090 if ( $versionNum !== true || $additionalNodeList !== false )
1091 {
1092 trigger_error( "This method does not support second and third parameters when operating on many objects!" );
1093 return false;
1094 }
1095
1096 self::clearObjectViewCacheArray( $objectID );
1097 }
1098 else
1099 {
1100 self::clearObjectViewCache( $objectID, $versionNum, $additionalNodeList );
1101 }
1102
1103 self::clearTemplateBlockCache( $objectID );
1104
1105 // Clear cached path strings of content SSL zones.
1106 eZSSLZone::clearCache();
1107
1108 eZDebug::accumulatorStop( 'check_cache' );
1109 return true;
1110 }
1111
1116 static function clearAllContentCache( $ignoreINISettings = false )
1117 {
1118 if ( !$ignoreINISettings )
1119 {
1120 $ini = eZINI::instance();
1121 $viewCacheEnabled = ( $ini->variable( 'ContentSettings', 'ViewCaching' ) === 'enabled' );
1122 $templateCacheEnabled = ( $ini->variable( 'TemplateSettings', 'TemplateCache' ) === 'enabled' );
1123 }
1124 else
1125 {
1126 $viewCacheEnabled = true;
1127 $templateCacheEnabled = true;
1128 }
1129
1130 if ( $viewCacheEnabled || $templateCacheEnabled )
1131 {
1132 // view cache and/or ordinary template block cache
1133 eZContentObject::expireAllCache();
1134
1135 ezpEvent::getInstance()->notify( 'content/cache/all' );
1136
1137 // subtree template block caches
1138 if ( $templateCacheEnabled )
1139 {
1140 eZSubtreeCache::cleanupAll();
1141 }
1142 }
1143 }
1144 }
1145
1146 ?>
eZContentCacheManager
Figures out relations between objects, nodes and classes for cache management.
Definition: ezcontentcachemanager.php:25
eZContentCacheManager\fetchNodePathString
static fetchNodePathString( $nodeList)
Definition: ezcontentcachemanager.php:111
eZContentCacheManager\CLEAR_NODE_CACHE
const CLEAR_NODE_CACHE
Definition: ezcontentcachemanager.php:28
eZContentCacheManager\clearObjectViewCache
static clearObjectViewCache( $objectID, $versionNum=true, $additionalNodeList=false)
Definition: ezcontentcachemanager.php:676
eZContentCacheManager\clearContentCache
static clearContentCache( $objectID, $versionNum=true, $additionalNodeList=false)
Definition: ezcontentcachemanager.php:1084
eZContentCacheManager\clearContentCacheIfNeededBySectionID
static clearContentCacheIfNeededBySectionID( $sectionID)
Definition: ezcontentcachemanager.php:1040
eZContentCacheManager\CLEAR_CHILDREN_CACHE
const CLEAR_CHILDREN_CACHE
Definition: ezcontentcachemanager.php:33
eZContentCacheManager\clearAllContentCache
static clearAllContentCache( $ignoreINISettings=false)
Definition: ezcontentcachemanager.php:1116
eZContentCacheManager\clearContentCacheIfNeeded
static clearContentCacheIfNeeded( $objectID, $versionNum=true, $additionalNodeList=false)
Definition: ezcontentcachemanager.php:1062
eZContentCacheManager\CLEAR_PARENT_CACHE
const CLEAR_PARENT_CACHE
Definition: ezcontentcachemanager.php:29
eZContentCacheManager\writeDebugBits
static writeDebugBits( $handledObjectList, $highestBit)
Definition: ezcontentcachemanager.php:415
eZContentCacheManager\appendAdditionalNodeIDs
static appendAdditionalNodeIDs(eZContentObject $contentObject, &$nodeIDList)
Definition: ezcontentcachemanager.php:67
eZContentCacheManager\CLEAR_ALL_CACHE
const CLEAR_ALL_CACHE
Definition: ezcontentcachemanager.php:34
eZContentCacheManager\dependencyInfo
static dependencyInfo( $classID, $ignoreINISettings=false)
Definition: ezcontentcachemanager.php:336
eZContentCacheManager\clearTemplateBlockCache
static clearTemplateBlockCache( $objectID, $checkViewCacheClassSettings=false)
Definition: ezcontentcachemanager.php:838
eZContentCacheManager\$additionalNodeIDsPerObject
static $additionalNodeIDsPerObject
Definition: ezcontentcachemanager.php:43
eZContentCacheManager\nodeListForObject
static nodeListForObject( $contentObject, $versionNum, $clearCacheType, &$nodeList, &$handledObjectList)
Definition: ezcontentcachemanager.php:457
eZContentCacheManager\appendRelatingNodeIDs
static appendRelatingNodeIDs( $object, &$nodeIDList)
Definition: ezcontentcachemanager.php:127
eZContentCacheManager\appendKeywordNodeIDs
static appendKeywordNodeIDs( $object, $versionNum, &$nodeIDList, $limit=null)
Definition: ezcontentcachemanager.php:224
eZContentCacheManager\addAdditionalNodeIDPerObject
static addAdditionalNodeIDPerObject( $contentObjectID, $additionalNodeID)
Definition: ezcontentcachemanager.php:51
eZContentCacheManager\CLEAR_NO_CACHE
const CLEAR_NO_CACHE
Definition: ezcontentcachemanager.php:27
eZContentCacheManager\clearObjectViewCacheArray
static clearObjectViewCacheArray(array $objectIDList)
Definition: ezcontentcachemanager.php:711
eZContentCacheManager\appendNodeIDs
static appendNodeIDs( $nodeList, &$nodeIDList)
Definition: ezcontentcachemanager.php:98
eZContentCacheManager\CLEAR_SIBLINGS_CACHE
const CLEAR_SIBLINGS_CACHE
Definition: ezcontentcachemanager.php:32
eZContentCacheManager\appendSiblingsNodeIDs
static appendSiblingsNodeIDs(&$nodeList, &$nodeIDList)
Definition: ezcontentcachemanager.php:283
eZContentCacheManager\clearNodeViewCacheArray
static clearNodeViewCacheArray(array $nodeList, array|null $contentObjectList=null)
Definition: ezcontentcachemanager.php:741
eZContentCacheManager\appendParentNodeIDs
static appendParentNodeIDs( $object, $versionNum, &$nodeIDList)
Definition: ezcontentcachemanager.php:85
eZContentCacheManager\appendChildrenNodeIDs
static appendChildrenNodeIDs(&$nodeList, &$nodeIDList)
Definition: ezcontentcachemanager.php:307
eZContentCacheManager\CLEAR_DEFAULT
const CLEAR_DEFAULT
Definition: ezcontentcachemanager.php:35
eZContentCacheManager\CLEAR_RELATING_CACHE
const CLEAR_RELATING_CACHE
Definition: ezcontentcachemanager.php:30
eZContentCacheManager\CLEAR_KEYWORD_CACHE
const CLEAR_KEYWORD_CACHE
Definition: ezcontentcachemanager.php:31
eZContentCacheManager\nodeList
static nodeList( $objectID, $versionNum)
Definition: ezcontentcachemanager.php:652
eZContentCacheManager\generateObjectViewCache
static generateObjectViewCache( $objectID)
Definition: ezcontentcachemanager.php:891
eZContentCacheManager\clearTemplateBlockCacheIfNeeded
static clearTemplateBlockCacheIfNeeded( $objectID)
Definition: ezcontentcachemanager.php:823
eZContentCacheManager\clearObjectViewCacheIfNeeded
static clearObjectViewCacheIfNeeded( $objectID, $versionNum=true, $additionalNodeList=false)
Definition: ezcontentcachemanager.php:795
eZContentCache\inCleanupThresholdRange
static inCleanupThresholdRange( $value)
Definition: ezcontentcache.php:248
eZContentCache\calculateCleanupValue
static calculateCleanupValue( $nodeCount)
Definition: ezcontentcache.php:243
eZContentCache\cleanup
static cleanup( $nodeList, $userId=false)
Definition: ezcontentcache.php:255
eZContentObjectAttribute
Encapsulates the data for an object attribute.
Definition: ezcontentobjectattribute.php:20
eZContentObjectTreeNode\fetch
static fetch( $nodeID=false, $lang=false, $asObject=true, $conditions=false)
Definition: ezcontentobjecttreenode.php:3058
eZContentObjectTreeNode\subTreeByNodeID
static subTreeByNodeID( $params=false, $nodeID=0)
Definition: ezcontentobjecttreenode.php:1940
eZContentObjectTreeNode\fetchClassIdentifierListByPathString
static fetchClassIdentifierListByPathString( $nodePath, $withLastNode, $limit=false)
Definition: ezcontentobjecttreenode.php:3286
eZContentObject
Definition: ezcontentobject.php:17
eZContentObject\expireComplexViewModeCache
static expireComplexViewModeCache()
Definition: ezcontentobject.php:5975
eZContentObject\fetchIDArray
static fetchIDArray( $idArray, $asObject=true, $lang=false)
Definition: ezcontentobject.php:1132
eZContentObject\RELATION_LINK
const RELATION_LINK
Definition: ezcontentobject.php:39
eZContentObject\expireTemplateBlockCache
static expireTemplateBlockCache()
Definition: ezcontentobject.php:5962
eZContentObject\fetch
static fetch( $id, $asObject=true)
Definition: ezcontentobject.php:885
eZContentObject\fetchByNodeID
static fetchByNodeID( $nodeID, $asObject=true)
Definition: ezcontentobject.php:1072
eZContentObject\RELATION_COMMON
const RELATION_COMMON
Definition: ezcontentobject.php:37
eZContentObject\fetchList
static fetchList( $asObject=true, $conditions=null, $offset=false, $limit=false)
Definition: ezcontentobject.php:1185
eZContentObject\RELATION_ATTRIBUTE
const RELATION_ATTRIBUTE
Definition: ezcontentobject.php:40
eZContentObject\RELATION_EMBED
const RELATION_EMBED
Definition: ezcontentobject.php:38
eZContentObject\expireAllViewCache
static expireAllViewCache()
Definition: ezcontentobject.php:5932
eZContentObject\expireAllCache
static expireAllCache()
Definition: ezcontentobject.php:5947
eZDB\instance
static instance( $databaseImplementation=false, $databaseParameters=false, $forceNewInstance=false)
Definition: ezdb.php:117
eZDebugSetting\writeDebug
static writeDebug( $conditionName, $string, $label="")
Definition: ezdebugsetting.php:127
eZDebug\writeDebug
static writeDebug( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:588
eZDebug\accumulatorStart
static accumulatorStart( $key, $inGroup=false, $name=false, $recursive=false)
Definition: ezdebug.php:1361
eZDebug\accumulatorStop
static accumulatorStop( $key, $recursive=false)
Definition: ezdebug.php:1389
eZExtension\getHandlerClass
static getHandlerClass(ezpExtensionOptions $options)
Definition: ezextension.php:531
eZKeyword
A content datatype which handles keyword index instances.
Definition: ezkeyword.php:19
eZNodeviewfunctions\generateViewCacheFile
static generateViewCacheFile( $user, $nodeID, $offset, $layout, $language, $viewMode, $viewParameters=false, $cachedViewPreferences=false, $viewCacheTweak='')
Definition: eznodeviewfunctions.php:280
eZNodeviewfunctions\generateNodeView
static generateNodeView( $tpl, $node, $object, $languageCode, $viewMode, $offset, $cacheDir, $cachePath, $viewCacheEnabled, $viewParameters=array( 'offset'=> 0, 'year'=> false, 'month'=> false, 'day'=> false), $collectionAttributes=false, $validation=false)
Definition: eznodeviewfunctions.php:20
eZPersistentObject\attribute
attribute( $attr, $noFunction=false)
Definition: ezpersistentobject.php:1329
eZSiteAccess\load
static load(array $access, ?eZINI $siteINI=null)
Definition: ezsiteaccess.php:585
eZSubtreeCache\cleanupAll
static cleanupAll()
Definition: ezsubtreecache.php:75
eZSubtreeCache\cleanup
static cleanup(&$nodeList)
Definition: ezsubtreecache.php:50
eZTemplate\factory
static factory()
Definition: eztemplate.php:2380
eZUser\NO_SESSION_REGENERATE
const NO_SESSION_REGENERATE
Definition: ezuser.php:63
eZUser\setCurrentlyLoggedInUser
static setCurrentlyLoggedInUser( $user, $userID, $flags=0)
Definition: ezuser.php:1054
eZUser\fetch
static fetch( $id, $asObject=true)
Definition: ezuser.php:351
eZUser\currentUser
static currentUser()
Definition: ezuser.php:1716
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.