source: trunk/common/task.php @ 1184

Revision 1184, 9.2 KB checked in by bogdan2412, 4 weeks ago (diff)

Merged changes from live and a few extra

  • Updated backup script to include new configuration files after migration to HPHP
  • Copied over updated code from the textblock controller to the user controller in order to fix crash on invalid revision number
  • Fixed Twitter button
  • Fixed a bug with task test case grouping when string was too large to be stored in database
  • Add IA_HTTPS_ENABLED configuration option. Allows disableing of secure connection enforcement in development mode.
  • More user friendly strings for 'security' in userinfo macro.
  • Linting fixes
  • Property svn:eol-style set to native
Line 
1<?php
2require_once(IA_ROOT_DIR . "common/textblock.php");
3
4// This module implements task and task-param related stuff.
5
6// Get valid task types.
7function task_get_types() {
8    return array(
9            'classic' => 'Clasic',
10            'output-only' => 'Doar de output',
11    );
12}
13
14/**
15 * Get valid task security types
16 * @return array
17 */
18function task_get_security_types() {
19    return array(
20            'private' => 'Private',
21            'protected' => 'Protected',
22            'public' => 'Public');
23}
24
25// Get parameter infos.
26function task_get_parameter_infos() {
27    return array(
28        'classic' => array(
29            'timelimit' => array(
30                    'description' => "Limita de timp (in secunde)",
31                    'default' => 1,
32                    'type' => 'float',
33                    'name' => 'Limita de timp',
34            ),
35            'memlimit' => array(
36                    'description' => "Limita de memorie (in kilobytes)",
37                    'default' => 16384,
38                    'type' => 'integer',
39                    'name' => 'Limita de memorie',
40            ),
41        ),
42        'output-only' => array(
43        ),
44    );
45}
46
47// Initialize a task object
48function task_init($task_id, $task_type, $user = null) {
49    $task = array(
50            'id' => $task_id,
51            'type' => $task_type,
52            'title' => ucfirst($task_id),
53            'security' => 'private',
54            'source' => 'ad-hoc',
55            'page_name' => IA_TASK_TEXTBLOCK_PREFIX . $task_id,
56            'open_source' => 0,
57            'open_tests' => 0,
58            'test_count' => 10,
59            'test_groups' => NULL,
60            'public_tests' => NULL,
61            'evaluator' => NULL,
62            'use_ok_files' => 1,
63            'rating' => NULL,
64    );
65
66    // User stuff. ugly
67    if (is_null($user)) {
68        $task['user_id'] = 0;
69    } else {
70        $task['user_id'] = $user['id'];
71    }
72
73    log_assert_valid(task_validate($task));
74    return $task;
75}
76
77// Validates a task.
78// NOTE: this might be incomplete, so don't rely on it exclusively.
79// Use this to check for a valid model. It's also usefull in controllers.
80function task_validate($task) {
81    $errors = array();
82
83    // FIXME How to handle this?
84    log_assert(is_array($task), "You didn't even pass an array");
85
86    if (strlen(getattr($task, 'title', '')) < 1) {
87        $errors['title'] = 'Titlu prea scurt.';
88    }
89
90    if (!is_page_name(getattr($task, 'page_name'))) {
91        $errors['page_name'] = 'Homepage invalid';
92    }
93
94    if (!is_user_id(getattr($task, 'user_id'))) {
95        $errors['user_id'] = 'ID de utilizator invalid';
96    }
97
98    if (!array_key_exists(getattr($task, 'security'),
99            task_get_security_types())) {
100        $errors['security'] = 'Tipul securitatii este invalid';
101    }
102
103    $open_source = getattr($task, 'open_source');
104    if ($open_source != '0' && $open_source != '1') {
105        $errors['open_source'] = 'Se accepta doar 0/1';
106    }
107
108    $open_tests = getattr($task, 'open_tests');
109    if ($open_tests != '0' && $open_tests != '1') {
110        $errors['open_tests'] = 'Se accepta doar 0/1';
111    }
112
113    if (!array_key_exists(getattr($task, 'type'), task_get_types())) {
114        $errors['type'] = "Tipul task-ului este invalid";
115    }
116
117    if (!is_task_id(getattr($task, 'id', ''))) {
118        $errors['id'] = 'ID de task invalid';
119    }
120
121    if (!is_whole_number($task['test_count'])) {
122        $errors['test_count'] = "Numarul de teste trebuie sa fie un numar.";
123    } else if ($task['test_count'] < 1) {
124        $errors['test_count'] = "Minim 1 test.";
125    } else if ($task['test_count'] > 100) {
126        $errors['test_count'] = "Maxim 100 de teste.";
127    }
128
129    if ($task['use_ok_files'] != '0' && $task['use_ok_files'] != '1') {
130        $errors['use_ok_files'] = "0/1 only";
131    }
132
133    if ($task['evaluator'] == "") {
134        if (!$task['use_ok_files']) {
135            $errors['evaluator'] = "Pentru evaluare cu diff e nevoie e fisiere .ok";
136        }
137    } else {
138        if (!is_attachment_name($task['evaluator'])) {
139            $errors['evaluator'] = "Nume de fisier invalid.";
140        }
141    }
142
143    if (strlen(getattr($task, 'test_groups', '')) > 256) {
144        $errors['test_groups'] = 'Expresia este prea lunga.';
145    } else if (task_get_testgroups($task) === false) {
146        $errors['test_groups'] = "Eroare de sintaxa in expresie.";
147    }
148
149    if (task_parse_test_group($task["public_tests"], $task["test_count"]) === false) {
150        $errors['public_tests'] = "Eroare de sintaxa in expresie.";
151    }
152
153    return $errors;
154}
155
156// Parse test grouping expression from task and returns groups as an array
157// If there is no grouping parameter defined it returns a group for each test by default
158// If the expression string contains errors the function returns false
159// Expression syntax:
160// item: number | number-number
161// group: item | item,group
162// groups: group | group;groups
163function task_parse_test_group($string, $test_count) {
164    if (strlen($string) == 0)
165        return array();
166
167    $current_group = array();
168    $items = explode(',', $string);
169    $used_count = array();
170    for ($test = 1; $test <= $test_count; $test++) {
171        $used_count[$test]  = 0;
172    }
173
174    foreach ($items as &$item) {
175        $tests = explode('-', $item);
176        if (count($tests) < 1 || count($tests) > 2) {
177            return false;
178        }
179        foreach ($tests as &$test) {
180            $test = trim($test);
181            if (!is_whole_number($test)) {
182                return false;
183            }
184        }
185        if (count($tests) == 1) {
186            if ($tests[0] < 1 || $tests[0] > $test_count) {
187                return false;
188            }
189            $current_group[] = $tests[0];
190            $used_count[$tests[0]] = 1;
191        } else {
192            $left = (int) $tests[0];
193            $right = (int) $tests[1];
194            if ($left < 1 || $right < 1 || $left > $test_count || $right > $test_count) {
195                return false;
196            }
197            for ($test = min($left, $right); $test <= max($left, $right); $test++) {
198                $current_group[] = $test;
199                $used_count[$test]++;
200            }
201        }
202    }
203
204    for ($test = 1; $test <= $test_count; $test++) {
205        if ($used_count[$test] > 1) {
206            return false;
207        }
208    }
209
210    return $current_group;
211}
212
213function task_get_testgroups($task) {
214    $test_count = $task['test_count'];
215    if (!is_whole_number($test_count)) {
216        return false;
217    }
218    if (!getattr($task, 'test_groups')) {
219        $testgroups = array();
220        for ($test = 1; $test <= $test_count; $test++) {
221            $group = array($test);
222            $testgroups[] = $group;
223        }
224        return $testgroups;
225    }
226
227    $used_count = array();
228    for ($test = 1; $test <= $test_count; $test++) {
229        $used_count[$test]  = 0;
230    }
231    $testgroups = array();
232    $groups = explode(';', $task['test_groups']);
233    foreach ($groups as &$group) {
234        $current_group = task_parse_test_group($group, $test_count);
235        if (!$current_group) {
236            return false;
237        }
238        foreach ($current_group as $test) {
239            $used_count[$test]++;
240        }
241        $testgroups[] = $current_group;
242    }
243
244    for ($test = 1; $test <= $test_count; $test++) {
245        if ($used_count[$test] != 1) {
246            return false;
247        }
248    }
249
250    return $testgroups;
251}
252
253// Validate parameters. Return errors as $form_errors
254function task_validate_parameters($task_type, $parameters) {
255    $errors = array();
256    if ($task_type == 'classic') {
257        if (!is_numeric($parameters['timelimit'])) {
258                $errors['timelimit'] = "Limita de timp trebuie sa fie un numar.";
259        } else if ($parameters['timelimit'] < 0.01) {
260            $errors['timelimit'] = "Minim 10 milisecunde.";
261        } else if ($parameters['timelimit'] > 60) {
262            $errors['timelimit'] = "Maxim un minut.";
263        }
264
265        if (!is_whole_number($parameters['memlimit'])) {
266            $errors['memlimit'] = "Limita de memorie trebuie sa fie un numar.";
267        } else if ($parameters['memlimit'] < 10) {
268            $errors['memlimit'] = "Minim 10 kilobytes.";
269        } else if ($parameters['memlimit'] > 131072) {
270            $errors['memlimit'] = "Maxim 128 megabytes.";
271        }
272    } else if ($task_type == 'output-only') {
273        // Nothing to validate
274    } else {
275        log_error("Bad task_type");
276    }
277    return $errors;
278}
279
280function task_get_topic($task_id) {
281    if (!is_task_id($task_id)) {
282        log_error("Invalid task id");
283    }
284
285    // Get task
286    $task = task_get($task_id);
287    $task_page = textblock_get_revision($task["page_name"]);
288    return $task_page["forum_topic"];
289}
290
291// Receives a list of method and algorithm tag ids and adds links them to task_id
292function task_update_tags($task_id, $method_tags_id, $algorithm_tags_id) {
293    log_assert(is_array($method_tags_id), 'method_tags must be an array');
294    log_assert(is_array($algorithm_tags_id), 'algorithm_tags must be an array');
295    log_assert(is_task_id($task_id), "Invalid task_id");
296
297    tag_clear('task', $task_id, 'method');
298    tag_clear('task', $task_id, 'algorithm');
299
300    foreach ($method_tags_id as $tag_id) {
301        tag_add('task', $task_id, $tag_id);
302    }
303
304    foreach ($algorithm_tags_id as $tag_id) {
305        tag_add('task', $task_id, $tag_id);
306    }
307}
Note: See TracBrowser for help on using the repository browser.