66
77use App \Models \Site ;
88use App \RemoteSite \Connection ;
9+ use App \RemoteSite \Responses \PrepareUpdate ;
910use Illuminate \Contracts \Queue \ShouldQueue ;
1011use Illuminate \Foundation \Queue \Queueable ;
12+ use Illuminate \Support \Facades \App ;
13+ use Illuminate \Support \Facades \Log ;
1114
1215class UpdateSite implements ShouldQueue
1316{
1417 use Queueable;
18+ protected int $ preUpdateCode ;
1519
1620 /**
1721 * Create a new job instance.
@@ -30,5 +34,92 @@ public function handle(): void
3034
3135 // Test connection and get current version
3236 $ healthResult = $ connection ->checkHealth ();
37+
38+ // Check the version
39+ if (version_compare ($ healthResult ->cms_version , $ this ->targetVersion , ">= " )) {
40+ Log::info ("Site is already up to date: " . $ this ->site ->id );
41+
42+ return ;
43+ }
44+
45+ // Store pre-update response code
46+ $ this ->preUpdateCode = $ this ->site ->getFrontendStatus ();
47+
48+ // Let site fetch available updates
49+ $ updateResult = $ connection ->getUpdate ();
50+
51+ // Check if update is found and return if not
52+ if (is_null ($ updateResult ->availableUpdate )) {
53+ Log::info ("No update available for site: " . $ this ->site ->id );
54+
55+ return ;
56+ }
57+
58+ // Check the version and return if it does not match
59+ if ($ updateResult ->availableUpdate !== $ this ->targetVersion ) {
60+ Log::info ("Update version mismatch for site: " . $ this ->site ->id );
61+
62+ return ;
63+ }
64+
65+ $ prepareResult = $ connection ->prepareUpdate ($ this ->targetVersion );
66+
67+ // Perform the actual extraction
68+ $ this ->performExtraction ($ prepareResult );
69+
70+ // Run the postupdate steps
71+ if (!$ connection ->finalizeUpdate ()->success ) {
72+ throw new \Exception ("Update for site failed in postprocessing: " . $ this ->site ->id );
73+ }
74+
75+ // Compare codes
76+ if ($ this ->site ->getFrontendStatus () !== $ this ->preUpdateCode ) {
77+ throw new \Exception ("Status code has changed after update for site: " . $ this ->site ->id );
78+ }
79+ }
80+
81+ protected function performExtraction (PrepareUpdate $ prepareResult ): void
82+ {
83+ /** Create a separate connection with the extraction password **/
84+ $ connection = App::makeWith (Connection::class, [
85+ "baseUrl " => $ this ->site ->url ,
86+ "key " => $ prepareResult ->password
87+ ]);
88+
89+ // Ping server
90+ $ pingResult = $ connection ->performExtractionRequest (["task " => "ping " ]);
91+
92+ if (empty ($ pingResult ["message " ]) || $ pingResult ["message " ] === 'Invalid login ' ) {
93+ throw new \Exception (
94+ "Invalid ping response for site: " . $ this ->site ->id
95+ );
96+ }
97+
98+ // Start extraction
99+ $ stepResult = $ connection ->performExtractionRequest (["task " => "startExtract " ]);
100+
101+ // Run actual core update
102+ while (array_key_exists ("done " , $ stepResult ) && $ stepResult ["done " ] !== true ) {
103+ if ($ stepResult ["status " ] !== true ) {
104+ throw new \Exception (
105+ "Invalid extract response for site: " . $ this ->site ->id
106+ );
107+ }
108+
109+ // Make next extraction step
110+ $ stepResult = $ connection ->performExtractionRequest (
111+ [
112+ "task " => "stepExtract " ,
113+ "instance " => $ stepResult ["instance " ]
114+ ]
115+ );
116+ }
117+
118+ // Clean up restore
119+ $ connection ->performExtractionRequest (
120+ [
121+ "task " => "finalizeUpdate "
122+ ]
123+ );
33124 }
34125}
0 commit comments