@@ -358,6 +358,218 @@ jobs:
358358 Get-ChildItem -Path $target -Filter *.zip | Remove-Item -Force
359359 Write-Host "✅ Cleanup completed for PHP $phpVersion ($tsMode)" -ForegroundColor Green
360360
361+ - name : 🔥 Download and process additional extensions
362+ shell : pwsh
363+ run : |
364+ $ErrorActionPreference = 'Continue'
365+ $target = "${{ steps.toolset.outputs.target }}"
366+ $phpVersion = "${{ matrix.php }}"
367+ $tsMode = "${{ matrix.ts }}".ToLower()
368+ $tool = "${{ steps.toolset.outputs.tool }}"
369+
370+ Write-Host ""
371+ Write-Host "🔥 Processing additional extensions for PHP $phpVersion ($($tsMode.ToUpper()))" -ForegroundColor Cyan
372+ Write-Host "=================================================================" -ForegroundColor Cyan
373+
374+ # Create ext and 3rd-party directories if they don't exist
375+ $extDir = Join-Path $target "ext"
376+ $thirdPartyDir = Join-Path $target "3rd-party"
377+
378+ if (-not (Test-Path $extDir)) {
379+ New-Item -ItemType Directory -Path $extDir -Force | Out-Null
380+ Write-Host "📁 Created ext directory" -ForegroundColor Green
381+ }
382+
383+ if (-not (Test-Path $thirdPartyDir)) {
384+ New-Item -ItemType Directory -Path $thirdPartyDir -Force | Out-Null
385+ Write-Host "📁 Created 3rd-party directory" -ForegroundColor Green
386+ }
387+
388+ # Define extension configurations
389+ $extensionConfigs = @{
390+ "blackfire" = @{
391+ "name" = "Blackfire"
392+ "urls" = @{
393+ "7.2" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/72"
394+ "7.3" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/73"
395+ "7.4" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/74"
396+ "8.0" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/80"
397+ "8.1" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/81"
398+ "8.2" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/82"
399+ "8.3" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/83"
400+ "8.4" = "https://blackfire.io/api/v1/releases/probe/php/windows/amd64/84"
401+ }
402+ "dll_name" = "blackfire_php.dll"
403+ "target_name" = "php_blackfire.dll"
404+ }
405+ "ioncube" = @{
406+ "name" = "Ioncube"
407+ "urls" = @{
408+ "7.2" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc15_x86-64.zip"
409+ "7.3" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc15_x86-64.zip"
410+ "7.4" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc15_x86-64.zip"
411+ "8.1" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc16_x86-64.zip"
412+ "8.2" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc16_x86-64.zip"
413+ "8.3" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc16_x86-64.zip"
414+ "8.4" = "https://downloads.ioncube.com/loader_downloads/ioncube_loaders_win_nonts_vc17_x86-64.zip"
415+ }
416+ "dll_name" = "ioncube_loader_win_$phpVersion.dll"
417+ "target_name" = "php_ioncube.dll"
418+ }
419+ "firebird" = @{
420+ "name" = "Firebird"
421+ "urls" = @{
422+ "7.3" = "https://github.com/FirebirdSQL/firebird/releases/download/v3.0.13/Firebird-3.0.13.33818-0-x64.zip"
423+ "7.4" = "https://github.com/FirebirdSQL/firebird/releases/download/v3.0.13/Firebird-3.0.13.33818-0-x64.zip"
424+ "8.0" = "https://github.com/FirebirdSQL/firebird/releases/download/v4.0.6/Firebird-4.0.6.3221-0-x64.zip"
425+ "8.1" = "https://github.com/FirebirdSQL/firebird/releases/download/v4.0.6/Firebird-4.0.6.3221-0-x64.zip"
426+ "8.2" = "https://github.com/FirebirdSQL/firebird/releases/download/v4.0.6/Firebird-4.0.6.3221-0-x64.zip"
427+ "8.3" = "https://github.com/FirebirdSQL/firebird/releases/download/v4.0.6/Firebird-4.0.6.3221-0-x64.zip"
428+ "8.4" = "https://github.com/FirebirdSQL/firebird/releases/download/v4.0.6/Firebird-4.0.6.3221-0-x64.zip"
429+ }
430+ "dll_name" = "fbclient.dll"
431+ "target_name" = "fbclient.dll"
432+ "target_location" = "root" # Special flag for root directory
433+ }
434+ }
435+
436+ $successCount = 0
437+ $failCount = 0
438+
439+ foreach ($extKey in $extensionConfigs.Keys) {
440+ $config = $extensionConfigs[$extKey]
441+ $extName = $config.name
442+
443+ Write-Host ""
444+ Write-Host "🔥 Processing $extName extension..." -ForegroundColor Yellow
445+
446+ # Check if URL exists for this PHP version
447+ if (-not $config.urls.ContainsKey($phpVersion)) {
448+ Write-Host "⚠️ Skipping $extName: No URL configured for PHP $phpVersion" -ForegroundColor Yellow
449+ continue
450+ }
451+
452+ # Skip Ioncube for TS mode (only NTS supported)
453+ if ($extKey -eq "ioncube" -and $tsMode -eq "ts") {
454+ Write-Host "⚠️ Skipping $extName: Only NTS mode supported" -ForegroundColor Yellow
455+ continue
456+ }
457+
458+ $url = $config.urls[$phpVersion]
459+ $dllName = $config.dll_name
460+ $targetName = $config.target_name
461+
462+ try {
463+ # Create temporary directory
464+ $tmpDir = "$env:TEMP\${extKey}_$(Get-Random)"
465+ $archivePath = if ($url.EndsWith(".zip")) { "$tmpDir.zip" } else { "$tmpDir.archive" }
466+
467+ Write-Host "📥 Downloading $extName from: $url" -ForegroundColor Gray
468+
469+ # Download archive
470+ Invoke-WebRequest -Uri $url -OutFile $archivePath -UseBasicParsing -ErrorAction Stop
471+
472+ $fileSize = [math]::Round((Get-Item $archivePath).Length / 1MB, 2)
473+ Write-Host "✅ Downloaded $extName successfully ($fileSize MB)" -ForegroundColor Green
474+
475+ # Extract archive
476+ Write-Host "📂 Extracting $extName archive..." -ForegroundColor Gray
477+ if ($url.EndsWith(".zip")) {
478+ Expand-Archive -Path $archivePath -DestinationPath $tmpDir -Force
479+ } else {
480+ # For non-zip archives, try to extract anyway
481+ try {
482+ Expand-Archive -Path $archivePath -DestinationPath $tmpDir -Force
483+ } catch {
484+ Write-Host "⚠️ Could not extract $extName as ZIP, trying to copy as-is" -ForegroundColor Yellow
485+ New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
486+ Copy-Item $archivePath $tmpDir
487+ }
488+ }
489+
490+ # Find the DLL file
491+ $dllFile = Get-ChildItem -Path $tmpDir -File -Recurse |
492+ Where-Object { $_.Name -eq $dllName } |
493+ Select-Object -First 1
494+
495+ if (-not $dllFile) {
496+ Write-Host "❌ $extName: DLL file '$dllName' not found in archive" -ForegroundColor Red
497+ $failCount++
498+ continue
499+ }
500+
501+ # Determine target location
502+ $targetLocation = if ($config.ContainsKey("target_location") -and $config.target_location -eq "root") {
503+ $target
504+ } else {
505+ $extDir
506+ }
507+
508+ $targetDllPath = Join-Path $targetLocation $targetName
509+
510+ # Copy DLL to target location
511+ Copy-Item -Path $dllFile.FullName -Destination $targetDllPath -Force
512+ $dllSize = [math]::Round((Get-Item $targetDllPath).Length / 1KB, 2)
513+ Write-Host "✅ Copied $targetName ($dllSize KB)" -ForegroundColor Green
514+
515+ # Process remaining files (move to 3rd-party directory)
516+ if ($extKey -ne "firebird") { # Firebird doesn't need 3rd-party files
517+ $extThirdPartyDir = Join-Path $thirdPartyDir $extKey
518+
519+ if (-not (Test-Path $extThirdPartyDir)) {
520+ New-Item -ItemType Directory -Path $extThirdPartyDir -Force | Out-Null
521+ }
522+
523+ $remainingFiles = Get-ChildItem -Path $tmpDir -Recurse -File |
524+ Where-Object { $_.FullName -ne $dllFile.FullName }
525+
526+ $movedCount = 0
527+ foreach ($file in $remainingFiles) {
528+ try {
529+ $relativePath = $file.FullName.Substring($tmpDir.Length + 1)
530+ $targetPath = Join-Path $extThirdPartyDir $relativePath
531+
532+ # Create subdirectory if needed
533+ $targetDir = Split-Path $targetPath -Parent
534+ if (-not (Test-Path $targetDir)) {
535+ New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
536+ }
537+
538+ Copy-Item -Path $file.FullName -Destination $targetPath -Force
539+ $movedCount++
540+ } catch {
541+ Write-Host "⚠️ Error copying file $($file.Name): $_" -ForegroundColor Yellow
542+ }
543+ }
544+
545+ if ($movedCount -gt 0) {
546+ Write-Host "📁 Moved $movedCount additional files to 3rd-party/$extKey" -ForegroundColor Green
547+ }
548+ }
549+
550+ # Cleanup temporary files
551+ Remove-Item $tmpDir, $archivePath -Recurse -Force -ErrorAction SilentlyContinue
552+
553+ Write-Host "✅ $extName extension processed successfully" -ForegroundColor Green
554+ $successCount++
555+
556+ } catch {
557+ Write-Host "❌ Error processing $extName extension: $_" -ForegroundColor Red
558+ Write-Host "🔗 URL: $url" -ForegroundColor DarkGray
559+ $failCount++
560+
561+ # Cleanup on error
562+ Remove-Item $tmpDir, $archivePath -Recurse -Force -ErrorAction SilentlyContinue
563+ }
564+ }
565+
566+ Write-Host ""
567+ Write-Host "📊 Additional Extensions Summary for PHP $phpVersion ($($tsMode.ToUpper()))" -ForegroundColor Cyan
568+ Write-Host "=================================================" -ForegroundColor Cyan
569+ Write-Host "✅ Successful: $successCount extensions" -ForegroundColor Green
570+ Write-Host "❌ Failed: $failCount extensions" -ForegroundColor $(if ($failCount -gt 0) { 'Red' } else { 'Green' })
571+ Write-Host ""
572+
361573 - name : 📦 Pack final result
362574 id : pack
363575 shell : pwsh
@@ -460,6 +672,7 @@ jobs:
460672 - Support for multiple PHP versions (7.x, 8.x)
461673 - Both Thread Safe (TS) and Non-Thread Safe (NTS) variants
462674 - Compiled with appropriate Visual Studio toolsets
675+ - Additional extensions: Blackfire, Ioncube (NTS only), Firebird client
463676
464677 ⚡ **Quick Installation:**
465678 1. Download the appropriate pack for your PHP version and thread safety mode
@@ -471,6 +684,11 @@ jobs:
471684 - \`vs16\` - Visual Studio 2019 (PHP 8.0-8.3)
472685 - \`vs17\` - Visual Studio 2022 (PHP 8.4+)
473686
687+ 🔥 **Additional Extensions:**
688+ - **Blackfire**: Performance profiling (all PHP versions, TS/NTS)
689+ - **Ioncube**: Code encryption loader (NTS only)
690+ - **Firebird**: Database client library (PHP 7.3+)
691+
474692 🤖 **Auto-generated** by GitHub Actions on $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
475693
476694 # Delete existing release if it exists
0 commit comments