TODO
Embedding and Integration
See the Embedding Development Roadmap. Next on the list are:
- polishing and committing the embed/ module (user synchronization)
Other
GalleryCoreApi::requireOnce
- We found out that the "10x faster" claim for our $loaded[$file] require_once wrapper cannot be reproduced
- An interesting approach would be to just change the include_path right at the beginning in GalleryInitFirstPass and add the gallery2 directory and gallery2/plugins to the include path. Then, we could use a plain require_once instead of GalleryCoreApi::requireOnce (about 15% faster)
- But the include_path can only be changed with ini_set (and since 4.3.0 with a dedicated function), so if we can't change the include_path successfully, we still need our GalleryCoreApi::requireOnce wrapper and this is the greatest common denominator. We need to support this case
- So we're back to using GalleryCoreApi::requireOnce and in this function, we'd like to use require_once directly if the include_path has been changed and our old mechanism with getPluginDir etc if the include path wasn't changed
- The "has the include path been changed" check should be as cheap as a if ($staticVar) check, since we're talking about a highly optimized function (maybe check the performance difference between GDC::containsKey)
- A static var would be bad for testability (unless we use another parameter to set/reset this var)
- If possible, we don't want to add an additional parameter to requireOnce to set/reset this static var
- In GalleryInitFirstPass, we'd have to first change the include_path and then requireOnce all the files (unless we use a GDC var which we can reset)
- don't forget about embedded G2, where we need to add the gallery2 folder to the include path and can't just replace the include_path
- In the end, we'll have to see if the resulting function would be faster than this optimized version (since all the checks etc would render it a little slower):
function requireOnce($file, $skipBaseDirectoryDetection=false) {
static $loaded, $galleryBaseDir;
if (strpos($file, '..') !== false) {
return;
}
if (!isset($loaded[$file])) {
if ($skipBaseDirectoryDetection || !strncmp($file, 'lib', 3)) {
if (empty($galleryBaseDir)) {
$galleryBaseDir = GALLERY_CONFIG_DIR . '/';
}
require_once($galleryBaseDir . $file);
} else {
if (!preg_match('/^(module|theme)s\/(.+)\/.+/iU', $file, $pluginData)) {
print('Invalid path: ' . $file);
return;
}
require_once(GalleryCoreApi::getPluginBaseDir($pluginData[1], $pluginData[2]) . $file);
}
$loaded[$file] = 1;
}
}
A prototype of setting / checking include_path:
In init.inc GalleryInitFirstpass:
/* Add the plugins dir to the include path */
$includePath = @ini_get('include_path');
if (substr($includePath, -1) != PATH_SEPARATOR) {
$includePath .= PATH_SEPARATOR;
}
$includePath .= GALLERY_CONFIG_DIR . PATH_SEPARATOR .
GALLERY_CONFIG_DIR . DIRECTORY_SEPARATOR . 'plugins';
@ini_set('include_path', $includePath);
In requireOnce before the if (isset($loaded[$file])) { check:
if (!empty($includePathChanged)) {
return require_once($file);
} else if (!isset($includePathChanged)) {
global $gallery;
if (strpos(@ini_get('include_path'),
PATH_SEPARATOR . GALLERY_CONFIG_DIR === false)) {
$includePathChanged = false;
} else {
$includePathChanged = true;
}
}
Issues:
- static var -> can't test both cases
- performance not yet compared with optimized requireOnce and pure require_once, but the improvement would be very small anyway
Bottom line:
- The approach with changing include_path would have been very elegant and the performance would have been improved (by maybe 50 micro seconds * nr of files includes per request)
- But since we must deal with hosts that can't change the include_path during runtime, we can't call require_once directly and we need to check on each require_once call whether to use require_once directly or our low-tech method. We will see if it's worth it.
- see http://gallery.pastebin.com/459591