ResultManager/subs/part/admin_backend.php

182 lines
5.9 KiB
PHP
Raw Permalink Normal View History

2019-08-08 13:58:29 +00:00
<?php
/**
* /subs/admin_backend.php
* @version 1.6
* @desc backend for admin tools
* @author Fándly Gergő Zoltán (fandlygergo@gmail.hu, systemtest.tk)
* @copy 2017 Fándly Gergő Zoltán
* License:
Result Manager for managing results of students in bilingual school systems.
Copyright (C) 2017 Fándly Gergő Zoltán
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
**/
try{
//import/step1: upload file to server
if(isset($_FILES['import_file'])){
//time limit of 2 min
set_time_limit(120);
//get file size and compare it if JS has sucked
$size=$_FILES['import_file']['size'];
if($size>10000000){
functions::setError(11);
echo "error";
}
else{
//get temp file to hold it
$target=tempnam(sys_get_temp_dir(), "resmanImp_");
//move file
if(!move_uploaded_file($_FILES['import_file']['tmp_name'], $target)){
//something's wrong here
functions::setError(13);
echo "error";
}
else{
//count lines
$lines=0;
$file=fopen($target, "r");
while(!feof($file)){
$line=fgets($file);
$lines++;
}
fclose($file);
//prepare session to track everything
$progress=array("total_lines"=>$lines, "lines_processed"=>0);
if(isset($_SESSION['progress'])){
$_SESSION['progress'][$target]=$progress;
}
else{
$_SESSION['progress']=array();
$_SESSION['progress'][$target]=$progress;
}
//echo file name (which is process identifier as well) to be able to track it
echo $target;
}
}
}
//import/step2: start file procession
if(isset($_POST['process_file'])){
//insert multiple records with the same query
$rowPerQuery=40;
//set a looong time limit (20 min)
set_time_limit(1200);
//don't stop execution even if the connection drops
ignore_user_abort(true);
//open file
$file=fopen($_POST['process_file'], "r");
//a simple counter
$rowProcessed=0;
//build query string
$querystr="INSERT INTO users (username, fullname, accesslevel, class, password) VALUES";
for($i=0; $i<$rowPerQuery; $i++){
$querystr.=" (?, ?, ?, ?, ?), ";
}
$querystr=rtrim($querystr, ", ");
//buffer to hold before insert
$buffer=array();
$rowBuffered=0;
//prepare SQL query
$sql=$db->prepare($querystr);
while($data=fgetcsv($file, 1000, ",")){
if(count($data)!=5){
continue;
}
else{
//add row to buffer
array_push($buffer, $data[0], $data[1], $data[2], $data[3], $data[4]);
$rowBuffered++;
//if needed, execute query
if($rowBuffered==$rowPerQuery){
$sql->execute($buffer);
$buffer=array();
$rowBuffered=0;
}
}
//update counter
$rowProcessed++;
//update status and close session to release write protect
if(session_status()==PHP_SESSION_NONE){
session_start();
}
$_SESSION['progress'][$_POST['process_file']]['lines_processed']=$rowProcessed;
session_write_close();
}
//if something remained in buffer
if($rowBuffered!=0){
//build new query for the remained records
$querystr="INSERT INTO users (username, fullname, accesslevel, class, password) VALUES";
for($i=0; $i<$rowBuffered; $i++){
$querystr.=" (?, ?, ?, ?, ?), ";
}
$querystr=rtrim($querystr, ", ");
$sql=$db->prepare($querystr);
//execute everything left over
$sql->execute($buffer);
}
//close, delete file and die (I leave the session there intentionally. I hope nobody will spam the session with 1 record imports lol)
fclose($file);
unlink($_POST['process_file']);
//some bogus stuff that actually fixes the ERR_RESPONSE_HEADERS_TOO_BIG error, because PHP wants to send a ton of set-cookie headers
header_remove("Set-Cookie");
die();
}
//import/step3: check status
if(isset($_GET['import_progress'])){
if(!isset($_SESSION['progress'][$_GET['import_progress']])){
//if it does not exist, echo 0
echo "error";
}
else{
$status=$_SESSION['progress'][$_GET['import_progress']];
//calculate percent
$percent=round($status['lines_processed']*100/$status['total_lines'], 1);
//print percent
echo $percent."%";
}
}
}
catch(Exception $e){
functions::setError(500);
error_log($e);
}