Exponential 6.0.13 Exponential Enterprise Open Source CMS - PHP Class Reference

ezextension.php
Go to the documentation of this file.
1 <?php
17 class eZExtension
18 {
24 const CACHE_DIR = 'var/cache/';
25
31 protected static $activeExtensionsCache = array();
32
39 static function baseDirectory( eZINI|null $siteINI = null )
40 {
41 if ( $siteINI === null )
42 $siteINI = eZINI::instance();
43 $extensionDirectory = $siteINI->variable( 'ExtensionSettings', 'ExtensionDirectory' );
44 return $extensionDirectory;
45 }
46
60 public static function activeExtensions( $extensionType = false, eZINI|null $siteINI = null )
61 {
62 if ( $siteINI === null )
63 {
64 $siteINI = eZINI::instance();
65 }
66
67 $activeExtensions = array();
68 if ( !$extensionType || $extensionType === 'default' )
69 {
70 $activeExtensions = $siteINI->variable( 'ExtensionSettings', 'ActiveExtensions' );
71 }
72
73 if ( !$extensionType || $extensionType === 'access' )
74 {
75 $activeExtensions = array_merge( $activeExtensions,
76 $siteINI->variable( 'ExtensionSettings', 'ActiveAccessExtensions' ) );
77 }
78
79 if ( isset( $GLOBALS['eZActiveExtensions'] ) )
80 {
81 $activeExtensions = array_merge( $activeExtensions,
82 $GLOBALS['eZActiveExtensions'] );
83 }
84
85 // return empty array as is to avoid further unneeded overhead
86 if ( !isset( $activeExtensions[0] ) )
87 {
88 return $activeExtensions;
89 }
90
91 // return array as is if ordering is disabled to avoid cache overhead
92 $activeExtensions = array_unique( $activeExtensions );
93 if ( $siteINI->variable( 'ExtensionSettings', 'ExtensionOrdering' ) !== 'enabled' )
94 {
95 // @todo Introduce a debug setting or re use existing dev mods to check that all extensions exists
96 return $activeExtensions;
97 }
98
99 $cacheIdentifier = md5( serialize( $activeExtensions ) );
100 if ( isset ( self::$activeExtensionsCache[$cacheIdentifier] ) )
101 {
102 return self::$activeExtensionsCache[$cacheIdentifier];
103 }
104
105 // cache has to be stored by siteaccess + $extensionType
106 $extensionDirectory = self::baseDirectory();
107 $expiryHandler = eZExpiryHandler::instance();
108 $phpCache = new eZPHPCreator( self::CACHE_DIR, "active_extensions_{$cacheIdentifier}.php" );
109 $expiryTime = $expiryHandler->hasTimestamp( 'active-extensions-cache' ) ? $expiryHandler->timestamp( 'active-extensions-cache' ) : 0;
110
111 if ( !$phpCache->canRestore( $expiryTime ) )
112 {
113 self::$activeExtensionsCache[$cacheIdentifier] = self::extensionOrdering( $activeExtensions );
114
115 // Check that all extensions defined actually exists before storing cache
116 foreach ( self::$activeExtensionsCache[$cacheIdentifier] as $activeExtension )
117 {
118 if ( !file_exists( $extensionDirectory . '/' . $activeExtension ) )
119 {
120 eZDebug::writeError( "Extension '$activeExtension' does not exist, looked for directory '" . $extensionDirectory . '/' . $activeExtension . "'", __METHOD__ );
121 }
122 }
123
124 $phpCache->addVariable( 'activeExtensions', self::$activeExtensionsCache[$cacheIdentifier] );
125 $phpCache->store( true );
126 }
127 else
128 {
129 $data = $phpCache->restore( array( 'activeExtensions' => 'activeExtensions' ) );
130 self::$activeExtensionsCache[$cacheIdentifier] = $data['activeExtensions'];
131 }
132
133 return self::$activeExtensionsCache[$cacheIdentifier];
134 }
135
143 public static function extensionOrdering( array $activeExtensions )
144 {
145 $activeExtensionsSet = array_flip( $activeExtensions );
146
147 $dependencies = array();
148 foreach ( $activeExtensions as $extension )
149 {
150 $loadingOrderData = ezpExtension::getInstance( $extension )->getLoadingOrder();
151
152 // The extension should appear even without dependencies to be taken into account
153 if ( ! isset( $dependencies[$extension] ) )
154 $dependencies[$extension] = array();
155
156 if ( isset( $loadingOrderData['after'] ) )
157 {
158 foreach ( $loadingOrderData['after'] as $dependency )
159 {
160 if ( isset( $activeExtensionsSet[$dependency] ) )
161 $dependencies[$extension][] = $dependency;
162 }
163 }
164 if ( isset( $loadingOrderData['before'] ) )
165 {
166 foreach ( $loadingOrderData['before'] as $dependency )
167 {
168 if ( isset( $activeExtensionsSet[$dependency] ) )
169 $dependencies[$dependency][] = $extension;
170 }
171 }
172 }
173
174 $topologySort = new ezpTopologicalSort( $dependencies );
175 $activeExtensionsSorted = $topologySort->sort();
176
177 return $activeExtensionsSorted !== false ? $activeExtensionsSorted : $activeExtensions;
178 }
179
187 static function activateExtensions( $extensionType = 'default', ?eZINI $siteINI = null )
188 {
189 if ( $siteINI === null )
190 {
191 $siteINI = eZINI::instance();
192 }
193
194 if ( $extensionType === false )
195 {
196 eZDebug::writeStrict( "Setting parameter \$extensionType to false is deprecated as of 4.4, see doc/bc/4.4!", __METHOD__ );
197 }
198
199 $extensionDirectory = self::baseDirectory();
200 $activeExtensions = self::activeExtensions( $extensionType, $siteINI );
201 $hasExtensions = false;
202 foreach ( $activeExtensions as $activeExtension )
203 {
204 $extensionSettingsPath = $extensionDirectory . '/' . $activeExtension . '/settings';
205
206 if ( $extensionType === 'access' )
207 $siteINI->prependOverrideDir( $extensionSettingsPath, true, 'extension:' . $activeExtension, 'sa-extension' );
208 else
209 $siteINI->prependOverrideDir( $extensionSettingsPath, true, 'extension:' . $activeExtension, 'extension' );
210
211 if ( isset( $GLOBALS['eZCurrentAccess'] ) )
212 self::prependSiteAccess( $activeExtension, $GLOBALS['eZCurrentAccess']['name'], $siteINI );
213
214 $hasExtensions = true;
215 }
216 if ( $hasExtensions )
217 $siteINI->load();
218 }
219
229 static function prependExtensionSiteAccesses( $accessName = false, $ini = false, $globalDir = true, $identifier = null, $order = true )
230 {
231 $extensionList = eZExtension::activeExtensions( 'default' );
232
233 if ( !$order )
234 {
235 $extensionList = array_reverse( $extensionList );
236 }
237
238 foreach( $extensionList as $extension )
239 {
240 self::prependSiteAccess( $extension, $accessName, $ini, $globalDir, $identifier );
241 }
242 }
243
255 static function prependSiteAccess( $extension, $accessName = false, $ini = false, $globalDir = true, $identifier = null )
256 {
257 if ( !$accessName )
258 {
259 $accessName = $GLOBALS['eZCurrentAccess']['name'];
260 }
261
262 $extensionSettingsPath = eZExtension::baseDirectory() . '/' . $extension;
263
264 if ( $identifier === null )
265 {
266 $identifier = "ext-siteaccess:$extension";
267 }
268
269 if ( !$ini instanceof eZINI )
270 {
271 $ini = eZINI::instance();
272 }
273
274 // ### EXP-MULTI-SITE-OVERRIDE-SETTINGS ###
275 // we need file_exists because we have several site_extensions with override folders
276 // this folder is only active if a siteaccess from extension is loaded
277 // disadvantage file_exists calls on every page request => but seems to be faster then to check an array of siteaccess = extension info
278 // may be its php5.3
279 if ( file_exists ( $extensionSettingsPath . '/settings/siteaccess/' . $accessName ) )
280 {
281 // define new ini location which is enabled if a extension siteaccess is active - overrides extension siteaccess settings
282 // extension/$ext_name/settings/override/ *.ini.append.php
283 $ini->prependOverrideDir( $extensionSettingsPath . '/settings/override/' , $globalDir, 'ext-siteaccess-override:'.$extension , 'siteaccess');
284
285 // settings/siteacces/ siteAccessGroupName__sprache
286 // extension/$ext_name/settings/override_$siteAccessGroupName/ *.ini.append.php
287 $siteAccessNameExplodeArray = explode( '__', $accessName );
288 if( count( $siteAccessNameExplodeArray ) > 1 )
289 {
290 $siteAccessGroupName = $siteAccessNameExplodeArray[0];
291 // extension/$ext_name/settings/override__ $sa_group_name / *.ini.append.php
292 $ini->prependOverrideDir( $extensionSettingsPath . '/settings/override__' . $siteAccessGroupName , $globalDir, 'ext-siteaccess-override:'.$extension.':__group:'.$siteAccessGroupName, 'siteaccess' );
293 }
294
295 // extension/$ext_name/settings/siteaccess/$siteaccess_name/ *.ini.append.php
296 $ini->prependOverrideDir( $extensionSettingsPath . '/settings/siteaccess/' . $accessName, $globalDir, $identifier, 'siteaccess' );
297
298 if( defined( 'EXP_SITE_STRUCTURE_EZ_INI_OVERRIDE_DIR_LIST' ) &&
299 EXP_SITE_STRUCTURE_EZ_INI_OVERRIDE_DIR_LIST === true )
300 {
301 $eZINIOverrideDirListOriginal = $ini->overrideDirs( 'extension' );
302 $eZINIOverrideDirList = array();
303
304 // delete all other site extenions from override list to minimize file_exists calls eZINI::findeInputFiles
305 foreach( $eZINIOverrideDirListOriginal as $key => $overrideLocation )
306 {
307 // if location beginning with extension/site_ => it is a site extension
308 if( strpos( $overrideLocation[0], 'extension/site_' ) === 0 &&
309 strpos( $overrideLocation[0], $extensionSettingsPath.'/' ) !== 0 )
310 // if location beginning with extension/site_projectname/ => it is the current site extension
311 {
312 // ignore other site_extension than current
313 }
314 else
315 {
316 $eZINIOverrideDirList[$key] = $overrideLocation;
317 }
318 }
319
320 // set manipulated override array in scope 'extension'
321 $ini->setOverrideDirs( $eZINIOverrideDirList, 'extension' );
322 }
323 }
324
325 //$ini->prependOverrideDir( $extensionSettingsPath . '/settings/siteaccess/' . $accessName, $globalDir, $identifier, 'siteaccess' );
326 }
327
334 static function expandedPathList( $extensionList, $subdirectory = false )
335 {
336 $pathList = array();
337 $extensionBase = eZExtension::baseDirectory();
338 foreach ( $extensionList as $extensionName )
339 {
340 $path = $extensionBase . '/' . $extensionName;
341 if ( $subdirectory )
342 $path .= '/' . $subdirectory;
343 $pathList[] = $path;
344 }
345 return $pathList;
346 }
347
385 static function findExtensionType( $parameters, &$out )
386 {
387 $iniName = $parameters['ini-name'];
388 $repositoryGroup = $parameters['repository-group'];
389 $repositoryVariable = $parameters['repository-variable'];
390 $extensionGroup = $parameters['extension-group'];
391 $extensionVariable = $parameters['extension-variable'];
392 $subdir = false;
393 if ( isset( $parameters['subdir'] ) )
394 $subdir = $parameters['subdir'];
395 $extensionSubdir = false;
396 if ( isset( $parameters['extension-subdir'] ) )
397 $extensionSubdir = $parameters['extension-subdir'];
398 $typeDirectory = true;
399 if ( isset( $parameters['type-directory'] ) )
400 $typeDirectory = $parameters['type-directory'];
401 $suffixName = $parameters['suffix-name'];
402 $ini = eZINI::instance( $iniName );
403 if ( isset( $parameters['type'] ) )
404 $originalType = $parameters['type'];
405 else if ( isset( $parameters['type-group'] ) and
406 isset( $parameters['type-variable'] ) )
407 $originalType = $ini->variable( $parameters['type-group'], $parameters['type-variable'] );
408 else
409 return false;
410 $type = $originalType;
411 if ( isset( $parameters['alias-group'] ) and
412 isset( $parameters['alias-variable'] ) )
413 {
414 if ( $ini->hasVariable( $parameters['alias-group'], $parameters['alias-variable'] ) )
415 {
416 $aliasMap = $ini->variable( $parameters['alias-group'], $parameters['alias-variable'] );
417 if ( isset( $aliasMap[$type] ) )
418 $type = $aliasMap[$type];
419 }
420 }
421
422 $baseDirectory = eZExtension::baseDirectory();
423 $repositoryDirectoryList = array();
424 $repositoryList = $ini->variable( $repositoryGroup, $repositoryVariable );
425 $extensionDirectories = $ini->variable( $extensionGroup, $extensionVariable );
426 foreach ( $repositoryList as $repository )
427 {
428 $repositoryDirectory = $repository;
429 if ( $subdir != '' )
430 $repositoryDirectory .= '/' . $subdir;
431 $repositoryDirectoryList[] = $repositoryDirectory;
432 }
433 foreach ( $extensionDirectories as $extensionDirectory )
434 {
435 $extensionPath = $baseDirectory . '/' . $extensionDirectory;
436 if ( $extensionSubdir != '' )
437 $extensionPath .= '/' . $extensionSubdir;
438 if ( file_exists( $extensionPath ) )
439 {
440 $repositoryDirectoryList[] = $extensionPath;
441 }
442 else if ( $extensionSubdir )
443 {
444 eZDebug::writeWarning( "Extension '$extensionDirectory' does not have the subdirectory $extensionSubdir, looked for directory '" . $extensionPath . "'" );
445 }
446 }
447 $foundType = false;
448 foreach ( $repositoryDirectoryList as $repositoryDirectory )
449 {
450 $fileDir = $repositoryDirectory;
451 if ( $typeDirectory )
452 $fileDir .= "/$type";
453 $fileName = $type . $suffixName;
454 $filePath = $fileDir . '/' . $fileName;
455 if ( file_exists( $filePath ) )
456 {
457 $foundType = true;
458 break;
459 }
460 }
461 $out['repository-directory-list'] = $repositoryDirectoryList;
462 if ( $foundType )
463 {
464 $out['type'] = $type;
465 $out['original-type'] = $originalType;
466 $out['found-file-dir'] = $fileDir;
467 $out['found-file-path'] = $filePath;
468 $out['found-file-name'] = $fileName;
469 }
470 $out['found-type'] = $foundType;
471 return $foundType;
472 }
473
484 static function extensionInfo( $extension )
485 {
486 return ezpExtension::getInstance( $extension )->getInfo();
487 }
488
496 static function nameFromPath( $path )
497 {
498 $path = eZDir::cleanPath( $path );
499 $base = eZExtension::baseDirectory() . '/';
500 $base = preg_quote( $base, '/' );
501 $pattern = '/'.$base.'([^\/]+)/';
502 if ( preg_match( $pattern, $path, $matches ) )
503 return $matches[1];
504 else
505 false;
506 }
507
514 static function isExtension( $path )
515 {
516 if ( eZExtension::nameFromPath( $path ) )
517 return true;
518 else
519 return false;
520 }
521
531 public static function getHandlerClass( ezpExtensionOptions $options )
532 {
533 $iniFile = $options->iniFile;
534 $iniSection = $options->iniSection;
535 $iniVariable = $options->iniVariable;
536 $handlerIndex = $options->handlerIndex;
537 $callMethod = $options->callMethod;
538 $handlerParams = $options->handlerParams;
539 $aliasSection = $options->aliasSection;
540 $aliasVariable = $options->aliasVariable;
541 $aliasOptionalIndex = $options->aliasOptionalIndex;
542
543 $ini = eZINI::instance( $iniFile );
544
545 if ( !$ini->hasVariable( $iniSection, $iniVariable ) )
546 {
547 eZDebug::writeError( 'Unable to find variable ' . $iniVariable . ' in section ' . $iniSection . ' in file ' . $iniFile, __METHOD__ );
548 return null;
549 }
550
551 $handlers = $ini->variable( $iniSection, $iniVariable );
552
553 if ( $handlerIndex !== null )
554 {
555 if ( is_array( $handlers ) && isset( $handlers[ $handlerIndex ] ) )
556 $handlers = $handlers[ $handlerIndex ];
557 else
558 return null;
559 }
560
561 // prepend alias settings if defined
562 if ( $aliasVariable !== null && is_string( $handlers ) )
563 {
564 if ( $aliasSection === null )
565 {
566 $aliasSection = $iniSection;
567 }
568 $aliasHandlers = $ini->variable( $aliasSection, $aliasVariable );
569 if ( $aliasOptionalIndex !== null && isset( $aliasHandlers[ $aliasOptionalIndex ] ) )
570 {
571 $handlers = array( $aliasHandlers[ $aliasOptionalIndex ], $handlers );
572 }
573 else if ( isset( $aliasHandlers[ $handlers ] ) )
574 {
575 $handlers = array( $aliasHandlers[ $handlers ], $handlers );
576 }
577 else
578 {
579 $handlers = array( $handlers );
580 }
581 }
582 else if ( !is_array( $handlers ) )
583 {
584 $handlers = array( $handlers );
585 }
586
587 foreach( $handlers as $handler )
588 {
589 // we rely on the autoload system here
590 if ( class_exists( $handler ) )
591 {
592 // only use reflection if we have params to avoid exception on objects without constructor
593 if ( $handlerParams !== null && is_array( $handlerParams ) && count( $handlerParams ) > 0 )
594 {
595 $reflection = new ReflectionClass( $handler );
596 // detect if class has a constructor, and if not write a notice about that
597 if ( $reflection->getConstructor() !== null )
598 {
599 $handlerParams = array_values( $handlerParams );
600 $object = $reflection->newInstanceArgs( $handlerParams );
601 }
602 else
603 {
604 eZDebug::writeNotice( 'Constructor is missing but parameters are provided to class ' . $handler . " as defined in setting $iniFile [$iniSection] $iniVariable", __METHOD__ );
605 $object = new $handler();
606 }
607 }
608 else
609 {
610 $object = new $handler();
611 }
612 // if callMethod is set, then call it so handler can decide if it is a valid handler
613 if ( $callMethod !== null )
614 {
615 if ( !is_callable( array( $object, $callMethod ) ) )
616 {
617 eZDebug::writeNotice( 'Method ' . $callMethod . ' is not callable on class ' . $handler . " as defined in setting $iniFile [$iniSection] $iniVariable", __METHOD__ );
618 continue;
619 }
620
621 if ( !call_user_func(array( $object, $callMethod ) ) )
622 continue;
623 }
624 return $object;
625 }
626 else
627 {
628 eZDebug::writeError( "Class '$handler' as defined in setting $iniFile [$iniSection] $iniVariable could not be autoloaded. Did you remember to run bin/php/ezpgenerateautoloads.php after you added extension(s)?", __METHOD__ );
629 }
630 }
631
632 return false;
633 }
634
639 public static function clearActiveExtensionsMemoryCache()
640 {
641 self::$activeExtensionsCache = array();
642 }
643
648 public static function clearActiveExtensionsCache()
649 {
650 $filesList = glob( self::CACHE_DIR . 'active_extensions_*.php' );
651 foreach ( $filesList as $path )
652 {
653 if ( is_file( $path ) )
654 {
655 $handler = eZFileHandler::instance( false );
656 $handler->unlink( $path );
657 }
658 }
659 }
660 }
661
662 ?>
eZDebug\writeStrict
static writeStrict( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:414
eZDebug\writeError
static writeError( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:545
eZDebug\writeNotice
static writeNotice( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:459
eZDebug\writeWarning
static writeWarning( $string, $label="", $backgroundClass="")
Definition: ezdebug.php:502
eZDir\cleanPath
static cleanPath( $path, $toType=self::SEPARATOR_UNIX)
Definition: ezdir.php:202
eZExtension
The class eZExtension does.
Definition: ezextension.php:18
eZExtension\expandedPathList
static expandedPathList( $extensionList, $subdirectory=false)
Definition: ezextension.php:334
eZExtension\prependSiteAccess
static prependSiteAccess( $extension, $accessName=false, $ini=false, $globalDir=true, $identifier=null)
Definition: ezextension.php:255
eZExtension\clearActiveExtensionsMemoryCache
static clearActiveExtensionsMemoryCache()
Definition: ezextension.php:639
eZExtension\isExtension
static isExtension( $path)
Definition: ezextension.php:514
eZExtension\extensionInfo
static extensionInfo( $extension)
Definition: ezextension.php:484
eZExtension\nameFromPath
static nameFromPath( $path)
Definition: ezextension.php:496
eZExtension\findExtensionType
static findExtensionType( $parameters, &$out)
Definition: ezextension.php:385
eZExtension\$activeExtensionsCache
static $activeExtensionsCache
Definition: ezextension.php:31
eZExtension\extensionOrdering
static extensionOrdering(array $activeExtensions)
Definition: ezextension.php:143
eZExtension\activateExtensions
static activateExtensions( $extensionType='default', ?eZINI $siteINI=null)
Definition: ezextension.php:187
eZExtension\activeExtensions
static activeExtensions( $extensionType=false, eZINI|null $siteINI=null)
Definition: ezextension.php:60
eZExtension\CACHE_DIR
const CACHE_DIR
Definition: ezextension.php:24
eZExtension\baseDirectory
static baseDirectory(eZINI|null $siteINI=null)
Definition: ezextension.php:39
eZExtension\getHandlerClass
static getHandlerClass(ezpExtensionOptions $options)
Definition: ezextension.php:531
eZExtension\prependExtensionSiteAccesses
static prependExtensionSiteAccesses( $accessName=false, $ini=false, $globalDir=true, $identifier=null, $order=true)
Definition: ezextension.php:229
eZExtension\clearActiveExtensionsCache
static clearActiveExtensionsCache()
Definition: ezextension.php:648
eZFileHandler\instance
static instance( $identifier, $filename=false, $mode=false, $binaryFile=true)
Definition: ezfilehandler.php:1017
eZINI
Reads and writes .ini style configuration files.
eZPHPCreator
eZPHPCreator provides a simple interface for creating and executing PHP code.
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.