2 /***************************************************************************
3 * Copyright (C) 2003-2007 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
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. *
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. *
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 *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 class FusionAxModule
extends PLModule
{
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'),
34 function handler_index(&$page)
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
));
44 /** Import de l'annuaire de l'AX depuis l'export situé sur leur serveur */
45 function handler_import(&$page, $action = 'index', $fileSQL = '')
47 if ($action == 'index') {
48 $page->changeTpl('fusionax/import.tpl');
49 $page->addJsLink('jquery.js');
51 if (isset($globals->fusionax
) && isset($globals->fusionax
->LastUpdate
)) {
52 $page->assign('lastimport', "le ".date("d/m/Y à H:i",$globals->fusionax
->LastUpdate
));
54 if (!file_exists(dirname(__FILE__
).'/../configs/ax_xorg_rsa')) {
55 $page->assign('keymissing', realpath(dirname(__FILE__
).'/../configs/').'/ax_xorg_rsa');
60 // toutes les actions sont faites en ajax en utilisant jquery
61 header("Content-type: text/javascript; charset=utf-8");
66 // création d'un fichier temporaire si nécessaire
67 if (Env
::has('tmpdir')) {
68 $tmpdir = Env
::v('tmpdir');
70 $tmpdir = tempnam('/tmp', 'fusionax');
74 // copie la clef d'authentification (paire de clef RSA dont la partie publique est sur polytechniciens.com)
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);
80 $modulepath = realpath(dirname(__FILE__
).'/fusionax/').'/';
84 if ($action == 'launch') {
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
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') {
92 // intégration des données dans la base MySQL
93 // liste des fichiers sql à exécuter
100 if ($fileSQL != '') {
101 // récupère le contenu du fichier sql
102 $queries = explode(';',file_get_contents($modulepath.$fileSQL));
103 foreach ($queries as $q) if (trim($q)) {
104 // coupe le fichier en requêtes individuelles
105 if (substr($q,0,2) == '--') {
106 // affiche les commentaires dans le report
107 $lines = explode("\n",$q);
109 $report[] = addslashes(utf8_decode($l));
111 // exécute la requête
114 // trouve le prochain fichier à exécuter
115 $trans = array_flip($filesSQL);
116 $nextfile = $trans[$fileSQL] +
1;
120 if (!isset($filesSQL[$nextfile])) {
121 // tous les fichiers ont été exécutés, on passe à l'étape suivante
124 // on passe au fichier suivant
125 $next = 'integrateSQL/'.$filesSQL[$nextfile];
127 } else if ($action == 'clean') {
128 // nettoyage du fichier temporaire
130 exec("rm -rf $tmpdir", $report);
131 $report[] = 'Fin de l\'import';
133 // met à jour la date de dernier import
134 $globals->change_dynamic_config(array('LastUpdate' => time()), 'FusionAx');
138 foreach($report as $t)
139 // affiche les lignes de report
140 echo "$('#fusionax_import').append('".utf8_encode($t)."<br/>');\n";
142 // lance le prochain script s'il y en a un
143 echo "$.getScript('fusionax/import/".$next."?tmpdir=".urlencode($tmpdir)."');";
145 // exit pour ne pas afficher la page template par défaut
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
154 private static function link_by_ids($user_id, $matricule_ax)
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()
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))
165 return XDB
::affectedRows() / 2;
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
173 private static function find_easy_to_link($limit = 10, $sure = false
)
175 $easy_to_link = XDB
::iterator("SELECT
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,
178 COUNT(*) AS nbMatches
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`
188 xorg.`user_id` IS NOT NULL AND
190 ".($limit?
('LIMIT '.$limit):''));
191 if ($easy_to_link->total() > 0 ||
$sure) {
192 return $easy_to_link;
194 return XDB
::iterator("SELECT
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,
197 COUNT(*) AS nbMatches
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`
211 xorg.`user_id` IS NOT NULL AND
213 ".($limit?
('LIMIT '.$limit):''));
216 /** Module de mise en correspondance les ids */
217 function handler_ids(&$page, $part = 'main', $user_id = null
, $matricule_ax = null
)
220 $globals->change_dynamic_config(array('LastUpdate' => time()), 'FusionAX');
221 $page->addJsLink('jquery.js');
223 $page->assign('xorg_title','Polytechnique.org - Fusion des annuaires - Mise en correspondance simple');
224 if ($part == 'missingInAX')
226 // locate all persons from this database that are not in AX's
227 $page->changeTpl('fusionax/idsMissingInAx.tpl');
228 $missingInAX = XDB
::iterator("SELECT *
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
233 $page->assign('missingInAX', $missingInAX);
236 if ($part == 'missingInXorg')
238 // locate all persons from AX's database that are not here
239 $page->changeTpl('fusionax/idsMissingInXorg.tpl');
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
245 $page->assign('missingInXorg', $missingInXorg);
250 FusionAxModule
::link_by_ids($user_id,$matricule_ax);
253 if ($part == 'linknext')
255 $linksToDo = FusionAxModule
::find_easy_to_link(10);
256 while ($l = $linksToDo->next())
258 FusionAxModule
::link_by_ids($l['user_id'],$l['id_ancien']);
260 pl_redirect('fusionax/ids#autolink');
262 if ($part == 'linkall')
264 $linksToDo = FusionAxModule
::find_easy_to_link(0);
265 while ($l = $linksToDo->next())
267 FusionAxModule
::link_by_ids($l['user_id'],$l['id_ancien']);
271 $page->changeTpl('fusionax/ids.tpl');
272 $missingInAX = XDB
::query("SELECT COUNT(*) FROM `auth_user_md5` WHERE `matricule_ax` IS NULL");
275 $page->assign('nbMissingInAX', $missingInAX->fetchOneCell());
277 $missingInXorg = XDB
::query("SELECT COUNT(*) FROM `fusionax_import` WHERE `user_id` IS NULL");
280 $page->assign('nbMissingInXorg', $missingInXorg->fetchOneCell());
282 $easyToLink = FusionAxModule
::find_easy_to_link(10);
283 if ($easyToLink->total() > 0)
285 $page->assign('easyToLink', $easyToLink);
290 function handler_misc(&$page)
292 $page->changeTpl('fusionax/misc.tpl');
294 $deceasedErrorsSql = XDB
::query('SELECT COUNT(*) FROM `fusionax_deceased`');
295 $page->assign('deceasedErrors',$deceasedErrorsSql->fetchOneCell());
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'));
301 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:?>