Updates fusionax scripts for better compliance.
[platal.git] / modules / fusionax.php
CommitLineData
b9ad0878
PC
1<?php
2/***************************************************************************
3 * Copyright (C) 2003-2007 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
c15c0053
PC
22/**
23 * @brief Module to merge data from AX database
24 *
25 * Module to import data from another database of alumni that had
26 * different schemas. The organization that used this db is called AX
27 * hence the name of this module.
28 *
29 * Datas are stored in an external server and you need a private key
30 * to connect to their server.
31 */
b9ad0878
PC
32class FusionAxModule extends PLModule{
33
c15c0053
PC
34 /// path ok private key file to connect to AX server
35 var $ax_xorg_rsa_key;
36
37 function __construct()
38 {
22f043e4
SJ
39 /*$this->ax_xorg_rsa_key =
40 dirname(__FILE__).'/../configs/ax_xorg_rsa.pem';*/
c15c0053 41 }
9cb8882b 42
b9ad0878
PC
43 function handlers()
44 {
45 return array(
46 'fusionax' => $this->make_hook('index', AUTH_MDP, 'admin'),
e8591429 47 'fusionax/import' => $this->make_hook('import', AUTH_MDP,'admin'),
b9ad0878
PC
48 'fusionax/ids' => $this->make_hook('ids', AUTH_MDP, 'admin'),
49 'fusionax/misc' => $this->make_hook('misc', AUTH_MDP, 'admin'),
50 );
51 }
c15c0053
PC
52
53
b9ad0878
PC
54 function handler_index(&$page)
55 {
56 global $globals;
57 $page->changeTpl('fusionax/index.tpl');
58 $page->assign('xorg_title','Polytechnique.org - Fusion des annuaires');
e8591429
PC
59 if (isset($globals->fusionax) &&
60 isset($globals->fusionax->LastUpdate)) {
61 $page->assign(
62 'lastimport',
63 date("d-m-Y",$globals->fusionax->LastUpdate));
b9ad0878
PC
64 }
65 }
22f043e4 66
cc8ea8b2 67 /** Import de l'annuaire de l'AX depuis l'export situé sur leur serveur */
b9ad0878
PC
68 function handler_import(&$page, $action = 'index', $fileSQL = '')
69 {
70 if ($action == 'index') {
71 $page->changeTpl('fusionax/import.tpl');
72 $page->addJsLink('jquery.js');
73 global $globals;
e8591429
PC
74 if (isset($globals->fusionax) &&
75 isset($globals->fusionax->LastUpdate)) {
76 $page->assign(
77 'lastimport',
78 "le ".date("d/m/Y à H:i",$globals->fusionax->LastUpdate));
b9ad0878 79 }
22f043e4 80 /*if (!file_exists($this->ax_xorg_rsa_key)) {
e8591429
PC
81 $page->assign(
82 'keymissing',
eb227060 83 $this->ax_xorg_rsa_key);
22f043e4 84 }*/
b9ad0878
PC
85 return;
86 }
22f043e4 87
cc8ea8b2 88 // toutes les actions sont faites en ajax en utilisant jquery
b9ad0878 89 header("Content-type: text/javascript; charset=utf-8");
22f043e4 90
cc8ea8b2
PC
91 // log des actions
92 $report = array();
22f043e4 93
cc8ea8b2 94 // création d'un fichier temporaire si nécessaire
b9ad0878
PC
95 if (Env::has('tmpdir')) {
96 $tmpdir = Env::v('tmpdir');
97 } else {
b9ad0878
PC
98 $tmpdir = tempnam('/tmp', 'fusionax');
99 unlink($tmpdir);
100 mkdir($tmpdir);
cc8ea8b2 101 chmod($tmpdir, 0700);
e8591429
PC
102 // copie la clef d'authentification (paire de clef RSA dont la
103 // partie publique est sur polytechniciens.com)
22f043e4 104 /*if (!copy(
eb227060 105 $this->ax_xorg_rsa_key,
e8591429
PC
106 $tmpdir.'/ax_xorg_rsa'))
107 $report[] = 'Impossible de copier la clef pour se logger '.
108 'au serveur AX';
22f043e4 109 chmod($tmpdir.'/ax_xorg_rsa', 0600);*/
b9ad0878 110 }
22f043e4 111
b9ad0878
PC
112 $modulepath = realpath(dirname(__FILE__).'/fusionax/').'/';
113 $olddir = getcwd();
114 chdir($tmpdir);
22f043e4 115
b9ad0878 116 if ($action == 'launch') {
e8591429
PC
117 // lancement : connexion en ssh et récupération du fichier depuis
118 // polyechniciens.com, décompression de l'archive et séparation en
119 // fichiers par tables
b9ad0878
PC
120 exec($modulepath.'import-ax.sh', $report);
121 $report[] = utf8_decode('Récupération du fichier terminé.');
122 $report[] = 'Import dans la base en cours...';
123 $next = 'integrateSQL';
124 } else if ($action == 'integrateSQL') {
cc8ea8b2
PC
125 // intégration des données dans la base MySQL
126 // liste des fichiers sql à exécuter
127 $filesSQL = array(
128 'Activites.sql',
129 'Adresses.sql',
130 'Anciens.sql',
131 'Formations.sql',
132 'Entreprises.sql');
b9ad0878 133 if ($fileSQL != '') {
cc8ea8b2 134 // récupère le contenu du fichier sql
b9ad0878
PC
135 $queries = explode(';',file_get_contents($modulepath.$fileSQL));
136 foreach ($queries as $q) if (trim($q)) {
cc8ea8b2 137 // coupe le fichier en requêtes individuelles
b9ad0878 138 if (substr($q,0,2) == '--') {
cc8ea8b2 139 // affiche les commentaires dans le report
b9ad0878
PC
140 $lines = explode("\n",$q);
141 $l = $lines[0];
142 $report[] = addslashes(utf8_decode($l));
143 }
cc8ea8b2 144 // exécute la requête
b9ad0878
PC
145 XDB::execute($q);
146 }
cc8ea8b2
PC
147 // trouve le prochain fichier à exécuter
148 $trans = array_flip($filesSQL);
149 $nextfile = $trans[$fileSQL] + 1;
b9ad0878
PC
150 } else {
151 $nextfile = 0;
152 }
153 if (!isset($filesSQL[$nextfile])) {
e8591429
PC
154 // tous les fichiers ont été exécutés, on passe à l'étape
155 // suivante
b9ad0878
PC
156 $next = 'clean';
157 } else {
cc8ea8b2 158 // on passe au fichier suivant
b9ad0878
PC
159 $next = 'integrateSQL/'.$filesSQL[$nextfile];
160 }
161 } else if ($action == 'clean') {
cc8ea8b2 162 // nettoyage du fichier temporaire
b9ad0878
PC
163 chdir($olddir);
164 exec("rm -rf $tmpdir", $report);
165 $report[] = 'Fin de l\'import';
166 global $globals;
cc8ea8b2 167 // met à jour la date de dernier import
e8591429
PC
168 $globals->change_dynamic_config(
169 array('LastUpdate' => time()),
170 'FusionAx');
b9ad0878
PC
171 }
172 $tmpdir = getcwd();
173 chdir($olddir);
174 foreach($report as $t)
cc8ea8b2 175 // affiche les lignes de report
b9ad0878
PC
176 echo "$('#fusionax_import').append('".utf8_encode($t)."<br/>');\n";
177 if (isset($next)) {
cc8ea8b2 178 // lance le prochain script s'il y en a un
e8591429
PC
179 echo "$.getScript('fusionax/import/".$next."?tmpdir=".
180 urlencode($tmpdir)."');";
b9ad0878 181 }
cc8ea8b2 182 // exit pour ne pas afficher la page template par défaut
b9ad0878
PC
183 exit;
184 }
22f043e4 185
b65beb64
PC
186 /** Lier les identifiants d'un ancien dans les deux annuaires
187 * @param user_id identifiant dans l'annuaire X.org
188 * @param matricule_ax identifiant dans l'annuaire de l'AX
189 * @return 0 si la liaison a échoué, 1 sinon
22f043e4 190 */
b9ad0878
PC
191 private static function link_by_ids($user_id, $matricule_ax)
192 {
e8591429
PC
193 if (!XDB::execute("
194 UPDATE fusionax_import AS i
195 INNER JOIN fusionax_xorg_anciens AS u
196 SET
197 u.matricule_ax = i.id_ancien,
198 i.user_id = u.user_id,
199 i.date_match_id = NOW()
b9ad0878 200 WHERE
e8591429
PC
201 i.id_ancien = {?} AND u.user_id = {?} AND (
202 u.matricule_ax != {?} OR u.matricule_ax IS NULL OR
203 i.user_id != {?} OR i.user_id IS NULL)",
204 $matricule_ax,
205 $user_id,
206 $matricule_ax,
207 $user_id))
b9ad0878
PC
208 {
209 return 0;
210 }
211 return XDB::affectedRows() / 2;
212 }
22f043e4 213
b65beb64
PC
214 /** Recherche automatique d'anciens à lier entre les deux annuaires
215 * @param limit nombre d'anciens à trouver au max
216 * @param sure si true, ne trouve que des anciens qui sont quasi sûrs
e8591429
PC
217 * @return un XOrgDBIterator sur les entrées avec display_name, promo,
218 * user_id, id_ancien et display_name_ax
22f043e4 219 */
b65beb64 220 private static function find_easy_to_link($limit = 10, $sure = false)
b9ad0878 221 {
e8591429
PC
222 $easy_to_link = XDB::iterator("
223 SELECT
224 xorg.display_name, xorg.promo, xorg.user_id, ax.id_ancien,
225 CONCAT(ax.prenom,' ',ax.nom_complet,' (X ',ax.promotion_etude,')')
226 AS display_name_ax,
b65beb64 227 COUNT(*) AS nbMatches
e8591429
PC
228 FROM fusionax_anciens AS ax
229 INNER JOIN fusionax_import AS i ON (
230 i.id_ancien = ax.id_ancien AND i.user_id IS NULL)
231 LEFT JOIN fusionax_xorg_anciens AS xorg ON (
232 xorg.matricule_ax IS NULL AND
233 ax.Nom_complet = xorg.nom AND
234 ax.prenom = xorg.prenom AND
235 xorg.promo = ax.promotion_etude)
236 GROUP BY xorg.user_id
237 HAVING
238 xorg.user_id IS NOT NULL AND
239 nbMatches = 1
b65beb64
PC
240 ".($limit?('LIMIT '.$limit):''));
241 if ($easy_to_link->total() > 0 || $sure) {
242 return $easy_to_link;
243 }
e8591429
PC
244 return XDB::iterator("
245 SELECT
246 xorg.display_name, xorg.promo, xorg.user_id, ax.id_ancien,
247 CONCAT(ax.prenom,' ',ax.nom_complet,' (X ',ax.promotion_etude,')')
248 AS display_name_ax,
cc8ea8b2 249 COUNT(*) AS nbMatches
e8591429
PC
250 FROM fusionax_anciens AS ax
251 INNER JOIN fusionax_import AS i ON (
252 i.id_ancien = ax.id_ancien AND i.user_id IS NULL)
253 LEFT JOIN fusionax_xorg_anciens AS xorg ON (
254 xorg.matricule_ax IS NULL AND
255 (ax.Nom_complet = xorg.nom
256 OR ax.Nom_complet LIKE CONCAT(xorg.nom,' %')
257 OR ax.Nom_complet LIKE CONCAT(xorg.nom,'-%')
258 OR ax.Nom_usuel = xorg.nom
259 OR xorg.nom LIKE CONCAT('% ',ax.Nom_complet)) AND
260 xorg.promo < ax.promotion_etude + 2 AND
261 xorg.promo > ax.promotion_etude - 2)
262 GROUP BY xorg.user_id
263 HAVING
264 xorg.user_id IS NOT NULL AND
265 nbMatches = 1
266 ".($limit?('LIMIT '.$limit):''));
b9ad0878 267 }
22f043e4 268
b65beb64 269 /** Module de mise en correspondance les ids */
e8591429
PC
270 function handler_ids(
271 &$page,
272 $part = 'main',
273 $user_id = null,
274 $matricule_ax = null)
b9ad0878
PC
275 {
276 global $globals;
b65beb64 277 $page->addJsLink('jquery.js');
22f043e4 278
e8591429
PC
279 $page->assign(
280 'xorg_title',
281 'Polytechnique.org - Fusion - Mise en correspondance simple');
b9ad0878
PC
282 if ($part == 'missingInAX')
283 {
284 // locate all persons from this database that are not in AX's
285 $page->changeTpl('fusionax/idsMissingInAx.tpl');
e8591429
PC
286 $missingInAX = XDB::iterator("SELECT
287 u.promo, u.user_id, u.display_name
288 FROM fusionax_xorg_anciens AS u
289 WHERE u.matricule_ax IS NULL
b9ad0878
PC
290 LIMIT 20");
291 $page->assign('missingInAX', $missingInAX);
292 return;
293 }
294 if ($part == 'missingInXorg')
295 {
296 // locate all persons from AX's database that are not here
297 $page->changeTpl('fusionax/idsMissingInXorg.tpl');
e8591429
PC
298 $missingInXorg = XDB::iterator("SELECT
299 a.promotion_etude AS promo,
300 CONCAT(a.prenom, ' ',a.Nom_usuel) AS display_name,
301 a.id_ancien
302 FROM fusionax_import
303 INNER JOIN fusionax_anciens AS a USING (id_ancien)
304 WHERE fusionax_import.user_id IS NULL
b9ad0878
PC
305 LIMIT 20");
306 $page->assign('missingInXorg', $missingInXorg);
307 return;
308 }
309 if ($part == 'link')
310 {
cc8ea8b2 311 FusionAxModule::link_by_ids($user_id,$matricule_ax);
b65beb64 312 exit;
b9ad0878
PC
313 }
314 if ($part == 'linknext')
315 {
316 $linksToDo = FusionAxModule::find_easy_to_link(10);
317 while ($l = $linksToDo->next())
318 {
319 FusionAxModule::link_by_ids($l['user_id'],$l['id_ancien']);
320 }
b65beb64 321 pl_redirect('fusionax/ids#autolink');
b9ad0878
PC
322 }
323 if ($part == 'linkall')
324 {
325 $linksToDo = FusionAxModule::find_easy_to_link(0);
326 while ($l = $linksToDo->next())
327 {
328 FusionAxModule::link_by_ids($l['user_id'],$l['id_ancien']);
329 }
330 }
331 {
332 $page->changeTpl('fusionax/ids.tpl');
e8591429
PC
333 $missingInAX = XDB::query(
334 'SELECT COUNT(*)
335 FROM fusionax_xorg_anciens AS u
336 WHERE u.matricule_ax IS NULL');
b9ad0878
PC
337 if ($missingInAX)
338 {
339 $page->assign('nbMissingInAX', $missingInAX->fetchOneCell());
340 }
e8591429
PC
341 $missingInXorg = XDB::query(
342 'SELECT COUNT(*)
343 FROM fusionax_import AS i
344 WHERE i.user_id IS NULL');
b9ad0878
PC
345 if ($missingInXorg)
346 {
e8591429
PC
347 $page->assign(
348 'nbMissingInXorg',
349 $missingInXorg->fetchOneCell());
b9ad0878
PC
350 }
351 $easyToLink = FusionAxModule::find_easy_to_link(10);
352 if ($easyToLink->total() > 0)
353 {
354 $page->assign('easyToLink', $easyToLink);
355 }
356 }
357 }
22f043e4 358
b9ad0878
PC
359 function handler_misc(&$page)
360 {
361 $page->changeTpl('fusionax/misc.tpl');
362 // deceased
e8591429
PC
363 $deceasedErrorsSql = XDB::query(
364 'SELECT COUNT(*) FROM fusionax_deceased');
b9ad0878 365 $page->assign('deceasedErrors',$deceasedErrorsSql->fetchOneCell());
e8591429
PC
366 $page->assign('deceasedMissingInXorg',XDB::iterator(
367 'SELECT
56637adc
PC
368 d.user_id,d.id_ancien,d.nom,d.prenom,d.promo,d.deces_ax,
369 CONCAT(d.prenom, " ", d.nom) AS display_name
e8591429
PC
370 FROM fusionax_deceased AS d
371 WHERE d.deces_xorg = "0000-00-00"
372 LIMIT 10'));
373 $page->assign('deceasedMissingInAX',XDB::iterator(
374 'SELECT
56637adc
PC
375 d.user_id,d.id_ancien,d.nom,d.prenom,d.promo,d.deces_xorg,
376 CONCAT(d.prenom, " ", d.nom) AS display_name
e8591429
PC
377 FROM fusionax_deceased AD d
378 WHERE d.deces_ax = "0000-00-00"
379 LIMIT 10'));
380 $page->assign('deceasedDifferent',XDB::iterator(
381 'SELECT
382 d.user_id,d.id_ancien,d.nom,d.prenom,d.promo,
56637adc
PC
383 d.deces_ax,d.deces_xorg,
384 CONCAT(d.prenom, " ", d.nom) AS display_name
e8591429
PC
385 FROM fusionax_deceased AS d
386 WHERE d.deces_xorg != "0000-00-00" AND d.deces_ax != "0000-00-00"
387 LIMIT 10'));
b9ad0878
PC
388 }
389}
e8591429 390
b9ad0878 391// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:?>