377 lines
8.1 KiB
PHP
377 lines
8.1 KiB
PHP
<?php
|
|
|
|
if(!defined('ONYX')) exit;
|
|
|
|
class Exercice
|
|
{
|
|
var $id = null;
|
|
var $number;
|
|
var $theme;
|
|
var $require;
|
|
var $level;
|
|
var $points;
|
|
var $statement;
|
|
var $files = array();
|
|
var $keys = array();
|
|
|
|
function Exercice($id=null, $theme=null)
|
|
{
|
|
global $VAR;
|
|
|
|
if (!empty($id))
|
|
{
|
|
$db = new BDD();
|
|
|
|
$db->escape($id);
|
|
$res = $db->unique_query("SELECT `id`, `id_theme`, `require`, `level`,
|
|
`points`, `statement`
|
|
FROM exercices WHERE id = '$id'");
|
|
|
|
if (!empty($res))
|
|
{
|
|
$this->files = $db->query("SELECT `id`, `path`, `name`, `sha1`
|
|
FROM exercice_files
|
|
WHERE id_exercice = '$id'");
|
|
// Decode sha1
|
|
if ($this->files)
|
|
foreach($this->files as &$f)
|
|
{
|
|
$f["path_orig"] = $f["path"];
|
|
if (isset($VAR["files_dir"]))
|
|
$f["path"] = $VAR["files_dir"].$f["path"];
|
|
$f["basename"] = basename($f["path"]);
|
|
$f["sha1"] = strhex($f["sha1"]);
|
|
}
|
|
|
|
$this->keys = $db->query("SELECT `id`, `format`, `value`
|
|
FROM exercice_keys
|
|
WHERE id_exercice = '$id'");
|
|
|
|
$db->deconnexion();
|
|
|
|
if (!empty($theme))
|
|
{
|
|
if ($res['id_theme'] == $theme->get_id())
|
|
$this->theme = $theme;
|
|
else
|
|
throw new InvalidThemeException();
|
|
}
|
|
else
|
|
$this->theme = new Theme($res['id_theme']);
|
|
|
|
$this->id = $res['id'];
|
|
$this->require = $res['require'];
|
|
$this->level = $res['level'];
|
|
$this->points = $res['points'];
|
|
$this->statement = $res['statement'];
|
|
|
|
$this->set_number();
|
|
}
|
|
else
|
|
{
|
|
$db->deconnexion();
|
|
throw new ExerciceNotFoundException();
|
|
}
|
|
}
|
|
}
|
|
|
|
static function __set_state(array $array)
|
|
{
|
|
$tmp = new Exercice();
|
|
|
|
$tmp->id = $array["id"];
|
|
$tmp->number = $array["number"];
|
|
$tmp->theme = $array["theme"];
|
|
$tmp->require = $array["require"];
|
|
$tmp->level = $array["level"];
|
|
$tmp->points = $array["points"];
|
|
$tmp->statement = $array["statement"];
|
|
$tmp->files = $array["files"];
|
|
$tmp->keys = $array["keys"];
|
|
|
|
return $tmp;
|
|
}
|
|
|
|
function get_id()
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
function get_name()
|
|
{
|
|
return "Exercice ".$this->number;
|
|
}
|
|
|
|
function get_statement()
|
|
{
|
|
return $this->statement;
|
|
}
|
|
|
|
// retourne le nombre d'equipes qui ont résolues l'exercice
|
|
// trié par date
|
|
function get_solved()
|
|
{
|
|
$id = $this->id;
|
|
|
|
$db = new BDD();
|
|
$db->escape($id);
|
|
$res = $db->query("SELECT `id_team`, `time` FROM solved
|
|
WHERE id_exercice = '$id'
|
|
ORDER BY time");
|
|
|
|
$db->deconnexion();
|
|
|
|
return $res;
|
|
}
|
|
|
|
function is_unlocked($team)
|
|
{
|
|
if ($this->require == "")
|
|
return 1;
|
|
|
|
$req = $this->require;
|
|
|
|
$db = new BDD();
|
|
$db->escape($req);
|
|
$res = $db->unique_query("SELECT `id` FROM solved
|
|
WHERE id_team = '".intval($team->id)."'
|
|
AND id_exercice = '$req'");
|
|
$db->deconnexion();
|
|
if (empty($res))
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
function has_solved($team)
|
|
{
|
|
$id = $this->id;
|
|
|
|
$db = new BDD();
|
|
$db->escape($id);
|
|
$res = $db->unique_query("SELECT `time` FROM solved WHERE id_exercice = '$id'
|
|
AND id_team = ".intval($team->get_id()));
|
|
|
|
$db->deconnexion();
|
|
|
|
return $res["time"];
|
|
}
|
|
|
|
function last_try($team)
|
|
{
|
|
$id = $this->id;
|
|
|
|
$db = new BDD();
|
|
$db->escape($id);
|
|
$res = $db->unique_query("SELECT `time` FROM exercice_tries WHERE id_exercice = '$id'
|
|
AND id_team = ".intval($team->get_id())." ORDER BY time DESC LIMIT 1");
|
|
|
|
$db->deconnexion();
|
|
|
|
if (!empty($res))
|
|
return $res["time"];
|
|
else
|
|
return null;
|
|
}
|
|
|
|
function set_number()
|
|
{
|
|
if ($this->require == "")
|
|
$this->number = 1;
|
|
|
|
$db = new BDD();
|
|
|
|
$exo = $this->id;
|
|
$ret = 0;
|
|
|
|
$checked = array();
|
|
|
|
do
|
|
{
|
|
array_push($checked, $exo);
|
|
$db->escape($exo);
|
|
$res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'");
|
|
$exo = $res['require'];
|
|
$ret++;
|
|
} while ($exo != "" && !in_array($exo, $checked));
|
|
|
|
$this->number = $ret;
|
|
|
|
$db->deconnexion();
|
|
}
|
|
|
|
function update($create=false)
|
|
{
|
|
$id = $this->id;
|
|
$theme = intval($this->theme->get_id());
|
|
$require = $this->require;
|
|
$level = intval($this->level);
|
|
$points = intval($this->points);
|
|
$statement = $this->statement;
|
|
$files = $this->files;
|
|
$keys = $this->keys;
|
|
|
|
$db = new BDD();
|
|
$db->escape($id);
|
|
$db->escape($theme);
|
|
$db->escape($require);
|
|
$db->escape($statement);
|
|
|
|
if ($create)
|
|
{
|
|
$db->query("INSERT INTO exercices
|
|
VALUES ('".$id."', '".$theme."', '".$require."', '".$level."', '".$points."','".$statement."');");
|
|
}
|
|
else
|
|
{
|
|
$db->query("UPDATE exercices
|
|
SET `id_theme` = '".$theme."', `require` = '".$require."', `level` = '".$level."', `points` = '".$points."', `statement` = '".$statement."'
|
|
WHERE id = '$id'");
|
|
|
|
$aff = $db->affected();
|
|
}
|
|
|
|
foreach ($this->keys as $k => $key)
|
|
{
|
|
$format = $key['format'];
|
|
$value = $key['value'];
|
|
if (isset($key['id']))
|
|
$kid = $key['id'];
|
|
else
|
|
$kid = 0;
|
|
|
|
$db->escape($format);
|
|
$db->escape($value);
|
|
|
|
if (empty($kid))
|
|
{
|
|
$db->query("INSERT INTO exercice_keys
|
|
VALUES (NULL, '".$this->id."', '".$format."', UNHEX('".strhex($value)."'))");
|
|
|
|
$this->keys[$k]['id'] = $db->insert_id();
|
|
}
|
|
else
|
|
{
|
|
$db->query("UPDATE exercice_keys
|
|
SET `format` = '".$format."', `value` = UNHEX('".strhex($value).")')
|
|
WHERE id = ".$kid);
|
|
}
|
|
}
|
|
|
|
foreach ($this->files as $k => $file)
|
|
{
|
|
if (!empty($file['path_orig']))
|
|
$path = $file['path_orig'];
|
|
else
|
|
$path = $file['path'];
|
|
$name = $file['name'];
|
|
$sha1 = $file['sha1'];
|
|
|
|
if (isset($file['id']))
|
|
$fid = intval($file['id']);
|
|
|
|
$db->escape($path);
|
|
$db->escape($name);
|
|
$db->escape($sha1);
|
|
|
|
if (!isset($file['id']))
|
|
{
|
|
$db->query("INSERT INTO exercice_files
|
|
VALUES (NULL, '".$id."', '".$path."', '".$name."', UNHEX('".$sha1."'));");
|
|
|
|
$this->files[$k]['id'] = $db->insert_id();
|
|
}
|
|
else
|
|
{
|
|
$db->query("UPDATE exercice_files
|
|
SET `path` = '".$path."', `name` = '".$name."', `sha1` = UNHEX('".$sha1."')
|
|
WHERE id = ".$fid);
|
|
}
|
|
}
|
|
|
|
$db->deconnexion();
|
|
|
|
//FIXME
|
|
return 1;
|
|
}
|
|
|
|
function create()
|
|
{
|
|
update(true);
|
|
}
|
|
|
|
function flush_keys()
|
|
{
|
|
$db = new BDD();
|
|
$db->query("DELETE FROM exercice_keys WHERE id_exercice = ".intval($this->id));
|
|
$db->deconnexion();
|
|
|
|
$this->keys = array();
|
|
}
|
|
|
|
function add_key($format, $value)
|
|
{
|
|
if ($format == "raw")
|
|
{
|
|
$this->add_key("sha1", hash("sha1", $value));
|
|
$this->add_key("sha512", hash("sha512", $value));
|
|
$this->add_key("md5", hash("md5", $value));
|
|
}
|
|
else
|
|
$this->keys[] = array(
|
|
"format" => $format,
|
|
"value" => $value
|
|
);
|
|
}
|
|
|
|
function add_file($path, $name, $sha1)
|
|
{
|
|
$this->files[] = array(
|
|
"path" => $path,
|
|
"name" => $name,
|
|
"sha1" => $sha1
|
|
);
|
|
}
|
|
|
|
public static function get_nb_exo_max()
|
|
{
|
|
$db = new BDD();
|
|
$res = $db->unique_query("SELECT count(id) AS max FROM exercices
|
|
GROUP BY id_theme
|
|
ORDER BY max DESC
|
|
LIMIT 1");
|
|
$db->deconnexion();
|
|
|
|
return $res['max'];
|
|
}
|
|
|
|
public function first_to_solve_exercice()
|
|
{
|
|
$db = new BDD();
|
|
|
|
$id = $this->id;
|
|
$db->escape($id);
|
|
|
|
$res = $db->unique_query("SELECT t3.team_name as result
|
|
FROM solved AS t1
|
|
INNER JOIN (
|
|
SELECT MIN(s.time) AS minTime
|
|
FROM solved AS s
|
|
WHERE s.id_exercice = '".$id."'
|
|
) AS t2
|
|
INNER JOIN teams AS t3 ON t1.id_team = t3.id
|
|
WHERE t1.time = t2.minTime");
|
|
$db->deconnexion();
|
|
|
|
return $res['result'];
|
|
}
|
|
|
|
}
|
|
|
|
class ExerciceNotFoundException extends Exception
|
|
{
|
|
}
|
|
|
|
class InvalidThemeException extends Exception
|
|
{
|
|
}
|