From 076fbbcde0088b3aeed7abf43bd22d8db4bbbf34 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 20 Feb 2018 01:31:19 +0100 Subject: [PATCH] Implemented data extraction from excel file forgot to add formations to groups --- .gitignore | 2 + build/api/module/Excel.php | 235 +++++++++++++++++++++++++++++++++++++ composer.json | 3 + composer.lock | 154 ++++++++++++++++++++++++ config/modules.json | 9 ++ 5 files changed, 403 insertions(+) create mode 100644 .gitignore create mode 100644 build/api/module/Excel.php create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecdf2d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +vendor +.idea diff --git a/build/api/module/Excel.php b/build/api/module/Excel.php new file mode 100644 index 0000000..3c011f0 --- /dev/null +++ b/build/api/module/Excel.php @@ -0,0 +1,235 @@ +setReadDataOnly(true); + $spreadsheet = $reader->load($_FILES["file"]["tmp_name"]); + + $spreadsheet->setActiveSheetIndex(0); + $UESpreadsheet = $spreadsheet->getActiveSheet(); + + /* + * Setting Up state variables + */ + + //current formation + $formation = ""; + //current UE code + $UECode = ""; + //current UE + $UE = []; + //array containing all the UEs + $allUE = []; + + /* + * declare the lambda that will add finalized UE to the array + */ + $addEU = function() use (&$UECode,&$allUE,&$UE){ + if($UECode != ""){ + if(isset($allUE[$UECode])){ + $counter = 1; + while(isset($allUE[$UECode.$counter])) $counter++; + + $allUE[$UECode.$counter] = $UE; + + }else{ + $allUE[$UECode] = $UE; + } + + $UE = []; + } + }; + + /* + * declaring the lambda tha twill extract the list of formation involved in the group + */ + $getFormations = function(?string $group) use (&$formation) : array{ + if(!$group) return [$formation]; + + //replace the generic "INFO" keyword by the actual formation + $group = str_replace("INFO",$formation,$group); + + //split the string + $groups = explode("+",$group); + + //trim the strings + $groups = array_map('trim', $groups); + + //delete empty strings + return array_filter($groups); + }; + + /* + * declaring the lambda that will compute the part of internal students in the course (used for stats purpose) + */ + $getInternalStudentPart = function(?string $group) use (&$formation, $getFormations) : float{ + + if(!$group) return 1.0; + + $groups = $getFormations($group); + + if(!in_array($formation,$groups)){ + return 0.0; + }else{ + return 1/count($groups); + } + }; + + //starting the iteration + foreach($UESpreadsheet->getRowIterator() as $row){ + //skip the first rows + if($row->getRowIndex() < Excel::startLineUE) continue; + + + $firstCellValue = $UESpreadsheet->getCellByColumnAndRow(1,$row->getRowIndex())->getValue(); + $secondCellValue = $UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex())->getValue(); + + //if the first value is not null and the second is, this means we change formation and rest the UUCode + if($secondCellValue == "" and $firstCellValue != "") {$formation = $firstCellValue; $addEU(); $UECode = ""; continue; } + + //if no UE is set yet, find it + if($UECode == "" and $firstCellValue != "") $UECode = $firstCellValue; + + //if the line is empty this means we change UE + if($firstCellValue == "" and $secondCellValue == "") {$addEU(); $UECode = ""; continue;} + + //now we have a formation, a UE and we are sure the line is not empty, let's fill up this bad boy + + //if the required field is not set this means we are at the header of the UE + if(!isset($UE["required"])){ + $UE["name"] = $UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex())->getCalculatedValue(); + $UE["required"] = $UESpreadsheet->getCellByColumnAndRow(3,$row->getRowIndex())->getValue(); + $UE["TotalVH"] = $UESpreadsheet->getCellByColumnAndRow(4,$row->getRowIndex())->getCalculatedValue(); + + $UE["CourseVH"] = $UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getValue() ?: 0.0; + $UE["CourseGroup"] = $UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue() ?: 0; + + $UE["TdVH"] = $UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getValue() ?: 0.0; + $UE["TdGroup"] = $UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getValue() ?: 0; + + $UE["TpVH"] = $UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getValue() ?: 0.0; + $UE["TpGroup"] = $UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getValue() ?: 0; + + continue; + } + + //we have a new group! if the array is not set, initialize it + if(!isset($UE["groups"])) $UE["groups"] = [ + "Course" => [], + "TD" => [], + "TP" => [] + ]; + + //compute Course + if ($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue()){ + $UE["groups"]["Course"][] = [ + "VH" => $UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "professor" => $UESpreadsheet->getCellByColumnAndRow(7,$row->getRowIndex())->getValue() ?: null + ]; + } + + //compute TDs + if($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue()){ + $UE["groups"]["TD"][] = [ + "VH" => $UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "professor" => $UESpreadsheet->getCellByColumnAndRow(10,$row->getRowIndex())->getValue() ?: null + ]; + } + + //compute TPs + if($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue()){ + $UE["groups"]["TP"][] = [ + "VH" => $UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "professor" => $UESpreadsheet->getCellByColumnAndRow(13,$row->getRowIndex())->getValue() ?: null + ]; + } + + } + + /* + * Now we compute the professor list to get the full name , the number of hour he must do and the category he is in + */ + + $spreadsheet->setActiveSheetIndex(1); + $ProfSpreadshit = $spreadsheet->getActiveSheet(); + + //array containing all the professors + $allProf = []; + + //current professor category + $currentCategory = ""; + + //category as represented in the excel (as a number) + $currentCategoryIndex = 0; + + foreach($ProfSpreadshit->getRowIterator() as $row){ + + //skip the first lines + if($row->getRowIndex() < Excel::startLineProf) continue; + + $firstCellValue = $ProfSpreadshit->getCellByColumnAndRow(2,$row->getRowIndex())->getValue(); + $secondCellValue = $ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue(); + + //skip empty lines + if(!$firstCellValue and !$secondCellValue) continue; + + //if the first cell contains something and not the second, it means that we change category + if($firstCellValue && !$secondCellValue){ + $currentCategory = $firstCellValue; + $currentCategoryIndex++; + } + + //if the line is valid + if($ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue() and $ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue()){ + $allProf[$ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue()] = [ + "categoryLabel" => $currentCategory, + "categoryIndex" => $currentCategoryIndex, + "lastName" => explode(" ",$ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue(),2)[1], + "firstName" => explode(" ",$ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue(),2)[0], + "hoursToDo" => $ProfSpreadshit->getCellByColumnAndRow(5,$row->getRowIndex())->getValue() ?: 0 + ]; + } + + } + + + + return [ 'data' => ["professors" => $allProf, "UEs" => $allUE ] ]; + }catch (Exception $e){ + return [ 'error' => new Error(Err::UnknownError) ]; + } + + }else{ + return [ 'error' => new Error(Err::UploadError) ]; + } + } + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 0dca2c6..e26b2de 100644 --- a/composer.json +++ b/composer.json @@ -23,5 +23,8 @@ "router\\": "build/router" }, "files": ["autoloader.php"] + }, + "require": { + "phpoffice/phpspreadsheet": "^1.1" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3ece352 --- /dev/null +++ b/composer.lock @@ -0,0 +1,154 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "1e36e5a5313eb5645d060a32fb93ac57", + "packages": [ + { + "name": "phpoffice/phpspreadsheet", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", + "reference": "a2771e562e3a17c0d512d2009e38fd628beece90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a2771e562e3a17c0d512d2009e38fd628beece90", + "reference": "a2771e562e3a17c0d512d2009e38fd628beece90", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-iconv": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-xmlwriter": "*", + "ext-zip": "*", + "ext-zlib": "*", + "php": "^5.6|^7.0", + "psr/simple-cache": "^1.0" + }, + "require-dev": { + "dompdf/dompdf": "^0.8.0", + "friendsofphp/php-cs-fixer": "@stable", + "jpgraph/jpgraph": "^4.0", + "mpdf/mpdf": "^7.0.0", + "phpunit/phpunit": "^5.7", + "squizlabs/php_codesniffer": "^2.7", + "tecnickcom/tcpdf": "^6.2" + }, + "suggest": { + "dompdf/dompdf": "Option for rendering PDF with PDF Writer", + "ext-dom": "Option to read and write HTML files", + "ext-gd": "Required for exact column width autocalculation", + "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers", + "mpdf/mpdf": "Option for rendering PDF with PDF Writer", + "tecnick.com/tcpdf": "Option for rendering PDF with PDF Writer" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "http://blog.maartenballiauw.be" + }, + { + "name": "Erik Tilt" + }, + { + "name": "Franck Lefevre", + "homepage": "http://rootslabs.net" + }, + { + "name": "Mark Baker", + "homepage": "http://markbakeruk.net" + } + ], + "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "https://github.com/PHPOffice/PhpSpreadsheet", + "keywords": [ + "OpenXML", + "excel", + "gnumeric", + "ods", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2018-01-28T12:37:15+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24", + "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-01-02T13:31:39+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/config/modules.json b/config/modules.json index 3f64396..cd5aded 100644 --- a/config/modules.json +++ b/config/modules.json @@ -61,6 +61,15 @@ } }, + "Excel":{ + "POST": { + "des": "Import data from an Excel file", + "per": [], + "par": { + } + } + }, + "a": { "b": {