Tableau contenant les valeurs * @dict Tableau contenant le dictionnaire des valeurs * @displayColumns VRAI s'il faut afficher les colonnes * * @return csvContent 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 Liste des identifiants des sujets à prendre en compte * @all Si TRUE, prend en compte tous les sujets (annule @subjects) * * @return data Retourne une archive .zip contenant toutes les données sélectionnées * */ public static function multiple($params){ extract($params); /* (0) Gestion du formattage des paramètres */ $subjects = !is_array($subjects) ? [] : $subjects; $all = !is_bool($all) ? false : $all; /* [0] On récupère le dictionnaire =========================================================*/ $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 =========================================================*/ $subjectindexes = array_keys($subjectdb->index()); $subjectids = []; /* (1) On récupère tous les sujets si c'est spécifié */ if( $all ) $subjectids = $subjectindexes; /* (2) Sinon on retire les ids incorrects */ else foreach($subjects as $i=>$id) if( in_array($id, $subjectindexes) ) $subjectids[] = intval($id); /* (3) Si aucun sujet restant -> error */ if( count($subjectids) === 0 ) return ['ModuleError' => ManagerError::ParamError]; /* [3] Export contacts/relations des sujets selectionnés =========================================================*/ foreach($subjectids as $subid){ /* (1) On récupère les données du sujet */ $subject = $subjectdb->fetch($subid); // 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 =========================================================*/ $zip = new \ZipArchive(); $fname = __TMP__.'/'.time().'.zip'; $zip->open($fname, \ZipArchive::CREATE); foreach($output as $file=>$content) if( strlen($content) > 0 ) $zip->addFromString($file.'.csv', $content); $zip->close(); /* [5] On lance le téléchargement =========================================================*/ return [ 'ModuleError' => ManagerError::Success, 'headers' => [ 'Content-Type' => 'application/zip; charset=utf-8', '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 Liste des identifiants des sujets à prendre en compte * @all Si TRUE, prend en compte tous les sujets (annule @subjects) * * @return data 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; $all = !is_bool($all) ? false : $all; /* [0] On récupère le dictionnaire =========================================================*/ $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 = [ 'gephi.nodes' => '', // contiendra les contacts et leurs données 'gephi.edges' => '', // 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 =========================================================*/ $subjectindexes = array_keys($subjectdb->index()); $subjectids = []; /* (1) On récupère tous les sujets si c'est spécifié */ if( $all ) $subjectids = $subjectindexes; /* (2) Sinon on retire les ids incorrects */ else foreach($subjects as $i=>$id) if( in_array($id, $subjectindexes) ) $subjectids[] = intval($id); /* (3) Si aucun sujet restant -> error */ if( count($subjectids) === 0 ) return ['ModuleError' => ManagerError::ParamError]; /* [3] Export contacts/relations des sujets selectionnés =========================================================*/ foreach($subjectids as $subid){ /* (1) On récupère les données du sujet */ $subject = $subjectdb->fetch($subid); // 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 $contact['type'] = 'fiche'; $output['gephi.nodes'] .= self::parseCSV([$contact], $dict['contacts'], strlen($output['gephi.nodes']) == 0 ); // {3.3} On ajoute le contact au fichier des MINI // }elseif( array_key_exists('studies1', $contact) ){ // On affiche les colonnes pour le premier contact uniquement $contact['type'] = 'mini'; $output['gephi.nodes'] .= self::parseCSV([$contact], $dict['contacts'], strlen($output['gephi.nodes']) == 0 ); } } /* (4) Si aucune relation -> suivant */ if( !isset($subject['relations']) || !is_array($subject['relations']) ) continue; /* (5) On ajoute les relations */ foreach($subject['relations'] as $r=>$rel) $output['gephi.edges'] .= self::parseCSV( [[ 'source' => $rel['idA'], 'target' => $rel['idB'], 'weight' => ($rel['idA']==$subid) ? .5 : 1, 'type' => 'Undirected' ]], [], strlen($output['gephi.edges']) == 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 =========================================================*/ $zip = new \ZipArchive(); $fname = __TMP__.'/'.time().'.zip'; $zip->open($fname, \ZipArchive::CREATE); foreach($output as $file=>$content) if( strlen($content) > 0 ) $zip->addFromString($file.'.csv', $content); $zip->close(); /* [5] On lance le téléchargement =========================================================*/ return [ 'ModuleError' => ManagerError::Success, 'headers' => [ 'Content-Type' => 'application/zip; charset=utf-8', '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 ]; } } ?>