Completed
Push — master ( a4261d...fc5e52 )
by John
14s
created

JudgeClient::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace App\Babel\Extension\noj;
3
4
class JudgeClient
5
{
6
    private $ch=null;
7
    private $serverBaseUrl='';
8
    private $token;
9
    private $languageConfigs=[];
10
    public function __construct($token, $serverBaseUrl)
11
    {
12
        $this->serverBaseUrl=rtrim($serverBaseUrl, '/');
13
        $this->token=hash('sha256', $token);
14
        $this->languageConfigs=Languages::get();
15
    }
16
    public function ping()
17
    {
18
        return $this->post($this->serverBaseUrl.'/ping');
19
    }
20
    /**
21
     * 调用判题 api
22
     * @param string $src 提交的源代码
23
     * @param string $language 使用的编程语言
24
     * @param string $testCaseId test_case_id
25
     * @param array $config 额外配置
26
     * @return array
27
     * @throws Exception
28
     */
29
    public function judge($src, $language, $testCaseId, $config=[])
30
    {
31
        $languageConfig=$this->getLanguageConfigByLanguage($language);
32
        if (is_null($languageConfig)) {
33
            throw new Exception("don't support \"$language\" language!");
0 ignored issues
show
Bug introduced by
The type App\Babel\Extension\noj\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
34
        }
35
        $default=[
36
            'language_config' => $languageConfig,
37
            'src' => $src,
38
            'test_case_id' => $testCaseId,
39
            'max_cpu_time' => $languageConfig['compile']['max_cpu_time'],
40
            'max_memory' => $languageConfig['compile']['max_memory'],
41
            'spj_version' => null,
42
            'spj_config' => null,
43
            'spj_compile_config' => null,
44
            'spj_src' => null,
45
            'output' => false
46
        ];
47
        return $this->post($this->serverBaseUrl.'/judge', array_merge($default, $config));
48
    }
49
    public function compileSpj($src, $spjVersion, $spjCompileConfig)
50
    {
51
        $data=[
52
            'src' => $src,
53
            'spj_version' => $spjVersion,
54
            'spj_compile_config' => $spjCompileConfig,
55
        ];
56
        return $this->post($this->serverBaseUrl.'/compile_spj', $data);
57
    }
58
    public function getLanguageConfigByLanguage($language)
59
    {
60
        return $this->getLanguageConfigByKey($language.'_lang_config');
61
    }
62
    public function getLanguageConfigByKey($key)
63
    {
64
        return isset($this->languageConfigs[$key]) ? $this->languageConfigs[$key] : null;
65
    }
66
    private function needCreateCurl()
67
    {
68
        return is_null($this->ch);
69
    }
70
    /**
71
     * 获取 curl 资源
72
     * @return null|resource
73
     */
74
    private function getCurl()
75
    {
76
        if ($this->needCreateCurl()) {
77
            $this->ch=curl_init();
78
            $defaults=[
79
                CURLOPT_RETURNTRANSFER => true,
80
                CURLOPT_HEADER => false,
81
                // set HTTP request header
82
                CURLOPT_HTTPHEADER => [
83
                    'Content-type: application/json',
84
                    'X-Judge-Server-Token: '.$this->token
85
                ],
86
            ];
87
            curl_setopt_array($this->ch, $defaults);
0 ignored issues
show
Bug introduced by
It seems like $this->ch can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            curl_setopt_array(/** @scrutinizer ignore-type */ $this->ch, $defaults);
Loading history...
88
        }
89
        return $this->ch;
90
    }
91
    /**
92
     * 发送 GET 请求
93
     * @param string $url 请求的url
94
     * @param array $data 请求参数
95
     * @return array
96
     */
97
    private function get($url, $data=[])
98
    {
99
        return $this->request('GET', $url, $data);
100
    }
101
    /**
102
     * 发送 POST 请求
103
     * @param string $url 请求的url
104
     * @param array $data 请求参数
105
     * @return array
106
     */
107
    private function post($url, $data=[])
108
    {
109
        return $this->request('POST', $url, $data);
110
    }
111
    /**
112
     * 发送 http 请求
113
     * @param string $method http method
114
     * @param string $url 请求的url
115
     * @param array $data 请求参数
116
     * @return array
117
     */
118
    private function request($method, $url, $data=[])
119
    {
120
        $ch=$this->getCurl();
121
        $method=strtoupper($method);
122
        if (in_array($method, ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH'])) {
123
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
124
        }
125
        curl_setopt($ch, CURLOPT_URL, $url);
126
        curl_setopt($ch, CURLOPT_POSTFIELDS, empty($data) ? '{}' : json_encode($data));
127
        if (!$result=curl_exec($this->ch)) {
128
            trigger_error(curl_error($this->ch));
129
        }
130
        return json_decode($result, true);
131
    }
132
    /**
133
     * 关闭 curl 资源
134
     */
135
    public function close()
136
    {
137
        if (is_resource($this->ch)) {
138
            curl_close($this->ch);
139
        }
140
        $this->ch=null;
141
    }
142
    public function __destruct()
143
    {
144
        $this->close();
145
    }
146
}
147