library-ts/node/webpack/PHPPagesBuilder.ts

189 lines
4.4 KiB
TypeScript
Raw Permalink Normal View History

2025-03-25 06:42:27 +00:00
import * as fs from "fs";
import * as path from "path";
import { RJLog } from "../log/RJLog";
2025-03-31 12:00:55 +00:00
import { spawn } from "child_process";
2025-03-25 06:42:27 +00:00
export class PagesInfo
{
pages:string[] = [];
}
2025-03-31 12:00:55 +00:00
export class PHPServerSettings
{
phpPaths:string[] = [ "D:\\apps\\php\\php.exe", "C:\\apps\\php\\php.exe" ];
relativeWebPath:string;
routerPath:string;
port:number = 8081;
}
2025-03-25 06:42:27 +00:00
export class PHPPagesBuilder
{
inputDir:string;
outputDir:string;
2025-03-31 12:00:55 +00:00
static hasServer = false;
constructor( source:string, build:string, settings:PHPServerSettings )
2025-03-25 06:42:27 +00:00
{
this.inputDir = source;
this.outputDir = build;
2025-03-31 12:00:55 +00:00
this.startServer( settings );
2025-03-25 06:42:27 +00:00
}
2025-03-31 12:00:55 +00:00
startServer( settings:PHPServerSettings )
{
if ( settings == null )
{
return;
}
if ( PHPPagesBuilder.hasServer )
{
return;
}
PHPPagesBuilder.hasServer = true;
let phpPath = PHPPagesBuilder.getPHPPath( settings );
if ( ! phpPath )
{
RJLog.error( "PHP was not found!");
RJLog.error( "Ensure PHP is installed and the paths in the settings are configured correctly.");
RJLog.log( "PHP paths from settings of '" + process.argv[ 2 ] + "': ");
RJLog.log( '"' + settings.phpPaths.join( ", " ) + '"' );
return;
}
let workdingDir = process.cwd();
let webPath = path.join( workdingDir, settings.relativeWebPath );
let routerPath = path.join( webPath, "_router_.php" );
let port = settings.port;
let spawnedProcess = spawn( phpPath,["-S", "0.0.0.0:" + port, routerPath, "-t", webPath ] );
spawnedProcess.stdout.on( "data", data => { console.log( data + "" ); } );
spawnedProcess.stderr.on( "data", data => { console.log( data + "" ); } );
spawnedProcess.on( 'error', (error) => {
console.log(`error: ${error.message}`);
});
spawnedProcess.on( "close", code => {
console.log(`child process exited with code ${code}`);
});
}
static getPHPPath( settings:PHPServerSettings )
{
for ( let path of settings.phpPaths )
{
let exists = fs.existsSync( path );
if ( exists )
{
RJLog.log( "Starting php server from:", path );
return path;
}
}
return null;
}
2025-03-25 06:42:27 +00:00
filterFiles( fileName:string )
{
if ( fileName.startsWith( "__" ) )
{
return false;
}
return fileName.endsWith( ".html" );
}
modify( content:string )
{
return `<?php ?>\n${content}`;
}
apply( compiler:any )
{
compiler.hooks.afterCompile.tapAsync( "PHPPagesBuilder",
( compilation:any, callback:any ) =>
{
if ( fs.existsSync( this.inputDir ) )
{
fs.readdirSync( this.inputDir )
.filter( this.filterFiles )
.forEach(
( file ) =>
{
let fullPath = path.join(this.inputDir, file);
compilation.fileDependencies.add(fullPath); // Mark for watching
}
);
}
callback();
}
);
compiler.hooks.emit.tapAsync( "PHPPagesBuilder",
( compilation:any, callback:any ) =>
{
fs.readdir( this.inputDir,
( err, files ) =>
{
if ( err )
{
RJLog.log( "Error", this.inputDir );
return callback( err );
}
let pages = new PagesInfo();
files.filter( this.filterFiles ).forEach( ( file ) =>
{
let filePath = path.join( this.inputDir, file );
let content = fs.readFileSync( filePath, "utf-8" );
let modifiedContent = this.modify( content );
let phpFileName = file.replace( ".html", ".php" );
let outputFileName = path.join( this.outputDir, phpFileName );
pages.pages.push( phpFileName );
compilation.assets[ outputFileName ] =
{
source: () => modifiedContent,
size: () => modifiedContent.length,
};
}
);
let pagesPath = path.join( this.outputDir, "pages.json" );
let pagesJSON = JSON.stringify( pages, null, " " );
compilation.assets[ pagesPath ] =
{
source: () => pagesJSON,
size: () => pagesJSON.length,
};
callback();
}
);
}
);
}
}