Orthanc::buildAnonQuery()   B
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 83
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 61
nc 12
nop 5
dl 0
loc 83
c 0
b 0
f 0
cc 6
rs 8.2286

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php 
2
/**
3
 Copyright (C) 2018-2020 KANOUN Salim
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the Affero GNU General Public v.3 License as published by
6
 the Free Software Foundation;
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
 Affero GNU General Public Public for more details.
11
 You should have received a copy of the Affero GNU General Public Public along
12
 with this program; if not, write to the Free Software Foundation, Inc.,
13
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
use GuzzleHttp\Client;
0 ignored issues
show
Bug introduced by
The type GuzzleHttp\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Psr\Http\Message\StreamInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Http\Message\StreamInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
19
/**
20
 * Main class for Orthanc communication, serve usefull APIs (get dicom tags, send to peer, download zip...)
21
 * 
22
 * If Orthanc is using HTTPS :
23
 * the php_openssl extension must exist and be enabled
24
 * In the php.ini file you should add this lines if not exists:
25
 * extension=php_openssl.dll
26
 * allow_url_fopen = On
27
*/
28
29
Class Orthanc {
30
	
31
	private $url;
32
	private $context;
33
	
34
	/**
35
	 * Build connexion string in Orthanc, boolean to connect with Orthanc Exposed or Orthanc PACS
36
	 * @param boolean $exposed
37
	 */
38
	public function __construct(bool $exposed=false) {
39
		//Set Time Limit at 3H as operation could be really long
40
		set_time_limit(10800);
41
42
		$this->client = new Client();
0 ignored issues
show
Bug Best Practice introduced by
The property client does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
43
		//Set address of Orthanc server
44
		if ($exposed) {
45
			$this->url=GAELO_ORTHANC_EXPOSED_INTERNAL_ADDRESS.':'.GAELO_ORTHANC_EXPOSED_INTERNAL_PORT;
46
			$this->login = GAELO_ORTHANC_EXPOSED_INTERNAL_LOGIN;
0 ignored issues
show
Bug Best Practice introduced by
The property login does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
47
			$this->password = GAELO_ORTHANC_EXPOSED_INTERNAL_PASSWORD;
0 ignored issues
show
Bug Best Practice introduced by
The property password does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
48
			$this->context=array(
49
				'http' => array(
50
					'header'  => "Authorization: Basic ".base64_encode(GAELO_ORTHANC_EXPOSED_INTERNAL_LOGIN.':'.GAELO_ORTHANC_EXPOSED_INTERNAL_PASSWORD)
51
	   			));
52
		}else {
53
			$this->url=GAELO_ORTHANC_PACS_ADDRESS.':'.GAELO_ORTHANC_PACS_PORT;
54
			$this->login = GAELO_ORTHANC_PACS_LOGIN;
55
			$this->password = GAELO_ORTHANC_PACS_PASSWORD;
56
			$this->context=array(
57
	   			'http' => array(
58
	   				'header'  => "Authorization: Basic ".base64_encode(GAELO_ORTHANC_PACS_LOGIN.':'.GAELO_ORTHANC_PACS_PASSWORD)
59
	   			) );
60
	   }
61
62
	}
63
	
64
	/**
65
	 * Return list of Peers declared in Orthanc
66
	 * @return mixed
67
	 */
68
	public function getPeers() {
69
		$context=stream_context_create($this->context);
70
		$json=file_get_contents($this->url.'/peers/', false, $context);
71
		$peers=json_decode($json, true);
72
		return $peers;
73
	}
74
	
75
	/**
76
	 * Search function in Orthanc, search the Patients/Studies/Series level in Orthanc and return the raw response in JSON
77
	 * @param string $level
78
	 * @param string $patientID
79
	 * @param string $patientName
80
	 * @param string $studyDate
81
	 * @param string $studyUID
82
	 * @param string $accessionNumber
83
	 * @param string $studyDescription
84
	 * @return string json
85
	 */
86
	public function searchInOrthanc(string $level, string $patientID, string $patientName, string $studyDate, string $studyUID, string $accessionNumber, string $studyDescription) {
87
		
88
		$queryDetails=array(
89
				'PatientID' => $patientID,
90
				'PatientName' => $patientName,
91
				'StudyDate' => $studyDate,
92
				'StudyInstanceUID' => $studyUID,
93
				'AccessionNumber'=> $accessionNumber,
94
				'StudyDescription'=> $studyDescription,
95
		);
96
		
97
		$query=array(
98
				'Level' => $level,
99
				'CaseSensitive' => false,
100
				'Expand' => false,
101
				'Query' => $queryDetails,
102
				
103
		);
104
		
105
		$opts=array('http' =>
106
				array(
107
						'method'  => 'POST',
108
						'content' => json_encode($query),
109
						'header'=>  ['Content-Type: application/json Accept: application/json ', $this->context['http']['header']]
110
				)
111
		);
112
113
		$context=stream_context_create($opts);
114
		$resultJson=file_get_contents($this->url.'/tools/find', false, $context);
115
		$result=json_decode($resultJson);
116
		
117
		return $result;
118
	}
119
	
120
	/**
121
	 * return the ZIP as temp file containing the Orthanc ID ressources dicoms
122
	 * @param array $uidList
123
	 * @return resource temporary file path
124
	 */
125
	public function getZipStream(array $uidList) : StreamInterface {
126
	   
127
		if (!is_array($uidList)) {
0 ignored issues
show
introduced by
The condition is_array($uidList) is always true.
Loading history...
128
			$uidList=array($uidList);
129
		}
130
131
		$options = [
132
			'auth' => [$this->login, $this->password],
133
			'headers'  => ['content-type' => 'application/json', 'Accept' => 'application/zip'],
134
			'body' => json_encode(array('Transcode'=>'1.2.840.10008.1.2.1', 'Resources' => $uidList)),
135
			'stream' => true
136
		];
137
138
		$response = $this->client->request('POST', $this->url.'/tools/create-archive' , $options);
139
140
		$zipStream = $response->getBody();
141
		
142
		return $zipStream;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $zipStream returns the type Psr\Http\Message\StreamInterface which is incompatible with the documented return type resource.
Loading history...
143
	}
144
	
145
	
146
	/**
147
	 * Delete in Orthanc patients / study / series depending on Level and Orthanc ID
148
	 * @param  $level
149
	 * @param  $uidList
150
	 */
151
	public function deleteFromOrthanc(string $level, string $uid) {
152
	    
153
		$opts=array('http' =>
154
			array(
155
				'method'  => 'DELETE',
156
				'header'=>  ['Content-Type: application/json Accept: application/json', $this->context['http']['header']]
157
			)
158
		);
159
	    
160
		$context=stream_context_create($opts);
161
		file_get_contents($this->url.'/'.$level.'/'.$uid, false, $context);
162
	    
163
	}
164
	
165
	/**
166
	 * Add Peer declaration to Orthanc
167
	 * @param string $name name of the peer
168
	 * @param string $url URL with http / https and port
169
	 * @param string $username
170
	 * @param string $password
171
	 * @return mixed
172
	 */
173
	public function addPeer(string $name, string $url, string $username, string $password) {
174
	    
175
		$peerValues['Username']=$username;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$peerValues was never initialized. Although not strictly required by PHP, it is generally a good practice to add $peerValues = array(); before regardless.
Loading history...
176
		$peerValues['Password']=$password;
177
		$peerValues['Url']=$url;
178
		$opts=array('http' =>
179
			array(
180
				'method'  => 'PUT',
181
				'content' => json_encode($peerValues),
182
				'header'=>  ['Content-Type: application/json Accept: application/json ', $this->context['http']['header']]
183
			)
184
		);
185
	    
186
		$context=stream_context_create($opts);
187
		$resultJson=file_get_contents($this->url.'/peers/'.$name, false, $context);
188
	    
189
		$result=json_decode($resultJson);
190
		return $result;
191
	    
192
	}
193
	
194
	/**
195
	 * Remove Peer declaration from Orthanc
196
	 * @param string $name
197
	 */
198
	public function removePeer(string $name) {
199
	    
200
		$opts=array('http' =>
201
			array(
202
				'method'  => 'DELETE',
203
				'header'=>  ['Content-Type: application/json Accept: application/json ', $this->context['http']['header']]
204
			)
205
		);
206
	    
207
		$context=stream_context_create($opts);
208
		$resultJson=file_get_contents($this->url.'/peers/'.$name, false, $context);
209
	    
210
		$result=json_decode($resultJson);
211
	    
212
		return $result;
213
	}
214
	
215
	/**
216
	 * Remove all peers from orthanc
217
	 */
218
	public function removeAllPeers() {
219
	    
220
		$peers=$this->getPeers();
221
	    
222
		foreach ($peers as $peer) {
223
			$this->removePeer($peer);
224
		}
225
	    
226
	}
227
	
228
	/**
229
	 * Test if a peer has Orthanc Peer Accelerator
230
	 * @param string $peer
231
	 * @return boolean
232
	 */
233
	public function isPeerAccelerated(string $peer) {
234
		$context=stream_context_create($this->context);
235
		$json=file_get_contents($this->url.'/transfers/peers/', false, $context);
236
		$peersTest=json_decode($json, true);
237
	    
238
		if ($peersTest[$peer] == "installed") {
239
			return true;
240
		}
241
	    
242
		return false;
243
	}
244
	
245
	/**
246
	 * Send id list of DICOM to a peer
247
	 * @param string $peer
248
	 * @param array $ids
249
	 */
250
	public function sendToPeer(string $peer, array $ids) {
251
		
252
		$opts=array('http' =>
253
				array(
254
						'method'  => 'POST',
255
						"timeout" => 300, 
256
						'content' => json_encode($ids),
257
						'header'=>  ['Content-Type: application/json Accept: application/json', $this->context['http']['header']]
258
				)
259
		);
260
		
261
		$context=stream_context_create($opts);
262
		$result=file_get_contents($this->url.'/peers/'.$peer.'/store', false, $context);
263
		return $result;
264
	    
265
	}
266
	
267
	/**
268
	 * Send to Orthanc peer but asynchroneously
269
	 * @param string $peer
270
	 * @param array $ids
271
	 * @return string
272
	 */
273
	public function sendToPeerAsync(string $peer, array $ids) {
274
		$data['Synchronous']=false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
275
		$data['Resources']=$ids;
276
	    
277
		$opts=array('http' =>
278
			array(
279
				'method'  => 'POST',
280
				'content' => json_encode($data),
281
				'header'=>  ['Content-Type: application/json Accept: application/json', $this->context['http']['header']]
282
			)
283
		);
284
	    
285
		$context=stream_context_create($opts);
286
		$result=file_get_contents($this->url.'/peers/'.$peer.'/store', false, $context);
287
		return $result;
288
	}
289
	
290
	/**
291
	 * Send to peer with transfers accelerator plugin
292
	 * @param string $peer
293
	 * @param array $ids
294
	 * @param bool $gzip
295
	 * @return string
296
	 */
297
	public function sendToPeerAsyncWithAccelerator(string $peer, array $ids, bool $gzip) {
298
	    
299
		//If Peer dosen't have accelerated transfers fall back to regular orthanc peer transfers
300
		if (!$this->isPeerAccelerated($peer)) {
301
			$answer=$this->sendToPeerAsync($peer, $ids);
302
			return $answer;
303
		}
304
	    
305
		if (!$gzip) $data['Compression']="none"; else $data['Compression']="gzip";
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
306
	    
307
		$data['Peer']=$peer;
308
	    
309
	    
310
		foreach ($ids as $serieID) {
311
			$resourceSeries['Level']="Series";
312
			$resourceSeries['ID']=$serieID;
313
			$data['Resources'][]=$resourceSeries;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $resourceSeries seems to be defined later in this foreach loop on line 311. Are you sure it is defined here?
Loading history...
314
		}
315
	    
316
		$opts=array('http' =>
317
			array(
318
				'method'  => 'POST',
319
				'content' => json_encode($data),
320
				'header'=>  ['Content-Type: application/json Accept: application/json', $this->context['http']['header']]
321
			)
322
		);
323
	    
324
		$context=stream_context_create($opts);
325
		$result=file_get_contents($this->url.'/transfers/send', false, $context);
326
	    
327
		return $result;
328
	    
329
	}
330
	
331
	/**
332
	 * Import a file in Orthanc using the POST API
333
	 * @param string $file (path)
334
	 * @return string
335
	 */
336
	public function importFile(string $file) {
337
	    
338
		try {
339
			$opts=array('http' =>
340
				array(
341
					'method'  => 'POST',
342
					'content' => file_get_contents($file),
343
					'header'=>  ['Content-Type: application/dicom Accept: application/json', "content-length: ".filesize($file), $this->context['http']['header']]
344
				)
345
			);
346
    	    
347
			$context=stream_context_create($opts);
348
			$result=file_get_contents($this->url.'/instances', false, $context);
349
    	    
350
		}catch (Exception $e1) {
351
			error_log("Error during import Dcm ".$e1->getMessage());
352
		}
353
		return $result;
354
355
	}
356
357
	/**
358
	 * This method has the advantage to stream the content and avoid running out memory
359
	 */
360
	public function importFileGuzzle(string $file){
361
		try{
362
			$body = fopen($file, 'r');
363
364
			$options = ['auth' => [$this->login, $this->password],
365
			'headers'  => ['content-type' => 'application/dicom', 'Accept' => 'application/json'],
366
			'body' => $body];
367
368
			$response = $this->client->request('POST', $this->url.'/instances' , $options);
369
			
370
			return (string) $response->getBody();
371
		} catch (Exception $e1) {
372
			error_log("Error during import Dcm ".$e1->getMessage());
373
		}
374
	}
375
376
	/**
377
	 * Anonymize a study ressources according to Anon Profile
378
	 * Return the Anonymized Orthanc ID
379
	 * @param string $studyID
380
	 * @param string $profile
381
	 * @param string $patientCode
382
	 * @param string $visitType
383
	 * @param string $studyName
384
	 * @return string
385
	 */
386
	public function Anonymize(string $studyID, string $profile, string $patientCode, string $visitType, string $studyName) {
387
	    
388
		$jsonAnonQuery=$this->buildAnonQuery($profile, $patientCode, $patientCode, $visitType, $studyName);
389
	    
390
		$opts=array('http' =>
391
			array(
392
				'method'  => 'POST',
393
				"timeout" => 300,
394
				'content' => json_encode($jsonAnonQuery),
395
				'header'=>  ['Content-Type: application/json Accept: application/json', $this->context['http']['header']]
396
			)
397
		);
398
	    
399
		$context=stream_context_create($opts);
400
401
		$result=file_get_contents($this->url."/studies/".$studyID."/anonymize", false, $context);
402
        
403
		//get the resulting Anonymized study Orthanc ID
404
		$anonAnswer=json_decode($result, true);
405
		$anonymizedID=$anonAnswer['ID'];
406
	    
407
		//Remove SC if any in the anonymized study
408
		$this->removeSC($anonymizedID);
409
	    
410
		return $anonymizedID;
411
	    
412
	}
413
	
414
	/**
415
	 * Build Anon Json post for Anon settings
416
	 * @param string $profile
417
	 * @param string $newPatientName
418
	 * @param string $newPatientID
419
	 * @param string $newStudyDescription
420
	 * @return string
421
	 */
422
	private function buildAnonQuery(string $profile, string $newPatientName, string $newPatientID, string $newStudyDescription, string $clinicalStudy) {
423
    	    
424
		$tagsObjects=[];
425
		if ($profile == "Default") {
426
			$date=TagAnon::KEEP;
427
			$body=TagAnon::KEEP;
428
            
429
			$tagsObjects[]=new TagAnon("0010,0030", TagAnon::REPLACE, "19000101"); // BirthDay
430
			$tagsObjects[]=new TagAnon("0008,1030", TagAnon::REPLACE, $newStudyDescription); //studyDescription
431
			$tagsObjects[]=new TagAnon("0008,103E", TagAnon::KEEP); //series Description
432
           
433
    
434
		}else if ($profile == "Full") {
435
			$date=TagAnon::CLEAR;
436
			$body=TagAnon::CLEAR;
437
            
438
			$tagsObjects[]=new TagAnon("0010,0030", TagAnon::REPLACE, "19000101"); // BirthDay
439
			$tagsObjects[]=new TagAnon("0008,1030", TagAnon::CLEAR); // studyDescription
440
			$tagsObjects[]=new TagAnon("0008,103E", TagAnon::CLEAR); //series Description
441
		}
442
        
443
		//List tags releted to Date
444
		$tagsObjects[]=new TagAnon("0008,0022", $date); // Acquisition Date
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $date does not seem to be defined for all execution paths leading up to this point.
Loading history...
445
		$tagsObjects[]=new TagAnon("0008,002A", $date); // Acquisition DateTime
446
		$tagsObjects[]=new TagAnon("0008,0032", $date); // Acquisition Time
447
		$tagsObjects[]=new TagAnon("0038,0020", $date); // Admitting Date
448
		$tagsObjects[]=new TagAnon("0038,0021", $date); // Admitting Time
449
		$tagsObjects[]=new TagAnon("0008,0035", $date); // Curve Time
450
		$tagsObjects[]=new TagAnon("0008,0025", $date); // Curve Date
451
		$tagsObjects[]=new TagAnon("0008,0023", $date); // Content Date
452
		$tagsObjects[]=new TagAnon("0008,0033", $date); // Content Time
453
		$tagsObjects[]=new TagAnon("0008,0024", $date); // Overlay Date
454
		$tagsObjects[]=new TagAnon("0008,0034", $date); // Overlay Time
455
		$tagsObjects[]=new TagAnon("0040,0244", $date); // ...Start Date
456
		$tagsObjects[]=new TagAnon("0040,0245", $date); // ...Start Time
457
		$tagsObjects[]=new TagAnon("0008,0021", $date); // Series Date
458
		$tagsObjects[]=new TagAnon("0008,0031", $date); // Series Time
459
		$tagsObjects[]=new TagAnon("0008,0020", $date); // Study Date
460
		$tagsObjects[]=new TagAnon("0008,0030", $date); // Study Time
461
		$tagsObjects[]=new TagAnon("0010,21D0", $date); // Last menstrual date
462
		$tagsObjects[]=new TagAnon("0008,0201", $date); // Timezone offset from UTC
463
		$tagsObjects[]=new TagAnon("0040,0002", $date); // Scheduled procedure step start date
464
		$tagsObjects[]=new TagAnon("0040,0003", $date); // Scheduled procedure step start time
465
		$tagsObjects[]=new TagAnon("0040,0004", $date); // Scheduled procedure step end date
466
		$tagsObjects[]=new TagAnon("0040,0005", $date); // Scheduled procedure step end time
467
    	
468
		// same for Body characteristics
469
		$tagsObjects[]=new TagAnon("0010,2160", $body); // Patient's ethnic group
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $body does not seem to be defined for all execution paths leading up to this point.
Loading history...
470
		$tagsObjects[]=new TagAnon("0010,21A0", $body); // Patient's smoking status
471
		$tagsObjects[]=new TagAnon("0010,0040", $body); // Patient's sex
472
		$tagsObjects[]=new TagAnon("0010,2203", $body); // Patient's sex neutered
473
		$tagsObjects[]=new TagAnon("0010,1010", $body); // Patient's age
474
		$tagsObjects[]=new TagAnon("0010,21C0", $body); // Patient's pregnancy status
475
		$tagsObjects[]=new TagAnon("0010,1020", $body); // Patient's size
476
		$tagsObjects[]=new TagAnon("0010,1030", $body); // Patient's weight
477
    
478
		//Others
479
		$tagsObjects[]=new TagAnon("0008,0050", TagAnon::REPLACE, $clinicalStudy); // Accession Number contains study name
480
		$tagsObjects[]=new TagAnon("0010,0020", TagAnon::REPLACE, $newPatientID); //new Patient Name
481
		$tagsObjects[]=new TagAnon("0010,0010", TagAnon::REPLACE, $newPatientName); //new Patient Name
482
    	
483
		// Keep some Private tags usefull for PET/CT or Scintigraphy
484
		$tagsObjects[]=new TagAnon("7053,1000", TagAnon::KEEP); //Phillips
485
		$tagsObjects[]=new TagAnon("7053,1009", TagAnon::KEEP); //Phillips
486
		$tagsObjects[]=new TagAnon("0009,103B", TagAnon::KEEP); //GE
487
		$tagsObjects[]=new TagAnon("0009,100D", TagAnon::KEEP); //GE
488
		$tagsObjects[]=new TagAnon("0011,1012", TagAnon::KEEP); //Other
489
    	
490
		$jsonArrayAnon=[];
491
		$jsonArrayAnon['KeepPrivateTags']=false;
492
		$jsonArrayAnon['Force']=true;
493
    	
494
		foreach ($tagsObjects as $tag) {
495
    	    
496
			if ($tag->choice == TagAnon::REPLACE) {
497
				$jsonArrayAnon['Replace'][$tag->tag]=$tag->newValue;
498
			}else if ($tag->choice == TagAnon::KEEP) {
499
				$jsonArrayAnon['Keep'][]=$tag->tag;
500
			}
501
            
502
		}
503
    	
504
		return $jsonArrayAnon;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $jsonArrayAnon returns the type array which is incompatible with the documented return type string.
Loading history...
505
    	
506
	}
507
    
508
	/**
509
	 * Remove secondary captures in the study
510
	 * @param string $orthancStudyID
511
	 */
512
	private function removeSC(string $orthancStudyID) {
513
    	
514
		$studyOrthanc=new Orthanc_Study($orthancStudyID, $this->url, $this->context);
515
		$studyOrthanc->retrieveStudyData();
516
		$seriesObjects=$studyOrthanc->orthancSeries;
517
		foreach ($seriesObjects as $serie) {
518
			if ($serie->isSecondaryCapture()) {
519
				$this->deleteFromOrthanc("series", $serie->serieOrthancID);
520
			}
521
		}
522
    	
523
	}
524
    
525
    
526
	/**
527
	 * Return JobId details (get request in Orthanc)
528
	 * @param String $jobId
529
	 * @return mixed
530
	 */
531
	public function getJobDetails(String $jobId) {
532
        
533
		$context=stream_context_create($this->context);
534
		$json=file_get_contents($this->url.'/jobs/'.$jobId, false, $context);
535
        
536
		return json_decode($json, true);
537
        
538
	}
539
540
}