33namespace Ajaxray \ServerSync \Commands ;
44
55use Illuminate \Console \Command ;
6- use Illuminate \Support \Facades \DB ;
7- use Illuminate \Support \Facades \Storage ;
86use Illuminate \Support \Facades \Config ;
97use Illuminate \Support \Facades \App ;
108use Symfony \Component \Process \Process ;
@@ -15,6 +13,7 @@ class SyncPullCommand extends Command
1513 {--host= : Production server hostname or IP}
1614 {--user= : SSH username for production server}
1715 {--path= : Path to production installation}
16+ {--remote=production : Remote server configuration to use (e.g., production, staging)}
1817 {--skip-db : Skip database sync}
1918 {--skip-files : Skip files sync}
2019 {--delete : Remove files that don \'t exist in production}
@@ -24,22 +23,28 @@ class SyncPullCommand extends Command
2423
2524 protected $ description = 'Pull and sync database and files from production to local environment ' ;
2625
27- protected string $ prodHost ;
28- protected string $ prodUser ;
29- protected string $ prodPath ;
26+ protected string $ remoteHost ;
27+ protected string $ remoteUser ;
28+ protected string $ remotePath ;
3029
3130 public function handle ()
32- {
31+ {
3332 if (App::environment ('production ' ) && !$ this ->option ('force ' )) {
3433 $ this ->error ('This command cannot be run in production environment. Use --force to override. ' );
3534 return 1 ;
3635 }
3736
38- $ this ->prodHost = $ this ->option ('host ' ) ?: Config::get ('server-sync.production.host ' );
39- $ this ->prodUser = $ this ->option ('user ' ) ?: Config::get ('server-sync.production.user ' );
40- $ this ->prodPath = $ this ->option ('path ' ) ?: Config::get ('server-sync.production.path ' );
37+ $ remote = $ this ->option ('remote ' );
38+
39+ $ this ->remoteHost = $ this ->option ('host ' ) ?: Config::get ("server-sync. $ remote.host " );
40+ $ this ->remoteUser = $ this ->option ('user ' ) ?: Config::get ("server-sync. $ remote.user " );
41+ $ this ->remotePath = $ this ->option ('path ' ) ?: Config::get ("server-sync. $ remote.path " );
42+
43+ if ($ remote ) {
44+ $ this ->info ("Pulling from {$ this ->remoteHost } as {$ this ->remoteUser }" );
45+ }
4146
42- if (!$ this ->validateRequirements ()) {
47+ if (!$ this ->validateRequirements ()) {
4348 return 1 ;
4449 }
4550
@@ -57,7 +62,7 @@ public function handle()
5762
5863 protected function validateRequirements (): bool
5964 {
60- if (!$ this ->prodHost || !$ this ->prodUser || !$ this ->prodPath ) {
65+ if (!$ this ->remoteHost || !$ this ->remoteUser || !$ this ->remotePath ) {
6166 $ this ->error ('Production server details are required. Please provide --host, --user and --path options or configure them in config/server-sync.php ' );
6267 return false ;
6368 }
@@ -75,12 +80,14 @@ protected function validateRequirements(): bool
7580 }
7681
7782 // Test SSH connection
78- $ testConnection = Process::fromShellCommandline ("ssh -q {$ this ->prodUser }@ {$ this ->prodHost } exit " );
79- $ testConnection ->run ();
80-
81- if (!$ testConnection ->isSuccessful ()) {
82- $ this ->error ('Failed to connect to production server. Please check your SSH configuration. ' );
83- return false ;
83+ if (!$ this ->option ('skip-db ' ) || !$ this ->option ('skip-files ' )) {
84+ $ testConnection = Process::fromShellCommandline ("ssh -q {$ this ->remoteUser }@ {$ this ->remoteHost } exit " );
85+ $ testConnection ->run ();
86+
87+ if (!$ testConnection ->isSuccessful ()) {
88+ $ this ->error ('Failed to connect to production server. Please check your SSH configuration. ' );
89+ return false ;
90+ }
8491 }
8592
8693 return true ;
@@ -165,9 +172,9 @@ protected function syncFiles()
165172 'rsync -avz --compress %s %s --progress %s@%s:%s/%s/ %s/ ' ,
166173 $ deleteFlag ,
167174 $ excludeFlags ,
168- $ this ->prodUser ,
169- $ this ->prodHost ,
170- $ this ->prodPath ,
175+ $ this ->remoteUser ,
176+ $ this ->remoteHost ,
177+ $ this ->remotePath ,
171178 $ relativePath ,
172179 $ path
173180 );
@@ -193,9 +200,9 @@ protected function getProductionDatabaseConfig(): ?array
193200 $ this ->info ('Retrieving production database credentials... ' );
194201 $ sshCommand = sprintf (
195202 'ssh %s@%s "cd %s && grep -E \'^DB_(HOST|DATABASE|USERNAME|PASSWORD)= \' .env" ' ,
196- $ this ->prodUser ,
197- $ this ->prodHost ,
198- $ this ->prodPath
203+ $ this ->remoteUser ,
204+ $ this ->remoteHost ,
205+ $ this ->remotePath
199206 );
200207
201208 $ process = Process::fromShellCommandline ($ sshCommand );
@@ -228,8 +235,8 @@ protected function buildMysqlDumpCommand(array $dbConfig, string $tempFile): str
228235 {
229236 $ command = sprintf (
230237 'ssh %s@%s "mysqldump -h%s -u%s -p \'%s \' %s ' ,
231- $ this ->prodUser ,
232- $ this ->prodHost ,
238+ $ this ->remoteUser ,
239+ $ this ->remoteHost ,
233240 $ dbConfig ['host ' ],
234241 $ dbConfig ['username ' ],
235242 $ dbConfig ['password ' ],
@@ -254,7 +261,7 @@ protected function buildMysqlDumpCommand(array $dbConfig, string $tempFile): str
254261
255262 // Create a temporary file on the remote server, then download it
256263 $ remoteTempFile = '/tmp/temp_dump.sql ' ;
257- $ command .= " > {$ remoteTempFile }\" && scp {$ this ->prodUser }@ {$ this ->prodHost }: {$ remoteTempFile } {$ tempFile } && ssh {$ this ->prodUser }@ {$ this ->prodHost } \"rm {$ remoteTempFile }\"" ;
264+ $ command .= " > {$ remoteTempFile }\" && scp {$ this ->remoteUser }@ {$ this ->remoteHost }: {$ remoteTempFile } {$ tempFile } && ssh {$ this ->remoteUser }@ {$ this ->remoteHost } \"rm {$ remoteTempFile }\"" ;
258265
259266 return $ command ;
260267 }
0 commit comments