2016-07-18 16:39:37 +00:00
< ? php
requirePHPLib ( 'form' );
requirePHPLib ( 'judger' );
2019-06-14 15:30:02 +00:00
requirePHPLib ( 'data' );
2022-03-17 04:00:03 +00:00
if ( ! Auth :: check ()) {
2022-10-06 12:28:43 +00:00
redirectToLogin ();
2022-03-17 04:00:03 +00:00
}
2022-04-03 10:18:17 +00:00
if ( ! isNormalUser ( $myUser )) {
become403Page ();
}
2016-07-18 16:39:37 +00:00
if ( ! validateUInt ( $_GET [ 'id' ]) || ! ( $problem = queryProblemBrief ( $_GET [ 'id' ]))) {
become404Page ();
}
if ( ! hasProblemPermission ( $myUser , $problem )) {
become403Page ();
}
2017-11-25 04:00:00 +00:00
$oj_name = UOJConfig :: $data [ 'profile' ][ 'oj-name' ];
2016-07-18 16:39:37 +00:00
$problem_extra_config = getProblemExtraConfig ( $problem );
$data_dir = " /var/uoj_data/ ${ problem['id'] } " ;
function echoFileNotFound ( $file_name ) {
2017-11-25 04:00:00 +00:00
echo '<h4>' , htmlspecialchars ( $file_name ), '<sub class="text-danger"> ' , '文件未找到' , '</sub></h4>' ;
2016-07-18 16:39:37 +00:00
}
function echoFilePre ( $file_name ) {
global $data_dir ;
$file_full_name = $data_dir . '/' . $file_name ;
$finfo = finfo_open ( FILEINFO_MIME );
$mimetype = finfo_file ( $finfo , $file_full_name );
if ( $mimetype === false ) {
echoFileNotFound ( $file_name );
return ;
}
finfo_close ( $finfo );
echo '<h4>' , htmlspecialchars ( $file_name ), '<sub> ' , $mimetype , '</sub></h4>' ;
echo " <pre> \n " ;
$output_limit = 1000 ;
if ( strStartWith ( $mimetype , 'text/' )) {
echo htmlspecialchars ( uojFilePreview ( $file_full_name , $output_limit ));
} else {
2018-10-11 15:01:50 +00:00
echo htmlspecialchars ( uojFilePreview ( $file_full_name , $output_limit , 'binary' ));
2016-07-18 16:39:37 +00:00
}
echo " \n </pre> " ;
}
2017-11-25 04:00:00 +00:00
//上传数据
2020-06-25 12:41:16 +00:00
if ( $_POST [ 'problem_data_file_submit' ] == 'submit' ) {
if ( $_FILES [ " problem_data_file " ][ " error " ] > 0 ) {
$errmsg = " Error: " . $_FILES [ " problem_data_file " ][ " error " ];
2017-11-25 04:00:00 +00:00
becomeMsgPage ( '<div>' . $errmsg . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
2020-06-25 12:41:16 +00:00
} else {
2019-04-16 13:12:52 +00:00
$zip_mime_types = array ( 'application/zip' , 'application/x-zip' , 'application/x-zip-compressed' );
2020-09-06 09:04:00 +00:00
if ( in_array ( $_FILES [ " problem_data_file " ][ " type " ], $zip_mime_types ) || $_FILES [ " problem_data_file " ][ " type " ] == 'application/octet-stream' && substr ( $_FILES [ " problem_data_file " ][ " name " ], - 4 ) == '.zip' ) {
2017-11-25 04:00:00 +00:00
$up_filename = " /tmp/ " . rand ( 0 , 100000000 ) . " data.zip " ;
move_uploaded_file ( $_FILES [ " problem_data_file " ][ " tmp_name " ], $up_filename );
$zip = new ZipArchive ;
2020-06-25 12:41:16 +00:00
if ( $zip -> open ( $up_filename ) === TRUE ) {
2019-06-14 15:30:02 +00:00
$zip -> extractTo ( " /var/uoj_data/upload/ { $problem [ 'id' ] } " );
2017-11-25 04:00:00 +00:00
$zip -> close ();
2019-08-02 11:00:37 +00:00
exec ( " cd /var/uoj_data/upload/ { $problem [ 'id' ] } ; if [ `find . -maxdepth 1 -type f`File = File ]; then for sub_dir in `find -maxdepth 1 -type d ! -name .`; do mv -f \$ sub_dir/* . && rm -rf \$ sub_dir; done; fi " );
2017-11-25 04:00:00 +00:00
echo " <script>alert('上传成功!')</script> " ;
2020-06-25 12:41:16 +00:00
} else {
2017-11-25 04:00:00 +00:00
$errmsg = " 解压失败! " ;
becomeMsgPage ( '<div>' . $errmsg . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
}
unlink ( $up_filename );
2020-06-25 12:41:16 +00:00
} else {
2019-04-16 14:42:19 +00:00
$errmsg = " 请上传zip格式! " ;
2019-04-16 13:12:52 +00:00
becomeMsgPage ( '<div>' . $errmsg . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
}
2020-06-25 12:41:16 +00:00
}
2017-11-25 04:00:00 +00:00
}
//添加配置文件
2020-06-25 12:41:16 +00:00
if ( $_POST [ 'problem_settings_file_submit' ] == 'submit' ) {
if ( $_POST [ 'use_builtin_checker' ] and $_POST [ 'n_tests' ] and $_POST [ 'input_pre' ] and $_POST [ 'input_suf' ] and $_POST [ 'output_pre' ] and $_POST [ 'output_suf' ] and $_POST [ 'time_limit' ] and $_POST [ 'memory_limit' ]) {
$set_filename = " /var/uoj_data/upload/ { $problem [ 'id' ] } /problem.conf " ;
$has_legacy = false ;
if ( file_exists ( $set_filename )) {
$has_legacy = true ;
unlink ( $set_filename );
}
$setfile = fopen ( $set_filename , " w " );
fwrite ( $setfile , " use_builtin_judger on \n " );
if ( $_POST [ 'use_builtin_checker' ] != 'ownchk' ) {
fwrite ( $setfile , " use_builtin_checker " . $_POST [ 'use_builtin_checker' ] . " \n " );
}
fwrite ( $setfile , " n_tests " . $_POST [ 'n_tests' ] . " \n " );
if ( $_POST [ 'n_ex_tests' ]) {
fwrite ( $setfile , " n_ex_tests " . $_POST [ 'n_ex_tests' ] . " \n " );
} else {
fwrite ( $setfile , " n_ex_tests 0 \n " );
}
if ( $_POST [ 'n_sample_tests' ]) {
fwrite ( $setfile , " n_sample_tests " . $_POST [ 'n_sample_tests' ] . " \n " );
} else {
fwrite ( $setfile , " n_sample_tests 0 \n " );
}
fwrite ( $setfile , " input_pre " . $_POST [ 'input_pre' ] . " \n " );
fwrite ( $setfile , " input_suf " . $_POST [ 'input_suf' ] . " \n " );
fwrite ( $setfile , " output_pre " . $_POST [ 'output_pre' ] . " \n " );
fwrite ( $setfile , " output_suf " . $_POST [ 'output_suf' ] . " \n " );
fwrite ( $setfile , " time_limit " . $_POST [ 'time_limit' ] . " \n " );
fwrite ( $setfile , " memory_limit " . $_POST [ 'memory_limit' ] . " \n " );
fclose ( $setfile );
if ( ! $has_legacy ) {
echo " <script>alert('添加成功!')</script> " ;
} else {
echo " <script>alert('替换成功!')</script> " ;
}
} else {
2017-11-25 04:00:00 +00:00
$errmsg = " 添加配置文件失败,请检查是否所有输入框都已填写! " ;
becomeMsgPage ( '<div>' . $errmsg . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
}
}
2016-07-18 16:39:37 +00:00
$info_form = new UOJForm ( 'info' );
$http_host = HTML :: escape ( UOJContext :: httpHost ());
$info_form -> appendHTML ( <<< EOD
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
<!--< label class = " col-sm-3 control-label " > zip上传数据 </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >
< row >
< button type = " button " style = " width:30% " class = " btn btn-primary " data - toggle = " modal " data - target = " #UploadDataModal " > 上传数据 </ button >
2019-06-14 15:30:02 +00:00
< button type = " submit " style = " width:30% " id = " button-submit-data " name = " submit-data " value = " data " class = " btn btn-danger " > 检验配置并同步数据 </ button >
2017-11-25 04:00:00 +00:00
</ row >
</ div >
</ div >-->
2016-07-18 16:39:37 +00:00
</ div >
EOD
);
2022-09-20 05:10:25 +00:00
$attachment_url = HTML :: url ( " /download.php?type=attachment&id= { $problem [ 'id' ] } " );
$info_form -> appendHTML ( <<< EOD
< div class = " form-group row " >
< label class = " col-sm-3 control-label " > problem_ { $problem [ 'id' ]} _attachment . zip </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >
< a href = " $attachment_url " > $attachment_url </ a >
</ div >
</ div >
</ div >
EOD
);
$download_url = HTML :: url ( " /download.php?type=problem&id= { $problem [ 'id' ] } " );
2016-07-18 16:39:37 +00:00
$info_form -> appendHTML ( <<< EOD
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2016-07-18 16:39:37 +00:00
< label class = " col-sm-3 control-label " > problem_ { $problem [ 'id' ]} . zip </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >
< a href = " $download_url " > $download_url </ a >
</ div >
</ div >
</ div >
EOD
);
$info_form -> appendHTML ( <<< EOD
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2016-07-18 16:39:37 +00:00
< label class = " col-sm-3 control-label " > testlib . h </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >
< a href = " /download.php?type=testlib.h " > 下载 </ a >
</ div >
</ div >
</ div >
EOD
);
$esc_submission_requirement = HTML :: escape ( json_encode ( json_decode ( $problem [ 'submission_requirement' ]), JSON_PRETTY_PRINT ));
$info_form -> appendHTML ( <<< EOD
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2016-07-18 16:39:37 +00:00
< label class = " col-sm-3 control-label " > 提交文件配置 </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >< pre >
$esc_submission_requirement
</ pre >
</ div >
</ div >
</ div >
EOD
);
$esc_extra_config = HTML :: escape ( json_encode ( json_decode ( $problem [ 'extra_config' ]), JSON_PRETTY_PRINT ));
$info_form -> appendHTML ( <<< EOD
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2016-07-18 16:39:37 +00:00
< label class = " col-sm-3 control-label " > 其它配置 </ label >
< div class = " col-sm-9 " >
< div class = " form-control-static " >< pre >
$esc_extra_config
</ pre >
</ div >
</ div >
</ div >
EOD
);
if ( isSuperUser ( $myUser )) {
$info_form -> addVInput ( 'submission_requirement' , 'text' , '提交文件配置' , $problem [ 'submission_requirement' ],
function ( $submission_requirement , & $vdata ) {
$submission_requirement = json_decode ( $submission_requirement , true );
if ( $submission_requirement === null ) {
return '不是合法的JSON' ;
}
$vdata [ 'submission_requirement' ] = json_encode ( $submission_requirement );
},
null );
$info_form -> addVInput ( 'extra_config' , 'text' , '其它配置' , $problem [ 'extra_config' ],
function ( $extra_config , & $vdata ) {
$extra_config = json_decode ( $extra_config , true );
if ( $extra_config === null ) {
return '不是合法的JSON' ;
}
$vdata [ 'extra_config' ] = json_encode ( $extra_config );
},
null );
$info_form -> handle = function ( & $vdata ) {
global $problem ;
$esc_submission_requirement = DB :: escape ( $vdata [ 'submission_requirement' ]);
$esc_extra_config = DB :: escape ( $vdata [ 'extra_config' ]);
DB :: update ( " update problems set submission_requirement = ' $esc_submission_requirement ', extra_config = ' $esc_extra_config ' where id = { $problem [ 'id' ] } " );
};
} else {
$info_form -> no_submit = true ;
}
class DataDisplayer {
public $problem_conf = array ();
public $data_files = array ();
public $displayers = array ();
public function __construct ( $problem_conf = null , $data_files = null ) {
global $data_dir ;
if ( isset ( $problem_conf )) {
foreach ( $problem_conf as $key => $val ) {
$this -> problem_conf [ $key ] = array ( 'val' => $val );
}
}
if ( ! isset ( $data_files )) {
2020-06-25 12:41:16 +00:00
$this -> data_files = array_filter ( scandir ( $data_dir ), function ( $x ) {
return $x !== '.' && $x !== '..' && $x !== 'problem.conf' ;
});
2016-07-18 16:39:37 +00:00
natsort ( $this -> data_files );
array_unshift ( $this -> data_files , 'problem.conf' );
} else {
$this -> data_files = $data_files ;
}
$this -> setDisplayer ( 'problem.conf' , function ( $self ) {
global $info_form ;
$info_form -> printHTML ();
echo '<div class="top-buffer-md"></div>' ;
echo '<table class="table table-bordered table-hover table-striped table-text-center">' ;
echo '<thead>' ;
echo '<tr>' ;
echo '<th>key</th>' ;
echo '<th>value</th>' ;
echo '</tr>' ;
echo '</thead>' ;
echo '<tbody>' ;
foreach ( $self -> problem_conf as $key => $info ) {
if ( ! isset ( $info [ 'status' ])) {
echo '<tr>' ;
echo '<td>' , htmlspecialchars ( $key ), '</td>' ;
echo '<td>' , htmlspecialchars ( $info [ 'val' ]), '</td>' ;
echo '</tr>' ;
} elseif ( $info [ 'status' ] == 'danger' ) {
echo '<tr class="text-danger">' ;
echo '<td>' , htmlspecialchars ( $key ), '</td>' ;
echo '<td>' , htmlspecialchars ( $info [ 'val' ]), ' <span class="glyphicon glyphicon-remove"></span>' , '</td>' ;
echo '</tr>' ;
}
}
echo '</tbody>' ;
echo '</table>' ;
echoFilePre ( 'problem.conf' );
});
}
public function setProblemConfRowStatus ( $key , $status ) {
$this -> problem_conf [ $key ][ 'status' ] = $status ;
return $this ;
}
public function setDisplayer ( $file_name , $fun ) {
$this -> displayers [ $file_name ] = $fun ;
return $this ;
}
public function addDisplayer ( $file_name , $fun ) {
$this -> data_files [] = $file_name ;
$this -> displayers [ $file_name ] = $fun ;
return $this ;
}
public function echoDataFilesList ( $active_file ) {
foreach ( $this -> data_files as $file_name ) {
2019-09-10 02:15:20 +00:00
echo '<li class="nav-item">' ;
2016-07-18 16:39:37 +00:00
if ( $file_name != $active_file ) {
2019-09-10 02:15:20 +00:00
echo '<a class="nav-link" href="#">' ;
2016-07-18 16:39:37 +00:00
} else {
2019-09-10 02:15:20 +00:00
echo '<a class="nav-link active" href="#">' ;
2016-07-18 16:39:37 +00:00
}
2019-09-10 02:15:20 +00:00
echo htmlspecialchars ( $file_name ), '</a>' , '</li>' ;
2016-07-18 16:39:37 +00:00
}
}
public function displayFile ( $file_name ) {
global $data_dir ;
if ( isset ( $this -> displayers [ $file_name ])) {
$fun = $this -> displayers [ $file_name ];
$fun ( $this );
} elseif ( in_array ( $file_name , $this -> data_files )) {
echoFilePre ( $file_name );
} else {
echoFileNotFound ( $file_name );
}
}
}
function getDataDisplayer () {
global $data_dir ;
global $problem ;
2020-06-25 12:41:16 +00:00
$allow_files = array_flip ( array_filter ( scandir ( $data_dir ), function ( $x ) {
return $x !== '.' && $x !== '..' ;
}));
2016-07-18 16:39:37 +00:00
2020-06-25 12:41:16 +00:00
$getDisplaySrcFunc = function ( $name ) use ( $allow_files ) {
return function () use ( $name , $allow_files ) {
2016-07-18 16:39:37 +00:00
$src_name = $name . '.cpp' ;
if ( isset ( $allow_files [ $src_name ])) {
echoFilePre ( $src_name );
} else {
echoFileNotFound ( $src_name );
}
if ( isset ( $allow_files [ $name ])) {
echoFilePre ( $name );
} else {
echoFileNotFound ( $name );
}
};
};
$problem_conf = getUOJConf ( " $data_dir /problem.conf " );
if ( $problem_conf === - 1 ) {
return ( new DataDisplayer ()) -> setDisplayer ( 'problem.conf' , function () {
global $info_form ;
$info_form -> printHTML ();
echoFileNotFound ( 'problem.conf' );
});
}
if ( $problem_conf === - 2 ) {
return ( new DataDisplayer ()) -> setDisplayer ( 'problem.conf' , function () {
global $info_form ;
$info_form -> printHTML ();
echo '<h4 class="text-danger">problem.conf 格式有误</h4>' ;
echoFilePre ( 'problem.conf' );
});
}
$judger_name = getUOJConfVal ( $problem_conf , 'use_builtin_judger' , null );
if ( ! isset ( $problem_conf [ 'use_builtin_judger' ])) {
return new DataDisplayer ( $problem_conf );
}
if ( $problem_conf [ 'use_builtin_judger' ] == 'on' ) {
$n_tests = getUOJConfVal ( $problem_conf , 'n_tests' , 10 );
if ( ! validateUInt ( $n_tests )) {
return ( new DataDisplayer ( $problem_conf )) -> setProblemConfRowStatus ( 'n_tests' , 'danger' );
}
$has_extra_tests = ! ( isset ( $problem_conf [ 'submit_answer' ]) && $problem_conf [ 'submit_answer' ] == 'on' );
$data_disp = new DataDisplayer ( $problem_conf , array ( 'problem.conf' ));
$data_disp -> addDisplayer ( 'tests' ,
2020-06-25 12:41:16 +00:00
function ( $self ) use ( $problem_conf , $allow_files , $n_tests , $n_ex_tests ) {
2016-07-18 16:39:37 +00:00
for ( $num = 1 ; $num <= $n_tests ; $num ++ ) {
$input_file_name = getUOJProblemInputFileName ( $problem_conf , $num );
$output_file_name = getUOJProblemOutputFileName ( $problem_conf , $num );
echo '<div class="row">' ;
echo '<div class="col-md-6">' ;
if ( isset ( $allow_files [ $input_file_name ])) {
echoFilePre ( $input_file_name );
} else {
echoFileNotFound ( $input_file_name );
}
echo '</div>' ;
echo '<div class="col-md-6">' ;
if ( isset ( $allow_files [ $output_file_name ])) {
echoFilePre ( $output_file_name );
} else {
echoFileNotFound ( $output_file_name );
}
echo '</div>' ;
echo '</div>' ;
}
}
);
if ( $has_extra_tests ) {
$n_ex_tests = getUOJConfVal ( $problem_conf , 'n_ex_tests' , 0 );
if ( ! validateUInt ( $n_ex_tests )) {
return ( new DataDisplayer ( $problem_conf )) -> setProblemConfRowStatus ( 'n_ex_tests' , 'danger' );
}
$data_disp -> addDisplayer ( 'extra tests' ,
2020-06-25 12:41:16 +00:00
function ( $self ) use ( $problem_conf , $allow_files , $n_tests , $n_ex_tests ) {
2016-07-18 16:39:37 +00:00
for ( $num = 1 ; $num <= $n_ex_tests ; $num ++ ) {
$input_file_name = getUOJProblemExtraInputFileName ( $problem_conf , $num );
$output_file_name = getUOJProblemExtraOutputFileName ( $problem_conf , $num );
echo '<div class="row">' ;
echo '<div class="col-md-6">' ;
if ( isset ( $allow_files [ $input_file_name ])) {
echoFilePre ( $input_file_name );
} else {
echoFileNotFound ( $input_file_name );
}
echo '</div>' ;
echo '<div class="col-md-6">' ;
if ( isset ( $allow_files [ $output_file_name ])) {
echoFilePre ( $output_file_name );
} else {
echoFileNotFound ( $output_file_name );
}
echo '</div>' ;
echo '</div>' ;
}
}
);
}
2018-07-09 02:40:30 +00:00
if ( ! isset ( $problem_conf [ 'interaction_mode' ])) {
if ( isset ( $problem_conf [ 'use_builtin_checker' ])) {
$data_disp -> addDisplayer ( 'checker' , function ( $self ) {
echo '<h4>use builtin checker : ' , $self -> problem_conf [ 'use_builtin_checker' ][ 'val' ], '</h4>' ;
});
} else {
$data_disp -> addDisplayer ( 'checker' , $getDisplaySrcFunc ( 'chk' ));
}
2016-07-18 16:39:37 +00:00
}
if ( $problem [ 'hackable' ]) {
$data_disp -> addDisplayer ( 'standard' , $getDisplaySrcFunc ( 'std' ));
$data_disp -> addDisplayer ( 'validator' , $getDisplaySrcFunc ( 'val' ));
}
2018-07-09 02:40:30 +00:00
if ( isset ( $problem_conf [ 'interaction_mode' ])) {
$data_disp -> addDisplayer ( 'interactor' , $getDisplaySrcFunc ( 'interactor' ));
}
2016-07-18 16:39:37 +00:00
return $data_disp ;
} else {
return ( new DataDisplayer ( $problem_conf )) -> setProblemConfRowStatus ( 'use_builtin_judger' , 'danger' );
}
}
$data_disp = getDataDisplayer ();
if ( isset ( $_GET [ 'display_file' ])) {
if ( ! isset ( $_GET [ 'file_name' ])) {
echoFileNotFound ( '' );
} else {
$data_disp -> displayFile ( $_GET [ 'file_name' ]);
}
die ();
}
$hackable_form = new UOJForm ( 'hackable' );
$hackable_form -> handle = function () {
global $problem ;
$problem [ 'hackable' ] = ! $problem [ 'hackable' ];
2017-11-25 04:00:00 +00:00
//$problem['hackable'] = 0;
2019-06-14 15:30:02 +00:00
$ret = dataSyncProblemData ( $problem );
2016-07-18 16:39:37 +00:00
if ( $ret ) {
becomeMsgPage ( '<div>' . $ret . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
}
$hackable = $problem [ 'hackable' ] ? 1 : 0 ;
2017-11-25 15:29:18 +00:00
DB :: query ( " update problems set hackable = $hackable where id = ${ problem['id'] } " );
2016-07-18 16:39:37 +00:00
};
$hackable_form -> submit_button_config [ 'class_str' ] = 'btn btn-warning btn-block' ;
$hackable_form -> submit_button_config [ 'text' ] = $problem [ 'hackable' ] ? '禁止使用hack' : '允许使用hack' ;
$hackable_form -> submit_button_config [ 'smart_confirm' ] = '' ;
$data_form = new UOJForm ( 'data' );
$data_form -> handle = function () {
global $problem , $myUser ;
2018-07-09 02:40:30 +00:00
set_time_limit ( 60 * 5 );
2019-06-14 15:30:02 +00:00
$ret = dataSyncProblemData ( $problem , $myUser );
2016-07-18 16:39:37 +00:00
if ( $ret ) {
becomeMsgPage ( '<div>' . $ret . '</div><a href="/problem/' . $problem [ 'id' ] . '/manage/data">返回</a>' );
}
};
$data_form -> submit_button_config [ 'class_str' ] = 'btn btn-danger btn-block' ;
2019-06-14 15:30:02 +00:00
$data_form -> submit_button_config [ 'text' ] = '检验配置并同步数据' ;
2016-07-18 16:39:37 +00:00
$data_form -> submit_button_config [ 'smart_confirm' ] = '' ;
$clear_data_form = new UOJForm ( 'clear_data' );
$clear_data_form -> handle = function () {
global $problem ;
2019-06-14 15:30:02 +00:00
dataClearProblemData ( $problem );
2016-07-18 16:39:37 +00:00
};
$clear_data_form -> submit_button_config [ 'class_str' ] = 'btn btn-danger btn-block' ;
$clear_data_form -> submit_button_config [ 'text' ] = '清空题目数据' ;
$clear_data_form -> submit_button_config [ 'smart_confirm' ] = '' ;
$rejudge_form = new UOJForm ( 'rejudge' );
$rejudge_form -> handle = function () {
global $problem ;
rejudgeProblem ( $problem );
};
$rejudge_form -> succ_href = " /submissions?problem_id= { $problem [ 'id' ] } " ;
$rejudge_form -> submit_button_config [ 'class_str' ] = 'btn btn-danger btn-block' ;
$rejudge_form -> submit_button_config [ 'text' ] = '重测该题' ;
$rejudge_form -> submit_button_config [ 'smart_confirm' ] = '' ;
2018-07-09 02:40:30 +00:00
$rejudgege97_form = new UOJForm ( 'rejudgege97' );
$rejudgege97_form -> handle = function () {
global $problem ;
rejudgeProblemGe97 ( $problem );
};
$rejudgege97_form -> succ_href = " /submissions?problem_id= { $problem [ 'id' ] } " ;
$rejudgege97_form -> submit_button_config [ 'class_str' ] = 'btn btn-danger btn-block' ;
$rejudgege97_form -> submit_button_config [ 'text' ] = '重测 >=97 的程序' ;
$rejudgege97_form -> submit_button_config [ 'smart_confirm' ] = '' ;
2016-07-18 16:39:37 +00:00
$view_type_form = new UOJForm ( 'view_type' );
$view_type_form -> addVSelect ( 'view_content_type' ,
array ( 'NONE' => '禁止' ,
'ALL_AFTER_AC' => 'AC后' ,
'ALL' => '所有人'
),
'查看提交文件:' ,
$problem_extra_config [ 'view_content_type' ]
);
$view_type_form -> addVSelect ( 'view_all_details_type' ,
array ( 'NONE' => '禁止' ,
'SELF' => '仅自己' ,
'ALL_AFTER_AC' => 'AC后' ,
'ALL' => '所有人'
),
'查看全部详细信息:' ,
$problem_extra_config [ 'view_all_details_type' ]
);
$view_type_form -> addVSelect ( 'view_details_type' ,
array ( 'NONE' => '禁止' ,
'SELF' => '仅自己' ,
'ALL_AFTER_AC' => 'AC后' ,
'ALL' => '所有人'
),
'查看测试点详细信息:' ,
$problem_extra_config [ 'view_details_type' ]
);
$view_type_form -> handle = function () {
global $problem , $problem_extra_config ;
$config = $problem_extra_config ;
$config [ 'view_content_type' ] = $_POST [ 'view_content_type' ];
$config [ 'view_all_details_type' ] = $_POST [ 'view_all_details_type' ];
$config [ 'view_details_type' ] = $_POST [ 'view_details_type' ];
$esc_config = DB :: escape ( json_encode ( $config ));
2017-11-25 15:29:18 +00:00
DB :: query ( " update problems set extra_config = ' $esc_config ' where id = ' { $problem [ 'id' ] } ' " );
2016-07-18 16:39:37 +00:00
};
$view_type_form -> submit_button_config [ 'class_str' ] = 'btn btn-warning btn-block top-buffer-sm' ;
2022-09-29 01:27:11 +00:00
$solution_view_type_form = new UOJForm ( 'solution_view_type' );
$solution_view_type_form -> addVSelect ( 'view_solution_type' ,
array ( 'NONE' => '禁止' ,
'ALL_AFTER_AC' => 'AC后' ,
'ALL' => '所有人'
),
'查看题解:' ,
$problem_extra_config [ 'view_solution_type' ]
);
$solution_view_type_form -> addVSelect ( 'submit_solution_type' ,
array ( 'NONE' => '禁止' ,
'ALL_AFTER_AC' => 'AC后' ,
'ALL' => '所有人'
),
'提交题解:' ,
$problem_extra_config [ 'submit_solution_type' ]
);
$solution_view_type_form -> handle = function () {
global $problem , $problem_extra_config ;
$config = $problem_extra_config ;
$config [ 'view_solution_type' ] = $_POST [ 'view_solution_type' ];
$config [ 'submit_solution_type' ] = $_POST [ 'submit_solution_type' ];
$esc_config = DB :: escape ( json_encode ( $config ));
DB :: query ( " update problems set extra_config = ' $esc_config ' where id = ' { $problem [ 'id' ] } ' " );
};
$solution_view_type_form -> submit_button_config [ 'class_str' ] = 'btn btn-warning btn-block top-buffer-sm' ;
2022-09-29 02:10:24 +00:00
$difficulty_form = new UOJForm ( 'difficulty' );
$difficulty_form -> addVInput ( 'difficulty' , 'text' , '难度系数' , $problem_extra_config [ 'difficulty' ],
function ( $str ) {
if ( ! is_numeric ( $str )) {
return '难度系数必须是一个数字' ;
}
return '' ;
},
null );
$difficulty_form -> handle = function () {
global $problem , $problem_extra_config ;
$config = $problem_extra_config ;
$config [ 'difficulty' ] = $_POST [ 'difficulty' ] + 0 ;
$esc_config = DB :: escape ( json_encode ( $config ));
DB :: query ( " update problems set extra_config = ' $esc_config ' where id = ' { $problem [ 'id' ] } ' " );
};
$difficulty_form -> submit_button_config [ 'class_str' ] = 'btn btn-warning btn-block top-buffer-sm' ;
2016-07-18 16:39:37 +00:00
if ( $problem [ 'hackable' ]) {
$test_std_form = new UOJForm ( 'test_std' );
$test_std_form -> handle = function () {
global $myUser , $problem ;
$user_std = queryUser ( 'std' );
if ( ! $user_std ) {
2017-11-25 04:00:00 +00:00
becomeMsgPage ( '请建立"std"账号。' );
2016-07-18 16:39:37 +00:00
}
$requirement = json_decode ( $problem [ 'submission_requirement' ], true );
$zip_file_name = uojRandAvaiableSubmissionFileName ();
$zip_file = new ZipArchive ();
if ( $zip_file -> open ( UOJContext :: storagePath () . $zip_file_name , ZipArchive :: CREATE ) !== true ) {
becomeMsgPage ( '提交失败' );
}
$content = array ();
$content [ 'file_name' ] = $zip_file_name ;
$content [ 'config' ] = array ();
foreach ( $requirement as $req ) {
if ( $req [ 'type' ] == " source code " ) {
$content [ 'config' ][] = array ( " { $req [ 'name' ] } _language " , " C++ " );
}
}
$tot_size = 0 ;
foreach ( $requirement as $req ) {
$zip_file -> addFile ( " /var/uoj_data/ { $problem [ 'id' ] } /std.cpp " , $req [ 'file_name' ]);
$tot_size += $zip_file -> statName ( $req [ 'file_name' ])[ 'size' ];
}
$zip_file -> close ();
$content [ 'config' ][] = array ( 'validate_input_before_test' , 'on' );
$content [ 'config' ][] = array ( 'problem_id' , $problem [ 'id' ]);
$esc_content = DB :: escape ( json_encode ( $content ));
$esc_language = DB :: escape ( 'C++' );
2020-06-25 12:41:16 +00:00
$result = array ();
$result [ 'status' ] = " Waiting " ;
$result_json = json_encode ( $result );
2016-07-18 16:39:37 +00:00
$is_hidden = $problem [ 'is_hidden' ] ? 1 : 0 ;
DB :: insert ( " insert into submissions (problem_id, submit_time, submitter, content, language, tot_size, status, result, is_hidden) values ( { $problem [ 'id' ] } , now(), ' { $user_std [ 'username' ] } ', ' $esc_content ', ' $esc_language ', $tot_size , ' { $result [ 'status' ] } ', ' $result_json ', $is_hidden ) " );
};
$test_std_form -> succ_href = " /submissions?problem_id= { $problem [ 'id' ] } " ;
$test_std_form -> submit_button_config [ 'class_str' ] = 'btn btn-danger btn-block' ;
$test_std_form -> submit_button_config [ 'text' ] = '检验数据正确性' ;
$test_std_form -> runAtServer ();
}
$hackable_form -> runAtServer ();
$view_type_form -> runAtServer ();
2022-09-29 01:27:11 +00:00
$solution_view_type_form -> runAtServer ();
2022-09-29 02:10:24 +00:00
$difficulty_form -> runAtServer ();
2016-07-18 16:39:37 +00:00
$data_form -> runAtServer ();
$clear_data_form -> runAtServer ();
$rejudge_form -> runAtServer ();
2018-07-09 02:40:30 +00:00
$rejudgege97_form -> runAtServer ();
2016-07-18 16:39:37 +00:00
$info_form -> runAtServer ();
2022-09-18 04:58:35 +00:00
?>
2016-07-18 16:39:37 +00:00
< ? php
$REQUIRE_LIB [ 'dialog' ] = '' ;
2022-09-18 04:58:35 +00:00
?>
2016-07-18 16:39:37 +00:00
< ? php echoUOJPageHeader ( HTML :: stripTags ( $problem [ 'title' ]) . ' - 数据 - 题目管理' ) ?>
< h1 class = " page-header " align = " center " > #<?=$problem['id']?> : <?=$problem['title']?> 管理</h1>
< ul class = " nav nav-tabs " role = " tablist " >
2019-09-10 02:15:20 +00:00
< li class = " nav-item " >< a class = " nav-link " href = " /problem/<?= $problem['id'] ?>/manage/statement " role = " tab " > 编辑 </ a ></ li >
< li class = " nav-item " >< a class = " nav-link " href = " /problem/<?= $problem['id'] ?>/manage/managers " role = " tab " > 管理者 </ a ></ li >
< li class = " nav-item " >< a class = " nav-link active " href = " /problem/<?= $problem['id'] ?>/manage/data " role = " tab " > 数据 </ a ></ li >
< li class = " nav-item " >< a class = " nav-link " href = " /problem/<?= $problem['id'] ?> " role = " tab " > 返回 </ a ></ li >
2016-07-18 16:39:37 +00:00
</ ul >
< div class = " row " >
< div class = " col-md-10 top-buffer-sm " >
< div class = " row " >
< div class = " col-md-3 top-buffer-sm " id = " div-file_list " >
2019-09-10 02:15:20 +00:00
< ul class = " nav nav-pills flex-column " >
2016-07-18 16:39:37 +00:00
< ? php $data_disp -> echoDataFilesList ( 'problem.conf' ); ?>
</ ul >
</ div >
< div class = " col-md-9 top-buffer-sm " id = " div-file_content " >
< ? php $data_disp -> displayFile ( 'problem.conf' ); ?>
</ div >
< script type = " text/javascript " >
curFileName = '' ;
$ ( '#div-file_list a' ) . click ( function ( e ) {
2017-11-25 04:00:00 +00:00
$ ( '#div-file_content' ) . html ( '<h3>Loading...</h3>' );
2016-07-18 16:39:37 +00:00
$ ( this ) . tab ( 'show' );
var fileName = $ ( this ) . text ();
curFileName = fileName ;
$ . get ( '/problem/<?= $problem[' id '] ?>/manage/data' , {
display_file : '' ,
file_name : fileName
},
function ( data ) {
if ( curFileName != fileName ) {
return ;
}
$ ( '#div-file_content' ) . html ( data );
},
'html'
);
return false ;
});
</ script >
</ div >
</ div >
< div class = " col-md-2 top-buffer-sm " >
< div class = " top-buffer-md " >
< ? php if ( $problem [ 'hackable' ]) : ?>
< span class = " glyphicon glyphicon-ok " ></ span > hack功能已启用
< ? php else : ?>
< span class = " glyphicon glyphicon-remove " ></ span > hack功能已禁止
< ? php endif ?>
< ? php $hackable_form -> printHTML () ?>
</ div >
< div class = " top-buffer-md " >
< ? php if ( $problem [ 'hackable' ]) : ?>
< ? php $test_std_form -> printHTML () ?>
< ? php endif ?>
</ div >
< div class = " top-buffer-md " >
2019-09-10 02:15:20 +00:00
< button id = " button-display_view_type " type = " button " class = " btn btn-primary btn-block " onclick = " $ ('#div-view_type').toggle('fast'); " > 提交记录可视权限 </ button >
2016-07-18 16:39:37 +00:00
< div class = " top-buffer-sm " id = " div-view_type " style = " display:none; padding-left:5px; padding-right:5px; " >
< ? php $view_type_form -> printHTML (); ?>
</ div >
</ div >
2022-09-29 01:27:11 +00:00
< div class = " top-buffer-md " >
2022-09-29 02:10:24 +00:00
< button id = " button-solution_view_type " type = " button " class = " btn btn-primary btn-block " onclick = " $ ('#div-solution_view_type').toggle('fast'); " > 题解可视权限 </ button >
2022-09-29 01:27:11 +00:00
< div class = " top-buffer-sm " id = " div-solution_view_type " style = " display:none; padding-left:5px; padding-right:5px; " >
< ? php $solution_view_type_form -> printHTML (); ?>
</ div >
</ div >
2016-07-18 16:39:37 +00:00
< div class = " top-buffer-md " >
< ? php $data_form -> printHTML (); ?>
</ div >
< div class = " top-buffer-md " >
< ? php $clear_data_form -> printHTML (); ?>
</ div >
< div class = " top-buffer-md " >
< ? php $rejudge_form -> printHTML (); ?>
</ div >
2018-07-09 02:40:30 +00:00
< div class = " top-buffer-md " >
< ? php $rejudgege97_form -> printHTML (); ?>
</ div >
2017-11-25 04:00:00 +00:00
< div class = " top-buffer-md " >
< button type = " button " class = " btn btn-block btn-primary " data - toggle = " modal " data - target = " #UploadDataModal " > 上传数据 </ button >
</ div >
< div class = " top-buffer-md " >
< button type = " button " class = " btn btn-block btn-primary " data - toggle = " modal " data - target = " #ProblemSettingsFileModal " > 试题配置 </ button >
</ div >
2022-09-29 02:10:24 +00:00
< div class = " top-buffer-md " >
< button id = " button-difficulty " type = " button " class = " btn btn-block btn-primary " onclick = " $ ('#div-difficulty').toggle('fast'); " > 难度系数 </ button >
< div class = " top-buffer-sm " id = " div-difficulty " style = " display:none; padding-left:5px; padding-right:5px; " >
< ? php $difficulty_form -> printHTML (); ?>
</ div >
</ div >
2017-11-25 04:00:00 +00:00
</ div >
< div class = " modal fade " id = " UploadDataModal " tabindex = " -1 " role = " dialog " aria - labelledby = " myModalLabel " aria - hidden = " true " >
< div class = " modal-dialog " >
< div class = " modal-content " >
< div class = " modal-header " >
2019-09-10 02:15:20 +00:00
< h4 class = " modal-title " id = " myModalLabel " > 上传数据 </ h4 >
2017-11-25 04:00:00 +00:00
< button type = " button " class = " close " data - dismiss = " modal " >< span aria - hidden = " true " >& times ; </ span >< span class = " sr-only " > Close </ span ></ button >
</ div >
< div class = " modal-body " >
< form action = " " method = " post " enctype = " multipart/form-data " role = " form " >
< div class = " form-group " >
2019-04-16 14:42:19 +00:00
< label for = " exampleInputFile " > 上传zip文件 </ label >
2017-11-25 04:00:00 +00:00
< input type = " file " name = " problem_data_file " id = " problem_data_file " >
2019-08-02 11:00:37 +00:00
< p class = " help-block " > 说明:请将所有数据放置于压缩包根目录内。若压缩包内仅存在文件夹而不存在文件,则会将这些一级子文件夹下的内容移动到根目录下,然后这些一级子文件夹删除;若这些子文件夹内存在同名文件,则会发生随机替换,仅保留一个副本。 </ p >
2017-11-25 04:00:00 +00:00
</ div >
< input type = " hidden " name = " problem_data_file_submit " value = " submit " >
</ div >
< div class = " modal-footer " >
< button type = " submit " class = " btn btn-success " > 上传 </ button >
</ form >
2019-09-10 02:15:20 +00:00
< button type = " button " class = " btn btn-secondary " data - dismiss = " modal " > 关闭 </ button >
2017-11-25 04:00:00 +00:00
</ div >
</ div >
</ div >
</ div >
< div class = " modal fade " id = " ProblemSettingsFileModal " tabindex = " -1 " role = " dialog " aria - labelledby = " myModalLabel " aria - hidden = " true " >
< div class = " modal-dialog " >
< div class = " modal-content " >
< div class = " modal-header " >
2019-09-10 02:15:20 +00:00
< h4 class = " modal-title " id = " myModalLabel " > 试题配置 </ h4 >
2017-11-25 04:00:00 +00:00
< button type = " button " class = " close " data - dismiss = " modal " >< span aria - hidden = " true " >& times ; </ span >< span class = " sr-only " > Close </ span ></ button >
</ div >
< div class = " modal-body " >
< form class = " form-horizontal " action = " " method = " post " role = " form " >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " use_builtin_checker " class = " col-sm-5 control-label " > 比对函数 </ label >
< div class = " col-sm-7 " >
< select class = " form-control " id = " use_builtin_checker " name = " use_builtin_checker " >
2022-09-22 02:26:16 +00:00
< option value = " ncmp " > ncmp : 整数序列 </ option >
< option value = " wcmp " > wcmp : 字符串序列 </ option >
2022-09-28 05:52:49 +00:00
< option value = " lcmp " > lcmp : 多行数据(忽略行内与行末的多余空格,同时忽略文末回车) </ option >
2022-09-22 02:26:16 +00:00
< option value = " fcmp " > fcmp : 多行数据(不忽略行末空格,但忽略文末回车) </ option >
< option value = " rcmp4 " > rcmp4 : 浮点数序列(误差不超过 1e-4 ) </ option >
< option value = " rcmp6 " > rcmp6 : 浮点数序列(误差不超过 1e-6 ) </ option >
< option value = " rcmp9 " > rcmp9 : 浮点数序列(误差不超过 1e-9 ) </ option >
< option value = " yesno " > yesno : Yes、No( 不区分大小写) </ option >
< option value = " uncmp " > uncmp : 整数集合 </ option >
< option value = " bcmp " > bcmp : 二进制文件 </ option >
2022-09-23 03:50:56 +00:00
< option value = " ownchk " > 自定义校验器(需上传 chk . cpp) </ option >
2017-11-25 04:00:00 +00:00
</ select >
<!--< input type = " hidden " class = " form-control " id = " use_builtin_checker " name = " use_builtin_checker " placeholder = " 比对函数 " >-->
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " n_tests " class = " col-sm-5 control-label " > n_tests </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " n_tests " name = " n_tests " placeholder = " 数据点个数 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " n_ex_tests " class = " col-sm-5 control-label " > n_ex_tests </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " n_ex_tests " name = " n_ex_tests " placeholder = " 额外数据点个数 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " n_sample_tests " class = " col-sm-5 control-label " > n_sample_tests </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " n_sample_tests " name = " n_sample_tests " placeholder = " 样例测试点个数 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " input_pre " class = " col-sm-5 control-label " > input_pre </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " input_pre " name = " input_pre " placeholder = " 输入文件名称 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " input_suf " class = " col-sm-5 control-label " > input_suf </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " input_suf " name = " input_suf " placeholder = " 输入文件后缀 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " output_pre " class = " col-sm-5 control-label " > output_pre </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " output_pre " name = " output_pre " placeholder = " 输出文件名称 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " output_suf " class = " col-sm-5 control-label " > output_suf </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " output_suf " name = " output_suf " placeholder = " 输出文件后缀 " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " time_limit " class = " col-sm-5 control-label " > time_limit </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " time_limit " name = " time_limit " placeholder = " 时间限制(不能为小数!) " >
</ div >
</ div >
2019-09-10 02:15:20 +00:00
< div class = " form-group row " >
2017-11-25 04:00:00 +00:00
< label for = " memory_limit " class = " col-sm-5 control-label " > memory_limit </ label >
< div class = " col-sm-7 " >
< input type = " text " class = " form-control " id = " memory_limit " name = " memory_limit " placeholder = " 内存限制 " >
</ div >
</ div >
< input type = " hidden " name = " problem_settings_file_submit " value = " submit " >
</ div >
< div class = " modal-footer " >
< button type = " submit " class = " btn btn-success " > 确定 </ button >
</ form >
2019-09-10 02:15:20 +00:00
< button type = " button " class = " btn btn-secondary " data - dismiss = " modal " > 关闭 </ button >
2017-11-25 04:00:00 +00:00
</ div >
</ div >
</ div >
2016-07-18 16:39:37 +00:00
</ div >
</ div >
< ? php echoUOJPageFooter () ?>