#!/usr/bin/env php targetFile = $targetFile ?? getcwd(); // original path with dir name $this->dirName = $dirName ?? basename($this->targetFile); // original dir name $this->laragonDir = $laragonDir ?? Config::getLaragonDir(); $this->symlinkFile = $symlinkFile ?? $this->laragonDir . DIRECTORY_SEPARATOR . $this->dirName; } public function makeSymlink() { try { $targetFile = $this->targetFile; $dirName = $this->dirName; $laragonDir = $this->laragonDir; $symlinkFile = $this->symlinkFile; // Check if file exists self::checkFileIfExist($symlinkFile); // Create the symlink if (symlink($targetFile, $symlinkFile)) { echo Colors::GREEN . "INFO" . Colors::CYAN . " The [" . Colors::RESET . $symlinkFile . Colors::CYAN . "] link has been connected to [" . Colors::RESET . $targetFile . Colors::CYAN . "].\n" . Colors::RESET; // TODO: check laragon config to determine http or https schema and domain tld echo Colors::CYAN . "Visit your website at: " . Colors::CYAN . "http://" . $dirName . ".test\n" . Colors::RESET; echo Colors::YELLOW . "Restart Laragon to see effect.\n" . Colors::RESET; Config::reloadLaragon(); } else { echo Colors::RED . "ERROR" . Colors::RESET . " Failed to create symlink." . Colors::RESET; } } catch (\Throwable $th) { echo $th->getMessage() . Colors::RESET; } } public function deleteSymlink() { try { $symlinkFile = $this->symlinkFile; // Check if file exists self::checkFileIfNotExist($symlinkFile); // Delete the symlink file if (rmdir($symlinkFile)) { echo Colors::GREEN . "INFO" . Colors::CYAN . " The symlink file [" . Colors::RESET . $symlinkFile . Colors::CYAN . "] has been deleted.\n" . Colors::RESET; } else { echo Colors::RED . "ERROR" . Colors::RESET . " Failed to delete symlink file." . Colors::RESET; } } catch (\Throwable $th) { echo Colors::RED . "ERROR" . Colors::RESET . " " . $th->getMessage() . Colors::RESET; } } protected static function checkFileIfExist($symlinkFile) { // Check if the symlink file already exists if (file_exists($symlinkFile)) { throw new \Exception(Colors::YELLOW . "WARNING" . Colors::CYAN . " The symlink file [" . Colors::RESET . $symlinkFile . Colors::CYAN . "] already exists.\n"); } } protected static function checkFileIfNotExist($symlinkFile) { // Check if the symlink file already exists if (!file_exists($symlinkFile)) { throw new \Exception(Colors::YELLOW . "WARNING" . Colors::RED . " The symlink file [" . Colors::RESET . $symlinkFile . Colors::RED . "] not exists.\n"); } } } /** * Define config of symlink maker */ class Config { public const VERSION = '1.0.0'; // update tag and release as is. private $configFileName = 'laralink.json'; public function __construct( public $laragonPath = null, public $userProfilePath = null, public $jsonFilePath = null ) { // Define the user profile path $this->userProfilePath = $userProfilePath ?? getenv('USERPROFILE'); // Define the path to the JSON file $this->jsonFilePath = $this->userProfilePath . DIRECTORY_SEPARATOR . $this->configFileName; } public static function getConfigFileName() { $self = new static(); return $self->configFileName; } public static function getConfigFilePath() { // Define the user profile path $userProfilePath = getenv('USERPROFILE'); // Define the path to the JSON file return $userProfilePath . DIRECTORY_SEPARATOR . self::getConfigFileName(); } public static function checkConfigFile() { return file_exists(self::getConfigFilePath()); } public function setLaragonPath() { $initialConfig = [ "www" => $this->laragonPath . DIRECTORY_SEPARATOR . 'www', ]; file_put_contents($this->jsonFilePath, json_encode($initialConfig)); // Read the existing JSON data $configData = json_decode(file_get_contents($this->jsonFilePath), true); } public static function getLaragonDir() { if (!self::checkConfigFile()) { // Get the user profile path $userProfilePath = getenv('USERPROFILE'); // Get the config file name $configFileName = self::getConfigFileName(); // Throw an exception if config file is not exist. throw new Exception("The config file [{$configFileName}] is not found in {$userProfilePath}."); } // Read the contents of the config file $configContents = file_get_contents(self::getConfigFilePath()); // Decode the JSON contents into an associative array $configData = json_decode($configContents, true); // Check if the 'www' key exists in the config data if (!isset($configData['www'])) { // Throw an exception or return a default value if the 'www' key is not found throw new Exception("The 'www' key is not found in the config file."); } return $configData['www']; } public static function info() { echo Colors::CYAN . "Laragon Linker " . Colors::GREEN . Config::VERSION . " \n" . Colors::RESET; echo Colors::YELLOW . "\nUsage: \n" . Colors::RESET; echo Colors::RESET . " command [options] [arguments] \n" . Colors::RESET; echo Colors::YELLOW . "\nOptions: \n" . Colors::RESET; echo Colors::GREEN . " -h, --help " . Colors::RESET . "Display help for the " . Colors::CYAN . "Laragon Linker " . Colors::RESET . "tool.\n" . Colors::RESET; echo Colors::YELLOW . "\nAvailable commands: \n" . Colors::RESET; echo Colors::GREEN . " link " . Colors::RESET . "Link current directory with laragon/www. \n" . Colors::RESET; echo Colors::GREEN . " unlink " . Colors::RESET . "Remove current directory from laragon/www.\n" . Colors::RESET; echo Colors::GREEN . " path " . Colors::RESET . "Get current path of laragon. \n" . Colors::RESET; echo Colors::GREEN . " set " . Colors::RESET . "Set the path of laragon. \n" . Colors::RESET; echo Colors::GREEN . " links " . Colors::RESET . "Get paths of linked projects (coming soon). \n" . Colors::RESET; echo Colors::GREEN . " php-scoop " . Colors::RESET . " Create symlinks for PHP versions from Scoop. \n" . Colors::RESET; } public static function reloadLaragon() { $command = self::getLaragonDir() . DIRECTORY_SEPARATOR . 'laragon.exe reload'; $output = []; $returnVar = 0; exec($command, $output, $returnVar); // Output the command output and return value echo "Command Output:\n" . Colors::RESET; foreach ($output as $line) { echo $line . "\n" . Colors::RESET; } } } if (isset($argv[1])) { if (!Config::checkConfigFile()) { echo Colors::CYAN . 'Enter the path of Laragon: ' . Colors::RESET; (new Config(laragonPath: trim(fgets(STDIN))))->setLaragonPath(); } // Usage: link current directory to Laragon www path if ($argv[1] == 'link') { (new SymlinkMaker())->makeSymlink(); } // Usage: unlink current directory from Laragon www path if ($argv[1] == 'unlink') { (new SymlinkMaker())->deleteSymlink(); } // Usage: get the path of Laragon if ($argv[1] == 'path') { echo Colors::GREEN . Config::getLaragonDir() . Colors::RESET; } // Usage: set the path of Laragon if ($argv[1] == 'set') { echo Colors::CYAN . 'Enter the path of Laragon: ' . Colors::RESET; (new Config(laragonPath: trim(fgets(STDIN))))->setLaragonPath(); } // Usage: create symlinks for PHP versions from Scoop if ($argv[1] == 'php-scoop') { // Get the username dynamically $userName = getenv('USERNAME'); // Define source directory $scoopAppsPath = "C:\\Users\\$userName\\scoop\\apps"; // Ask the user for the Laragon root path with a default value $defaultLaragonPath = str_replace('www', '', Config::getLaragonDir()); echo "Enter Laragon root path [default: $defaultLaragonPath]: "; $laragonRootPath = trim(fgets(STDIN)); // Use the default path if the user input is empty $laragonPhpPath = !empty($laragonRootPath) ? $laragonRootPath . "\\bin\\php" : $defaultLaragonPath . "\\bin\\php"; // Ensure source and destination directories exist if (!is_dir($scoopAppsPath)) { die("Error: Scoop apps directory does not exist.\n"); } if (!is_dir($laragonPhpPath)) { die("Error: Laragon PHP directory does not exist.\n"); } // Get a list of all installed PHP versions in the Scoop apps directory $phpVersions = glob($scoopAppsPath . "\\php*\\current", GLOB_ONLYDIR); foreach ($phpVersions as $phpVersionPath) { // Extract the PHP version from the path $phpVersion = basename(str_replace('current', '', $phpVersionPath)); // Define the destination path for the symlink in Laragon $destinationPath = $laragonPhpPath . "\\" . $phpVersion; // Create a symbolic link if (!file_exists($destinationPath)) { symlink($phpVersionPath, $destinationPath); echo "Symlink created for PHP version: $phpVersion\n"; } else { echo "Symlink already exists for PHP version: $phpVersion\n"; } } echo "All symlinks created successfully.\n"; } // Usage: get help if ($argv[1] == '--help' || $argv[1] == '-h') { Config::info(); } } else { Config::info(); }