Public Access
feat: nested Joomla package support in release_package.php #323
+79
-1
@@ -270,12 +270,90 @@ class ReleasePackageCli extends CliFramework
|
||||
}
|
||||
}
|
||||
|
||||
// Check if sub-source is itself a Joomla package (nested package)
|
||||
$nestedPkgManifests = glob("{$subSourceDir}/pkg_*.xml") ?: [];
|
||||
$isNestedPackage = !empty($nestedPkgManifests) && is_dir("{$subSourceDir}/packages");
|
||||
|
||||
$subZip = new \ZipArchive();
|
||||
if ($subZip->open($subZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
||||
$this->log('ERROR', "Failed to create sub-package ZIP: {$subZipPath}");
|
||||
continue;
|
||||
}
|
||||
$this->addDirToZip($subZip, $subSourceDir, '', $this->excludePatterns);
|
||||
|
||||
if ($isNestedPackage) {
|
||||
// Build nested package: zip each sub-extension, then assemble
|
||||
echo " Building nested package: {$subName}\n";
|
||||
$nestedPkgDirs = glob("{$subSourceDir}/packages/*", GLOB_ONLYDIR) ?: [];
|
||||
|
||||
$nestedManifested = [];
|
||||
foreach ($nestedPkgManifests as $npmf) {
|
||||
$npmXml = @simplexml_load_file($npmf);
|
||||
if ($npmXml && isset($npmXml->files)) {
|
||||
foreach ($npmXml->files->file as $fn) {
|
||||
$nzn = pathinfo((string) $fn, PATHINFO_FILENAME);
|
||||
if (!empty($nzn)) {
|
||||
$nestedManifested[$nzn] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a subdirectory to avoid filename collisions with outer ZIPs
|
||||
$nestedOutputDir = "{$outputDir}/nested_{$subName}";
|
||||
@mkdir($nestedOutputDir, 0755, true);
|
||||
|
||||
foreach ($nestedPkgDirs as $npd) {
|
||||
$nestedSubName = basename($npd);
|
||||
if (!empty($nestedManifested) && !isset($nestedManifested[$nestedSubName])) {
|
||||
continue;
|
||||
}
|
||||
$nestedSubZipPath = "{$nestedOutputDir}/{$nestedSubName}.zip";
|
||||
$nsZip = new \ZipArchive();
|
||||
if ($nsZip->open($nestedSubZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
||||
continue;
|
||||
}
|
||||
$this->addDirToZip($nsZip, $npd, '', $this->excludePatterns);
|
||||
$nsZip->close();
|
||||
$subZip->addFile($nestedSubZipPath, "packages/{$nestedSubName}.zip");
|
||||
echo " Nested sub: {$nestedSubName}.zip\n";
|
||||
}
|
||||
|
||||
// Patch nested manifest: ensure folder="packages" so Joomla finds sub-ZIPs
|
||||
foreach ($nestedPkgManifests as $npmf) {
|
||||
$npmContent = file_get_contents($npmf);
|
||||
if ($npmContent !== false
|
||||
&& strpos($npmContent, '<files>') !== false
|
||||
&& strpos($npmContent, 'folder="packages"') === false
|
||||
) {
|
||||
$npmContent = str_replace('<files>', '<files folder="packages">', $npmContent);
|
||||
file_put_contents($npmf, $npmContent);
|
||||
echo " Fixed: added folder=\"packages\" to " . basename($npmf) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Add top-level files (manifest, script, etc.) with exclude filter
|
||||
$nestedTopFiles = array_merge(
|
||||
glob("{$subSourceDir}/*.xml") ?: [],
|
||||
glob("{$subSourceDir}/*.php") ?: []
|
||||
);
|
||||
foreach ($nestedTopFiles as $ntf) {
|
||||
if (!$this->isExcluded(basename($ntf), $this->excludePatterns)) {
|
||||
$subZip->addFile($ntf, basename($ntf));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all top-level directories except packages/
|
||||
$nestedTopDirs = glob("{$subSourceDir}/*", GLOB_ONLYDIR) ?: [];
|
||||
foreach ($nestedTopDirs as $ntd) {
|
||||
$ndName = basename($ntd);
|
||||
if ($ndName === 'packages') {
|
||||
continue;
|
||||
}
|
||||
$this->addDirToZip($subZip, $ntd, $ndName, $this->excludePatterns);
|
||||
}
|
||||
} else {
|
||||
$this->addDirToZip($subZip, $subSourceDir, '', $this->excludePatterns);
|
||||
}
|
||||
$subZip->close();
|
||||
|
||||
$zip->addFile($subZipPath, "packages/{$subName}.zip");
|
||||
|
||||
Reference in New Issue
Block a user