NxTIC/build/api/module/download.php

584 lines
17 KiB
PHP
Raw Permalink Normal View History

<?php
namespace api\module;
use \database\core\DatabaseDriver;
use \manager\sessionManager;
use \api\core\ModuleRequest;
use \manager\ManagerError;
use \database\core\Repo;
use \lightdb\core\lightdb;
class download{
/* CONSTRUIT UN CONTENU CSV A PARTIR DES DONNEES @DATA ET DU DICTIONNAIRE @DICT
*
* @data<Array> Tableau contenant les valeurs
* @dict<Array> Tableau contenant le dictionnaire des valeurs
* @displayColumns<Boolean> VRAI s'il faut afficher les colonnes
*
* @return csvContent<String> Retourne le contenu CSV associé
*
*/
private static function parseCSV($data, $dict, $displayColumns=true){
$output = ''; // Contiendra le résultat
$dictKeys = array_keys($dict); // Contient les clés de @dict
/* [0] On récupère toutes les colonnes
=========================================================*/
$columns = []; // Contiendra les colonnes
/* (1) Pour chaque set de @data */
foreach($data as $dataset){
$keys = [];
/* (2) Pour chaque champ de chaque set de @data, on ajoute les clés */
foreach($dataset as $key=>$value){
// {1} Si c'est un tableau -> on ajoute les sous-clés //
if( is_array($value) )
foreach($value as $subIndex=>$subValue)
array_push( $keys, "${key}_$subIndex" );
// {2} Si c'est une valeur simple -> on ajoute la clé //
else
array_push( $keys, $key );
}
/* (3) On ajoute à chaque fois les clés du set à la liste des colonnes */
$columns = array_unique( array_merge( $columns, $keys ) );
}
/* [1] On ajoute les colonnes à la sortie
=========================================================*/
if( $displayColumns )
foreach($columns as $i=>$column)
$output .= ($i < count($columns)-1) ? "\"$column\";" : "\"$column\"\r\n";
/* [2] On récupère les valeurs et on les ajoute à la sortie
=========================================================*/
/* (1) Pour chaque set de @data */
foreach($data as $dataset){
/* (2) Pour chaque colonne */
foreach($columns as $c=>$column){
/* (3) On décompose la colonne (ne change que si elle l'est) */
$col = explode('_', $column);
$composed = true;
// Si il n'existe pas une 2me partie numérique, on annule la décomposition
if( !isset($col[1]) || !is_numeric($col[1]) ){
$col = [ $column ];
$composed = false;
}
/* (4) Si la colonne existe dans le set actuel */
if( isset($dataset[$col[0]]) ){
/* (5) Si c'est une valeur composée, on récupère la valeur */
if( $composed && isset($dataset[$col[0]][$col[1]]) )
// {1} Si valeur dans le dictionnaire, on fait modulo le nombre de choix possibles //
if( isset($dict[$col[0]]) )
$output .= "\"".( $dataset[$col[0]][$col[1]] % count($dict[$col[0]]) )."\"";
// {2} Si pas dans le dictionnaire, on laisse la valeur //
else
$output .= "\"".$dataset[$col[0]][$col[1]]."\"";
/* (6) Si la valeur n'est pas composée, on récupère la valeur */
elseif( !$composed && !is_array($dataset[$col[0]]) )
$output .= "\"".$dataset[$col[0]]."\"";
}
// On ajoute une virgule sauf à la dernière valeur
$output .= ($c < count($columns)-1) ? ";" : "";
}
$output .= "\r\n";
}
return $output;
}
/* DOWNLOAD D'UN FICHIER CONTENANT LES DONNEES SELECTIONNEES
*
* @subjects<Array> Liste des identifiants des sujets à prendre en compte
* @all<Boolean> Si TRUE, prend en compte tous les sujets (annule @subjects)
*
* @return data<File> Retourne une archive .zip contenant toutes les données sélectionnées
*
*/
public static function multiple($params){
2016-05-17 14:51:24 +00:00
extract($params);
/* (0) Gestion du formattage des paramètres */
2016-11-22 10:06:03 +00:00
$subjects = !is_array($subjects) ? [] : $subjects;
$all = !is_bool($all) ? false : $all;
2016-05-18 08:08:34 +00:00
/* [0] On récupère le dictionnaire
=========================================================*/
2016-11-22 10:06:03 +00:00
$dict = file_get_contents(__BUILD__.'/lightdb/storage/dictionary.json');
/* (2) Si une erreur pour le fichier de conf */
if( $dict === false )
return [ 'ModuleError' => ManagerError::UnreachableResource ];
/* (3) On récupère la config sous forme de tableau */
$dict = json_decode( $dict, true );
/* (4) Si erreur de PARSAGE */
if( !is_array($dict) )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* [1] Initialisation
=========================================================*/
/* (1) Fichiers de sortie */
$output = [
'contacts.fiche' => '', // contiendra les contacts et leurs données fiches
'contacts.mini' => '', // contiendra les contacts et leurs données mini
'relations' => '', // contiendra les relations
'dict' => '' // contiendra le dictionnaire de valeurs
];
/* (2) Base de données */
$subjectdb = new lightdb('subject');
$contactdb = new lightdb('contact');
/* [2] On construit la liste des sujets
2016-11-22 10:06:03 +00:00
=========================================================*/
$subjectindexes = array_keys($subjectdb->index());
$subjectids = [];
2016-11-22 10:06:03 +00:00
/* (1) On récupère tous les sujets si c'est spécifié */
if( $all )
2016-11-22 10:06:03 +00:00
$subjectids = $subjectindexes;
2016-11-22 10:06:03 +00:00
/* (2) Sinon on retire les ids incorrects */
else
2016-11-22 10:06:03 +00:00
foreach($subjects as $i=>$id)
if( in_array($id, $subjectindexes) )
$subjectids[] = intval($id);
2016-11-22 10:06:03 +00:00
/* (3) Si aucun sujet restant -> error */
if( count($subjectids) === 0 )
return ['ModuleError' => ManagerError::ParamError];
2016-11-22 10:06:03 +00:00
/* [3] Export contacts/relations des sujets selectionnés
2016-05-17 14:51:24 +00:00
=========================================================*/
foreach($subjectids as $subid){
2016-05-18 08:08:34 +00:00
/* (1) On récupère les données du sujet */
$subject = $subjectdb->fetch($subid);
2016-05-18 08:08:34 +00:00
// si pas trouvé -> suivant
if( $subject === false )
continue;
/* (2) Si aucun contact -> suivant */
if( !isset($subject['contacts']) || !is_array($subject['contacts']) )
continue;
/* (3) Pour chaque contact */
foreach($subject['contacts'] as $c=>$contactid){
// {3.1} On récupère le contact //
$contact = $contactdb->fetch($contactid);
// si pas trouvé -> suivant
if( $contact === false )
continue;
// {3.2} On ajoute le contact au fichier des FICHES //
if( array_key_exists('studies2', $contact) )
// On affiche les colonnes pour le premier contact uniquement
$output['contacts.fiche'] .= self::parseCSV([$contact], $dict['contacts'], strlen($output['contacts.fiche']) == 0 );
// {3.3} On ajoute le contact au fichier des MINI //
if( array_key_exists('studies1', $contact) )
// On affiche les colonnes pour le premier contact uniquement
$output['contacts.mini'] .= self::parseCSV([$contact], $dict['contacts'], strlen($output['contacts.mini']) == 0 );
}
/* (4) Si aucune relation -> suivant */
if( !isset($subject['relations']) || !is_array($subject['relations']) )
continue;
/* (5) On ajoute les relations */
$output['relations'] .= self::parseCSV($subject['relations'], [], strlen($output['relations']) == 0 );
}
/* [5] On ajoute le dictionnaire
=========================================================*/
$output['dict'] .= "\"sheet\";\"field\";\"key\";\"value\"\r\n";
foreach($dict as $ds=>$dataset)
foreach($dataset as $f=>$field)
foreach($field as $key=>$value)
$output['dict'] .= "\"$ds\";\"$f\";\"$key\";\"$value\"\r\n";
/* [6] Création de l'archive
2016-05-17 14:51:24 +00:00
=========================================================*/
$zip = new \ZipArchive();
2016-11-22 10:06:03 +00:00
$fname = __TMP__.'/'.time().'.zip';
2016-05-17 14:51:24 +00:00
$zip->open($fname, \ZipArchive::CREATE);
2016-05-18 08:08:34 +00:00
foreach($output as $file=>$content)
if( strlen($content) > 0 )
$zip->addFromString($file.'.csv', $content);
2016-05-17 14:51:24 +00:00
$zip->close();
2016-05-17 14:51:24 +00:00
/* [5] On lance le téléchargement
=========================================================*/
return [
'ModuleError' => ManagerError::Success,
'headers' => [
'Content-Type' => 'application/zip; charset=utf-8',
2016-06-08 19:56:12 +00:00
'Content-Disposition' => 'attachment; filename=export'.date('_d_m_Y', time()).'.zip',
'Pragma' => 'no-cache',
'Expires' => '0'
],
'body' => file_get_contents($fname)
];
}
/* EXPORT POUR GEPHI OU AUTRE LOGICIEL SUR LE PRINCIPE NODES+EDGES
*
* @subjects<Array> Liste des identifiants des sujets à prendre en compte
* @phone<Boolean> Si TRUE, prend en compte les données des questionnaires cellulaires
* @facebook<Boolean> Si TRUE, prend en compte les données des questionnaires facebook
* @survey<Boolean> Si TRUE, prend en compte les données des questionnaires ResTIC
* @all<Boolean> Si TRUE, prend en compte tous les sujets (annule @subjects)
*
* @return data<File> Retourne une archive .zip contenant toutes les données sélectionnées
*/
public static function chart($params){
extract($params);
/* (0) Gestion du formattage des paramètres */
$subjects = !is_array($subjects) ? [] : $subjects;
$phone = !is_bool($phone) ? false : $phone;
$facebook = !is_bool($facebook) ? false : $facebook;
$survey = !is_bool($survey) ? false : $survey;
$all = !is_bool($all) ? false : $all;
/* [0] On récupère le dictionnaire
=========================================================*/
$dict = file_get_contents(__BUILD__.'/src/dynamic/dictionary.json');
/* (2) Si une erreur pour le fichier de conf */
if( $dict === false )
return [ 'ModuleError' => ManagerError::UnreachableResource ];
/* (3) On récupère la config sous forme de tableau */
$dict = json_decode( $dict, true );
/* (4) Si erreur de PARSAGE */
if( !is_array($dict) )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* [1] On construit l'arborescence des données
=========================================================*/
$output = [
'common_' => [
'contacts' => '',
'relations' => '',
'dict' => ''
],
'logs/' => [] // Contiendra les journaux d'appels
];
/* [2] On construit les fichiers de chaque sujet DE TELEPHONE
=========================================================*/
if( $phone ){ // Si @phone vaut TRUE
// On ouvre une instance de la base de données
$db = new lightdb('phone_db');
// Si on doit prendre tous les sujets, on les récupère
if( $all )
$subjects = array_keys( $db->index() );
// Pour chaque sujet
foreach($subjects as $s=>$subjectId){
/* (1) On récupère les données du sujet en cours */
$subjectData = $db->fetch($subjectId);
// Si on ne trouve rien, on passe au suivant
if( $subjectData === false )
continue;
/* (2) On construit le log s'il existe */
$output['logs/'][$subjectId] = self::parseCSV($subjectData['logs'], $dict['logs']);
/* (3) On complète les relations */
// {1} On retire les valeurs ou le type = 0 //
$formattedRelations = [];
foreach($subjectData['relations'] as $i=>$relation)
if( $relation['type'] != 0 )
array_push($formattedRelations, [
'source' => $relation['idA'],
'target' => $relation['idB'],
2016-06-02 16:52:12 +00:00
'weight' => ($relation['idA']==$subjectId) ? .1 : 1, // plus de poids aux relations alter/alter
'type' => 'Undirected'
]);
// {2} On ajoute au contenu //
$output['common_']['relations'] .= self::parseCSV($formattedRelations, [], strlen($output['common_']['relations']) == 0 ); // On affiche les colonnes pour la première fois uniquement
/* (4) On ajoute les contacts à la liste */
$output['common_']['contacts'] .= self::parseCSV($subjectData['contacts'], $dict['contacts'], strlen($output['common_']['contacts']) == 0 ); // On affiche les colonnes pour la première fois uniquement
}
// On ferme l'instance de la base de données
$db->close();
}
/* [3] On construit les fichiers de chaque sujet DE FACEBOOK
=========================================================*/
if( $facebook ){ // Si @facebook vaut TRUE
// On ouvre une instance de la base de données
$db = new lightdb('facebook_db');
// Si on doit prendre tous les sujets, on les récupère
if( $all )
$subjects = array_keys( $db->index() );
// Pour chaque sujet
foreach($subjects as $s=>$subjectId){
/* (1) On récupère les données du sujet en cours */
$subjectData = $db->fetch($subjectId);
// Si on ne trouve rien, on passe au suivant
if( $subjectData === false )
continue;
/* (2) On complète les relations */
// {1} On retire les valeurs ou le type = 0 //
$formattedRelations = [];
foreach($subjectData['relations'] as $i=>$relation)
if( $relation['type'] != 0 )
array_push($formattedRelations, [
'source' => $relation['idA'],
'target' => $relation['idB'],
2016-06-02 16:52:12 +00:00
'weight' => ($relation['idA']==$subjectId) ? .1 : 1, // plus de poids aux relations alter/alter
'type' => 'Undirected'
]);
// {2} On ajoute au contenu //
$output['common_']['relations'] .= self::parseCSV($formattedRelations, [], strlen($output['common_']['relations']) == 0 ); // On affiche les colonnes pour la première fois uniquement
/* (3) On ajoute les contacts à la liste */
$output['common_']['contacts'] .= self::parseCSV($subjectData['contacts'], $dict['contacts'], strlen($output['common_']['contacts']) == 0 ); // On affiche les colonnes pour la première fois uniquement
}
// On ferme l'instance de la base de données
$db->close();
}
/* [4] On construit les fichiers de chaque sujet DE FORMULAIRE
=========================================================*/
if( $survey ){ // Si @survey vaut TRUE
// On ouvre une instance de la base de données
$db = new lightdb('survey_db');
// Si on doit prendre tous les sujets, on les récupère
if( $all )
$subjects = array_keys( $db->index() );
// Pour chaque sujet
foreach($subjects as $s=>$subjectId){
/* (1) On récupère les données du sujet en cours */
$subjectData = $db->fetch($subjectId);
// Si on ne trouve rien, on passe au suivant
if( $subjectData === false )
continue;
/* (2) On complète les relations */
// {1} On retire les valeurs ou le type = 0 //
$formattedRelations = [];
foreach($subjectData['relations'] as $i=>$relation)
if( $relation['type'] != 0 ) // On retire les relations ego/alter
array_push($formattedRelations, [
'source' => $relation['idA'],
'target' => $relation['idB'],
2016-06-02 16:52:12 +00:00
'weight' => ($relation['idA']==$subjectId) ? .1 : 1, // plus de poids aux relations alter/alter
'type' => 'Undirected'
]);
// {2} On ajoute au contenu //
$output['common_']['relations'] .= self::parseCSV($formattedRelations, [], strlen($output['common_']['relations']) == 0 ); // On affiche les colonnes pour la première fois uniquement
/* (3) On ajoute les contacts à la liste */
$output['common_']['contacts'] .= self::parseCSV($subjectData['contacts'], $dict['contacts'], strlen($output['common_']['contacts']) == 0 ); // On affiche les colonnes pour la première fois uniquement
}
// On ferme l'instance de la base de données
$db->close();
}
/* [5] On ajoute le dictionnaire
=========================================================*/
$output['common_']['dict'] .= "\"sheet\";\"field\";\"key\";\"value\"\r\n";
foreach($dict as $ds=>$dataset)
foreach($dataset as $f=>$field)
foreach($field as $key=>$value)
$output['common_']['dict'] .= "\"$ds\";\"$f\";\"$key\";\"$value\"\r\n";
/* [6] Création de l'archive
=========================================================*/
$zip = new \ZipArchive();
2016-11-22 10:06:03 +00:00
$fname = __TMP__.'/'.time().'.zip';
$zip->open($fname, \ZipArchive::CREATE);
foreach($output as $folder=>$files){
foreach($files as $file=>$content)
if( strlen($content) > 0 )
$zip->addFromString($folder.$file.'.csv', $content);
}
$zip->close();
/* [5] On lance le téléchargement
=========================================================*/
return [
'ModuleError' => ManagerError::Success,
'headers' => [
'Content-Type' => 'application/zip; charset=utf-8',
2016-06-08 19:56:12 +00:00
'Content-Disposition' => 'attachment; filename=graphics'.date('_d_m_Y', time()).'.zip',
'Pragma' => 'no-cache',
'Expires' => '0'
],
'body' => file_get_contents($fname)
];
}
/* RENVOIE LE CONTENU DU MENU
*
*/
public static function menu($params){
extract($params);
$menu_json = json_decode( file_get_contents(__CONFIG__.'/menu.json'), true );
// si erreur
if( $menu_json == null )
return ['ModuleError' => ManagerError::ParsingFailed];
// si tout bon
return [
'ModuleError' => ManagerError::Success,
'menu' => $menu_json
];
}
}
?>