new coderule for MySQL queries : use backquotes around fields and tables
[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
22class FusionAxModule extends PLModule{
23
24 function handlers()
25 {
26 return array(
27 'fusionax' => $this->make_hook('index', AUTH_MDP, 'admin'),
28 'fusionax/import' => $this->make_hook('import', AUTH_MDP, 'admin'),
29 'fusionax/ids' => $this->make_hook('ids', AUTH_MDP, 'admin'),
30 'fusionax/misc' => $this->make_hook('misc', AUTH_MDP, 'admin'),
31 );
32 }
33
34 function handler_index(&$page)
35 {
36 global $globals;
37 $page->changeTpl('fusionax/index.tpl');
38 $page->assign('xorg_title','Polytechnique.org - Fusion des annuaires');
39 if (isset($globals->fusionax) && isset($globals->fusionax->LastUpdate)) {
40 $page->assign('lastimport', date("d-m-Y",$globals->fusionax->LastUpdate));
41 }
42 }
43
cc8ea8b2 44 /** Import de l'annuaire de l'AX depuis l'export situé sur leur serveur */
b9ad0878
PC
45 function handler_import(&$page, $action = 'index', $fileSQL = '')
46 {
47 if ($action == 'index') {
48 $page->changeTpl('fusionax/import.tpl');
49 $page->addJsLink('jquery.js');
50 global $globals;
51 if (isset($globals->fusionax) && isset($globals->fusionax->LastUpdate)) {
52 $page->assign('lastimport', "le ".date("d/m/Y à H:i",$globals->fusionax->LastUpdate));
53 }
54 if (!file_exists(dirname(__FILE__).'/../configs/ax_xorg_rsa')) {
55 $page->assign('keymissing', realpath(dirname(__FILE__).'/../configs/').'/ax_xorg_rsa');
56 }
57 return;
58 }
cc8ea8b2
PC
59
60 // toutes les actions sont faites en ajax en utilisant jquery
b9ad0878 61 header("Content-type: text/javascript; charset=utf-8");
cc8ea8b2
PC
62
63 // log des actions
64 $report = array();
65
66 // création d'un fichier temporaire si nécessaire
b9ad0878
PC
67 if (Env::has('tmpdir')) {
68 $tmpdir = Env::v('tmpdir');
69 } else {
b9ad0878
PC
70 $tmpdir = tempnam('/tmp', 'fusionax');
71 unlink($tmpdir);
72 mkdir($tmpdir);
cc8ea8b2
PC
73 chmod($tmpdir, 0700);
74 // copie la clef d'authentification (paire de clef RSA dont la partie publique est sur polytechniciens.com)
b9ad0878
PC
75 if (!copy(dirname(__FILE__).'/../configs/ax_xorg_rsa',$tmpdir.'/ax_xorg_rsa'))
76 $report[] = 'Impossible de copier la clef pour se logger sur le serveur AX';
77 chmod($tmpdir.'/ax_xorg_rsa', 0600);
78 }
cc8ea8b2 79
b9ad0878
PC
80 $modulepath = realpath(dirname(__FILE__).'/fusionax/').'/';
81 $olddir = getcwd();
82 chdir($tmpdir);
cc8ea8b2 83
b9ad0878 84 if ($action == 'launch') {
cc8ea8b2
PC
85 // lancement : connexion en ssh et récupération du fichier depuis polyechniciens.com
86 // décompression de l'archive et séparation en fichiers par tables
b9ad0878
PC
87 exec($modulepath.'import-ax.sh', $report);
88 $report[] = utf8_decode('Récupération du fichier terminé.');
89 $report[] = 'Import dans la base en cours...';
90 $next = 'integrateSQL';
91 } else if ($action == 'integrateSQL') {
cc8ea8b2
PC
92 // intégration des données dans la base MySQL
93 // liste des fichiers sql à exécuter
94 $filesSQL = array(
95 'Activites.sql',
96 'Adresses.sql',
97 'Anciens.sql',
98 'Formations.sql',
99 'Entreprises.sql');
b9ad0878 100 if ($fileSQL != '') {
cc8ea8b2 101 // récupère le contenu du fichier sql
b9ad0878
PC
102 $queries = explode(';',file_get_contents($modulepath.$fileSQL));
103 foreach ($queries as $q) if (trim($q)) {
cc8ea8b2 104 // coupe le fichier en requêtes individuelles
b9ad0878 105 if (substr($q,0,2) == '--') {
cc8ea8b2 106 // affiche les commentaires dans le report
b9ad0878
PC
107 $lines = explode("\n",$q);
108 $l = $lines[0];
109 $report[] = addslashes(utf8_decode($l));
110 }
cc8ea8b2 111 // exécute la requête
b9ad0878
PC
112 XDB::execute($q);
113 }
cc8ea8b2
PC
114 // trouve le prochain fichier à exécuter
115 $trans = array_flip($filesSQL);
116 $nextfile = $trans[$fileSQL] + 1;
b9ad0878
PC
117 } else {
118 $nextfile = 0;
119 }
120 if (!isset($filesSQL[$nextfile])) {
cc8ea8b2 121 // tous les fichiers ont été exécutés, on passe à l'étape suivante
b9ad0878
PC
122 $next = 'clean';
123 } else {
cc8ea8b2 124 // on passe au fichier suivant
b9ad0878
PC
125 $next = 'integrateSQL/'.$filesSQL[$nextfile];
126 }
127 } else if ($action == 'clean') {
cc8ea8b2 128 // nettoyage du fichier temporaire
b9ad0878
PC
129 chdir($olddir);
130 exec("rm -rf $tmpdir", $report);
131 $report[] = 'Fin de l\'import';
132 global $globals;
cc8ea8b2 133 // met à jour la date de dernier import
b9ad0878
PC
134 $globals->change_dynamic_config(array('LastUpdate' => time()), 'FusionAx');
135 }
136 $tmpdir = getcwd();
137 chdir($olddir);
138 foreach($report as $t)
cc8ea8b2 139 // affiche les lignes de report
b9ad0878
PC
140 echo "$('#fusionax_import').append('".utf8_encode($t)."<br/>');\n";
141 if (isset($next)) {
cc8ea8b2 142 // lance le prochain script s'il y en a un
b9ad0878
PC
143 echo "$.getScript('fusionax/import/".$next."?tmpdir=".urlencode($tmpdir)."');";
144 }
cc8ea8b2 145 // exit pour ne pas afficher la page template par défaut
b9ad0878
PC
146 exit;
147 }
148
b65beb64
PC
149 /** Lier les identifiants d'un ancien dans les deux annuaires
150 * @param user_id identifiant dans l'annuaire X.org
151 * @param matricule_ax identifiant dans l'annuaire de l'AX
152 * @return 0 si la liaison a échoué, 1 sinon
153 */
b9ad0878
PC
154 private static function link_by_ids($user_id, $matricule_ax)
155 {
61f70d79
PC
156 if (!XDB::execute("UPDATE `fusionax_import` AS i INNER JOIN `auth_user_md5` AS u
157 SET u.`matricule_ax` = i.`id_ancien`, i.`user_id` = u.`user_id`, i.`date_match_id` = NOW()
b9ad0878 158 WHERE
61f70d79
PC
159 i.`id_ancien` = {?} AND u.`user_id` = {?} AND (
160 u.`matricule_ax` != {?} OR u.`matricule_ax` IS NULL OR
161 i.`user_id` != {?} OR i.`user_id` IS NULL)", $matricule_ax, $user_id, $matricule_ax, $user_id))
b9ad0878
PC
162 {
163 return 0;
164 }
165 return XDB::affectedRows() / 2;
166 }
167
b65beb64
PC
168 /** Recherche automatique d'anciens à lier entre les deux annuaires
169 * @param limit nombre d'anciens à trouver au max
170 * @param sure si true, ne trouve que des anciens qui sont quasi sûrs
171 * @return un XOrgDBIterator sur les entrées avec prenom, nom, promo, user_id, id_ancien et nom_ax
172 */
173 private static function find_easy_to_link($limit = 10, $sure = false)
b9ad0878 174 {
b65beb64 175 $easy_to_link = XDB::iterator("SELECT
61f70d79
PC
176 xorg.`prenom`, xorg.`nom`, xorg.`promo`, xorg.`user_id`, ax.`id_ancien`,
177 CONCAT(ax.`prenom`,' ',ax.`nom_complet`,' (X ',ax.`promotion_etude`,')') AS nom_ax,
b65beb64 178 COUNT(*) AS nbMatches
61f70d79
PC
179 FROM `fusionax_anciens` AS ax
180 INNER JOIN `fusionax_import` AS i ON (i.`id_ancien` = ax.`id_ancien` AND i.`user_id` IS NULL)
181 LEFT JOIN `auth_user_md5` AS xorg ON (
182 xorg.`matricule_ax` IS NULL AND
183 ax.`Nom_complet` = xorg.`nom` AND
184 ax.`prenom` = xorg.`prenom` AND
185 xorg.`promo` = ax.`promotion_etude`)
186 GROUP BY xorg.`user_id`
b65beb64 187 HAVING
61f70d79 188 xorg.`user_id` IS NOT NULL AND
b65beb64
PC
189 nbMatches = 1
190 ".($limit?('LIMIT '.$limit):''));
191 if ($easy_to_link->total() > 0 || $sure) {
192 return $easy_to_link;
193 }
b9ad0878 194 return XDB::iterator("SELECT
61f70d79
PC
195 xorg.`prenom`, xorg.`nom`, xorg.`promo`, xorg.`user_id`, ax.`id_ancien`,
196 CONCAT(ax.`prenom`,' ',ax.`nom_complet`,' (X ',ax.`promotion_etude`,')') AS nom_ax,
cc8ea8b2 197 COUNT(*) AS nbMatches
61f70d79
PC
198 FROM `fusionax_anciens` AS ax
199 INNER JOIN `fusionax_import` AS i ON (i.`id_ancien` = ax.`id_ancien` AND i.`user_id` IS NULL)
200 LEFT JOIN `auth_user_md5` AS xorg ON (
201 xorg.`matricule_ax` IS NULL AND
202 (ax.`Nom_complet` = xorg.`nom`
203 OR ax.`Nom_complet` LIKE CONCAT(xorg.`nom`,' %')
204 OR ax.`Nom_complet` LIKE CONCAT(xorg.`nom`,'-%')
205 OR ax.`Nom_usuel` = xorg.`nom`
206 OR xorg.`nom` LIKE CONCAT('% ',ax.`Nom_complet`)) AND
207 xorg.`promo` < ax.`promotion_etude` + 2 AND
208 xorg.`promo` > ax.`promotion_etude` - 2)
209 GROUP BY xorg.`user_id`
cc8ea8b2 210 HAVING
61f70d79 211 xorg.`user_id` IS NOT NULL AND
cc8ea8b2 212 nbMatches = 1
b9ad0878
PC
213 ".($limit?('LIMIT '.$limit):''));
214 }
215
b65beb64 216 /** Module de mise en correspondance les ids */
cc8ea8b2 217 function handler_ids(&$page, $part = 'main', $user_id = null, $matricule_ax = null)
b9ad0878
PC
218 {
219 global $globals;
220 $globals->change_dynamic_config(array('LastUpdate' => time()), 'FusionAX');
b65beb64 221 $page->addJsLink('jquery.js');
b9ad0878
PC
222
223 $page->assign('xorg_title','Polytechnique.org - Fusion des annuaires - Mise en correspondance simple');
224 if ($part == 'missingInAX')
225 {
226 // locate all persons from this database that are not in AX's
227 $page->changeTpl('fusionax/idsMissingInAx.tpl');
228 $missingInAX = XDB::iterator("SELECT *
61f70d79
PC
229 FROM `auth_user_md5` AS u
230 LEFT JOIN `aliases` AS a ON(a.`id` = u.`user_id` AND FIND_IN_SET('bestalias', a.`flags`))
231 WHERE u.`matricule_ax` IS NULL
b9ad0878
PC
232 LIMIT 20");
233 $page->assign('missingInAX', $missingInAX);
234 return;
235 }
236 if ($part == 'missingInXorg')
237 {
238 // locate all persons from AX's database that are not here
239 $page->changeTpl('fusionax/idsMissingInXorg.tpl');
61f70d79
PC
240 $missingInXorg = XDB::iterator("SELECT `promotion_etude` AS promo, `prenom`, `Nom_usuel` AS nom, `id_ancien`
241 FROM `fusionax_import`
242 INNER JOIN `fusionax_anciens` AS a USING (`id_ancien`)
243 WHERE `fusionax_import`.`user_id` IS NULL
b9ad0878
PC
244 LIMIT 20");
245 $page->assign('missingInXorg', $missingInXorg);
246 return;
247 }
248 if ($part == 'link')
249 {
cc8ea8b2 250 FusionAxModule::link_by_ids($user_id,$matricule_ax);
b65beb64 251 exit;
b9ad0878
PC
252 }
253 if ($part == 'linknext')
254 {
255 $linksToDo = FusionAxModule::find_easy_to_link(10);
256 while ($l = $linksToDo->next())
257 {
258 FusionAxModule::link_by_ids($l['user_id'],$l['id_ancien']);
259 }
b65beb64 260 pl_redirect('fusionax/ids#autolink');
b9ad0878
PC
261 }
262 if ($part == 'linkall')
263 {
264 $linksToDo = FusionAxModule::find_easy_to_link(0);
265 while ($l = $linksToDo->next())
266 {
267 FusionAxModule::link_by_ids($l['user_id'],$l['id_ancien']);
268 }
269 }
270 {
271 $page->changeTpl('fusionax/ids.tpl');
61f70d79 272 $missingInAX = XDB::query("SELECT COUNT(*) FROM `auth_user_md5` WHERE `matricule_ax` IS NULL");
b9ad0878
PC
273 if ($missingInAX)
274 {
275 $page->assign('nbMissingInAX', $missingInAX->fetchOneCell());
276 }
61f70d79 277 $missingInXorg = XDB::query("SELECT COUNT(*) FROM `fusionax_import` WHERE `user_id` IS NULL");
b9ad0878
PC
278 if ($missingInXorg)
279 {
280 $page->assign('nbMissingInXorg', $missingInXorg->fetchOneCell());
281 }
282 $easyToLink = FusionAxModule::find_easy_to_link(10);
283 if ($easyToLink->total() > 0)
284 {
285 $page->assign('easyToLink', $easyToLink);
286 }
287 }
288 }
c4035ce6 289
b9ad0878
PC
290 function handler_misc(&$page)
291 {
292 $page->changeTpl('fusionax/misc.tpl');
293 // deceased
61f70d79 294 $deceasedErrorsSql = XDB::query('SELECT COUNT(*) FROM `fusionax_deceased`');
b9ad0878 295 $page->assign('deceasedErrors',$deceasedErrorsSql->fetchOneCell());
61f70d79
PC
296 $page->assign('deceasedMissingInXorg',XDB::iterator('SELECT `user_id`,`id_ancien`,`nom`,`prenom`,`promo`,`deces_ax` FROM `fusionax_deceased` WHERE `deces_xorg` = "0000-00-00" LIMIT 10'));
297 $page->assign('deceasedMissingInAX',XDB::iterator('SELECT `user_id`,`id_ancien`,`nom`,`prenom`,`promo`,`deces_xorg` FROM `fusionax_deceased` WHERE `deces_ax` = "0000-00-00" LIMIT 10'));
298 $page->assign('deceasedDifferent',XDB::iterator('SELECT ``user_id`,`id_ancien`,`nom`,`prenom`,`promo`,`deces_ax`,`deces_xorg` FROM `fusionax_deceased` WHERE `deces_xorg` != "0000-00-00" AND `deces_ax` != "0000-00-00" LIMIT 10'));
b9ad0878
PC
299 }
300}
301// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:?>