Alternc  3.2
Alternc logiel libre pour l'hébergement
 All Data Structures Namespaces Files Functions Variables Pages
m_mem.php
Go to the documentation of this file.
1 <?php
2 /*
3  $Id: m_mem.php,v 1.19 2006/01/12 08:04:43 anarcat Exp $
4  ----------------------------------------------------------------------
5  LICENSE
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License (GPL)
9  as published by the Free Software Foundation; either version 2
10  of the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  To read the license please visit http://www.gnu.org/copyleft/gpl.html
18  ----------------------------------------------------------------------
19  Original Author of file: Benjamin Sonntag
20  Purpose of file: Manage Login session on the virtual desktop and
21  member parameters
22  ----------------------------------------------------------------------
23 */
24 /**
25 * This class manage user sessions in the web desktop.
26 *
27 * This class manage user sessions and administration in AlternC.
28 * @copyright AlternC-Team 2002-2005 http://alternc.org/
29 *
30 */
31 class m_mem {
32 
33  /** Original uid for the temporary uid swapping (for administrators) */
34  var $olduid=0;
35 
36  /** This array contains the Tableau contenant les champs de la table "membres" du membre courant
37  * Ce tableau est utilisable globalement par toutes les classes filles.
38  */
39  var $user;
40  /** Tableau contenant les champs de la table "local" du membre courant
41  * Ce tableau est utilisable globalement par toutes les classes filles.
42  * Note : les champs de "local" sont spécifiques à l'hébergeur.
43  */
44  var $local;
45 
46  /* ----------------------------------------------------------------- */
47  /**
48  * Constructeur
49  */
50  function m_mem() {
51  }
52 
53  /* ----------------------------------------------------------------- */
54  /**
55  * Password kind used in this class (hook for admin class)
56  */
58  return array("mem"=>"AlternC's account password");
59  }
60 
61  function hook_menu() {
62  $obj = array(
63  'title' => _("Settings"),
64  'ico' => 'images/settings.png',
65  'link' => 'mem_param.php',
66  'pos' => 160,
67  ) ;
68 
69  return $obj;
70  }
71 
72  /* ----------------------------------------------------------------- */
73  /** Check that the current user is an admnistrator.
74  * @return boolean TRUE if we are super user, or FALSE if we are not.
75  */
76  function checkright() {
77  return ($this->user["su"]=="1");
78  }
79 
80  /* ----------------------------------------------------------------- */
81  /** Start a session in the web desktop. Check username and password.
82  * <b>Note : </b>If the user entered a bas password, the failure will be logged
83  * and told to the corresponding user on next successfull login.
84  * @param $username string Username that want to get connected.
85  * @param $password string User Password.
86  * @return boolean TRUE if the user has been successfully connected, or FALSE if an error occured.
87  */
88  function login($username,$password,$restrictip=0,$authip_token=false) {
89  global $db,$err,$cuid,$authip,$admin;
90  $err->log("mem","login",$username);
91  // $username=addslashes($username);
92  // $password=addslashes($password);
93  $db->query("select * from membres where login='$username';");
94  if ($db->num_rows()==0) {
95  $err->raise("mem",_("User or password incorrect"));
96  return false;
97  }
98  $db->next_record();
99  if (_md5cr($password,$db->f("pass"))!=$db->f("pass")) {
100  $db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid='".$db->f("uid")."';");
101  $err->raise("mem",_("User or password incorrect"));
102  return false;
103  }
104  if (!$db->f("enabled")) {
105  $err->raise("mem",_("This account is locked, contact the administrator"));
106  return false;
107  }
108  $this->user=$db->Record;
109  $cuid=$db->f("uid");
110 
111  if (panel_islocked() && $cuid != 2000) {
112  $err->raise("mem",_("This website is currently under maintenance, login is currently disabled."));
113  return false;
114  }
115 
116  // AuthIP
117  $allowed_ip=false;
118  if ( $authip_token ) $allowed_ip = $this->authip_tokencheck($authip_token);
119 
120  $aga = $authip->get_allowed('panel');
121  foreach ($aga as $k=>$v ) {
122  if ( $authip->is_in_subnet(get_remote_ip(), $v['ip'], $v['subnet']) ) $allowed=true ;
123  }
124 
125  // Error if there is rules, the IP is not allowed and it's not in the whitelisted IP
126  if ( sizeof($aga)>1 && !$allowed_ip && !$authip->is_wl(get_remote_ip()) ) {
127  $err->raise("mem",_("Your IP isn't allowed to connect"));
128  return false;
129  }
130  // End AuthIP
131 
132  if ($restrictip) {
133  $ip="'".get_remote_ip()."'";
134  } else $ip="''";
135  /* Close sessions that are more than 2 days old. */
136  $db->query("DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)<NOW();");
137  /* Delete old impersonation */
138  if ( isset($_COOKIE["oldid"]) ) setcookie('oldid','',0,'/');
139  /* Open the session : */
140  $sess=md5(uniqid(mt_rand()));
141  $_REQUEST["session"]=$sess;
142  $db->query("insert into sessions (sid,ip,uid) values ('$sess',$ip,'$cuid');");
143  setcookie("session",$sess,0,"/");
144  $err->error=0;
145  /* Fill in $local */
146  $db->query("SELECT * FROM local WHERE uid='$cuid';");
147  if ($db->num_rows()) {
148  $db->next_record();
149  $this->local=$db->Record;
150  }
151  return true;
152  }
153 
154  /* ----------------------------------------------------------------- */
155  /** Start a session as another user from an administrator account.
156  * This function is not the same as su. setid connect the current user in the destination
157  * account (for good), and su allow any user to become another account for some commands only.
158  * (del_user, add_user ...) and allow to bring back admin rights with unsu
159  *
160  * @param $id integer User id where we will connect to.
161  * @return boolean TRUE if the user has been successfully connected, FALSE else.
162  */
163  function setid($id) {
164  global $db,$err,$cuid,$mysql,$quota;
165  $err->log("mem","setid",$id);
166  $db->query("select * from membres where uid='$id';");
167  if ($db->num_rows()==0) {
168  $err->raise("mem",_("User or password incorrect"));
169  return false;
170  }
171  $db->next_record();
172  $this->user=$db->Record;
173  $cuid=$db->f("uid");
174  // And recreate the $db->dbus
175  $mysql->reload_dbus();
176 
177  $ip=get_remote_ip();
178  $sess=md5(uniqid(mt_rand()));
179  $_REQUEST["session"]=$sess;
180  $db->query("insert into sessions (sid,ip,uid) values ('$sess','$ip','$cuid');");
181  setcookie("session",$sess,0,"/");
182  $err->error=0;
183  /* Fill in $local */
184  $db->query("SELECT * FROM local WHERE uid='$cuid';");
185  if ($db->num_rows()) {
186  $db->next_record();
187  $this->local=$db->Record;
188  }
189  $quota->getquota('', true);
190  return true;
191  }
192 
193  /* ----------------------------------------------------------------- */
194  /** Suite à la connexion de l'utilisateur, réinitialise ses paramètres de dernière connexion
195  */
196  function resetlast() {
197  global $db,$cuid;
198  $ip=addslashes(getenv("REMOTE_HOST"));
199  if (!$ip) $ip=addslashes(get_remote_ip());
200  $db->query("UPDATE membres SET lastlogin=NOW(), lastfail=0, lastip='$ip' WHERE uid='$cuid';");
201  }
202 
203  function authip_token($bis=false) {
204  global $db,$cuid;
205  $db->query("select pass from membres where uid='$cuid';");
206  $db->next_record();
207  $i=intval(time()/3600);
208  if ($bis) ++$i;
209  return md5("$i--".$db->f('pass'));
210  }
211 
212  function authip_tokencheck($t) {
213  if ($t==$this->authip_token() || $t==$this->authip_token(true) ) return true;
214  return false;
215  }
216 
217 /* Faut finir de l'implémenter :) * /
218  function authip_class() {
219  global $cuid;
220  $c = Array();
221  $c['name']="Panel access";
222  $c['protocol']="mem";
223  $c['values']=Array($cuid=>'');
224 
225  return $c;
226  }
227 /* */
228 
229  /* ----------------------------------------------------------------- */
230  /** Vérifie que la session courante est correcte (cookie ok et ip valide).
231  * Si besoin, et si réception des champs username & password, crée une nouvelle
232  * session pour l'utilisateur annoncé.
233  * Cette fonction doit être appellée à chaque page devant être authentifiée.
234  * et AVANT d'émettre des données. (un cookie peut être envoyé)
235  * @global string $session Le cookie de session eventuel
236  * @global string $username/password le login/pass de l'utilisateur
237  * @return TRUE si la session est correcte, FALSE sinon.
238  */
239  function checkid() {
240  global $db,$err,$cuid,$restrictip,$authip;
241  if (isset($_REQUEST["username"])) {
242  if ( empty($_REQUEST['password']) ) {
243  $err->raise("mem",_("Missing password"));
244  return false;
245  }
246  if ($_REQUEST["username"] && $_REQUEST["password"]) {
247  return $this->login($_REQUEST["username"],$_REQUEST["password"], (isset($_REQUEST["restrictip"])?$_REQUEST["restrictip"]:0) );
248  }
249  } // end isset
250  $_COOKIE["session"]=isset($_COOKIE["session"])?addslashes($_COOKIE["session"]):"";
251  if (strlen($_COOKIE["session"])!=32) {
252  $err->raise("mem",_("Identity lost or unknown, please login"));
253  return false;
254  }
255  $ip=get_remote_ip();
256  $db->query("select uid,'$ip' as me,ip from sessions where sid='".$_COOKIE["session"]."'");
257  if ($db->num_rows()==0) {
258  $err->raise("mem",_("Session unknown, contact the administrator"));
259  return false;
260  }
261  $db->next_record();
262  if ($db->f("ip")) {
263  if ($db->f("me")!=$db->f("ip")) {
264  $err->raise("mem",_("IP address incorrect, please contact the administrator"));
265  return false;
266  }
267  }
268  $cuid=$db->f("uid");
269 
270  if (panel_islocked() && $cuid != 2000) {
271  $err->raise("mem",_("This website is currently under maintenance, login is currently disabled."));
272  return false;
273  }
274 
275  $db->query("select * from membres where uid='$cuid';");
276  $db->next_record();
277  $this->user=$db->Record;
278  $err->error=0;
279  /* Remplissage de $local */
280  $db->query("SELECT * FROM local WHERE uid='$cuid';");
281  if ($db->num_rows()) {
282  $db->next_record();
283  $this->local=$db->Record;
284  }
285  return true;
286  }
287 
288  /* ----------------------------------------------------------------- */
289  /** Change l'identité d'un utilisateur temporairement.
290  * @global string $uid Utilisateur dont on prends l'identité
291  * @return TRUE si la session est correcte, FALSE sinon.
292  */
293  function su($uid) {
294  global $cuid,$db,$err,$mysql;
295  if (!$this->olduid)
296  $this->olduid=$cuid;
297  $db->query("select * from membres where uid='$uid';");
298  if ($db->num_rows()==0) {
299  $err->raise("mem",_("User or password incorrect"));
300  return false;
301  }
302  $db->next_record();
303  $this->user=$db->Record;
304  $cuid=$db->f("uid");
305 
306  // And recreate the $db->dbus
307  $mysql->reload_dbus();
308  return true;
309  }
310 
311  /* ----------------------------------------------------------------- */
312  /** Retourne a l'identite d'origine de l'utilisateur apres su.
313  * @return TRUE si la session est correcte, FALSE sinon.
314  */
315  function unsu() {
316  global $cuid,$mysql;
317  if (!$this->olduid)
318  return false;
319  $this->su($this->olduid);
320  $this->olduid=0;
321  // And recreate the $db->dbus
322  $mysql->reload_dbus();
323  return true;
324  }
325 
326 
327  /* ----------------------------------------------------------------- */
328  /** Termine une session du bureau virtuel (logout)
329  * @return boolean TRUE si la session a bien été détruite, FALSE sinon.
330  */
331  function del_session() {
333  $_COOKIE["session"]=addslashes(isset($_COOKIE["session"])?$_COOKIE["session"]:'');
334  setcookie("session","",0,"/");
335  setcookie("oldid","",0,"/");
336  if ($_COOKIE["session"]=="") {
337  $err->error=0;
338  return true;
339  }
340  if (strlen($_COOKIE["session"])!=32) {
341  $err->raise("mem",_("Cookie incorrect, please accept the session cookie"));
342  return false;
343  }
344  $ip=get_remote_ip();
345  $db->query("select uid,'$ip' as me,ip from sessions where sid='".$_COOKIE["session"]."'");
346  if ($db->num_rows()==0) {
347  $err->raise("mem",_("Session unknown, contact the administrator"));
348  return false;
349  }
350  $db->next_record();
351  if ($db->f("me")!=$db->f("ip")) {
352  $err->raise("mem",_("IP address incorrect, please contact the administrator"));
353  return false;
354  }
355  $cuid=$db->f("uid");
356  $db->query("delete from sessions where sid='".$_COOKIE["session"]."';");
357  $err->error=0;
358 
359  # Invoker le logout dans toutes les autres classes
360  /*
361  foreach($classes as $c) {
362  if (method_exists($GLOBALS[$c],"alternc_del_session")) {
363  $GLOBALS[$c]->alternc_del_session();
364  }
365  }
366  */
367  $hooks->invoke("alternc_del_session");
368 
369  session_unset();
370  @session_destroy();
371  return true;
372  }
373 
374  /* ----------------------------------------------------------------- */
375  /** Change le mot de passe de l'utilisateur courant.
376  * @param string $oldpass Ancien mot de passe.
377  * @param string $newpass Nouveau mot de passe
378  * @param string $newpass2 Nouveau mot de passe (à nouveau)
379  * @return boolean TRUE si le mot de passe a été changé, FALSE sinon.
380  */
381  function passwd($oldpass,$newpass,$newpass2) {
382  global $db,$err,$cuid,$admin;
383  $err->log("mem","passwd");
384  $oldpass=stripslashes($oldpass);
385  $newpass=stripslashes($newpass);
386  $newpass2=stripslashes($newpass2);
387  if (!$this->user["canpass"]) {
388  $err->raise("mem",_("You are not allowed to change your password."));
389  return false;
390  }
391  if ($this->user["pass"]!=_md5cr($oldpass,$this->user["pass"])) {
392  $err->raise("mem",_("The old password is incorrect"));
393  return false;
394  }
395  if ($newpass!=$newpass2) {
396  $err->raise("mem",_("The new passwords are differents, please retry"));
397  return false;
398  }
399  $db->query("SELECT login FROM membres WHERE uid='$cuid';");
400  $db->next_record();
401  $login=$db->Record["login"];
402  if (!$admin->checkPolicy("mem",$login,$newpass)) {
403  return false; // The error has been raised by checkPolicy()
404  }
405  $newpass=_md5cr($newpass);
406  $db->query("UPDATE membres SET pass='$newpass' WHERE uid='$cuid';");
407  $err->error=0;
408  return true;
409  }
410 
411  /* ----------------------------------------------------------------- */
412  /** Change les préférences administrateur d'un compte
413  * @param integer $admlist Mode de visualisation des membres (0=large 1=courte)
414  * @return boolean TRUE si les préférences ont été changées, FALSE sinon.
415  */
416  function adminpref($admlist) {
417  global $db,$err,$cuid;
418  $err->log("mem","admlist");
419  if (!$this->user["su"]) {
420  $err->raise("mem",_("You must be a system administrator to do this."));
421  return false;
422  }
423  $db->query("UPDATE membres SET admlist='$admlist' WHERE uid='$cuid';");
424  $err->error=0;
425  return true;
426  }
427 
428  /* ----------------------------------------------------------------- */
429  /** Envoie en mail le mot de passe d'un compte.
430  * <b>Note : </b>On ne peut demander le mot de passe qu'une seule fois par jour.
431  * TODO : Translate this mail into the localization program.
432  * TODO : Check this function's !
433  * @return boolean TRUE si le mot de passe a été envoyé avec succès, FALSE sinon.
434  */
435  function send_pass($login) {
436  global $err,$db,$L_HOSTING,$L_FQDN;
437  $err->log("mem","send_pass");
438  $db->query("SELECT * FROM membres WHERE login='$login';");
439  if (!$db->num_rows()) {
440  $err->raise("mem",_("This account is locked, contact the administrator."));
441  return false;
442  }
443  $db->next_record();
444  if (time()-$db->f("lastaskpass")<86400) {
445  $err->raise("mem",_("The new passwords are differents, please retry"));
446  return false;
447  }
448  $txt=sprintf(_("Hello,
449 
450 You requested the modification of your password for your
451 account %s on %s
452 Here are your username and password to access the panel :
453 
454 --------------------------------------
455 
456 Username : %s
457 Password : %s
458 
459 --------------------------------------
460 
461 Note : if you didn't requested that modification, it means that
462 someone did it instead of you. You can choose to ignore this message.
463 If it happens again, please contact your server's Administrator.
464 
465 Cordially.
466 "), $login, $L_HOSTING, $db->f("login"), $db->f("pass"));
467  mail($db->f("mail"),"Your password on $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
468  $db->query("UPDATE membres SET lastaskpass=".time()." WHERE login='$login';");
469  return true;
470  }
471 
472  /* ----------------------------------------------------------------- */
473  /** Change le mail d'un membre (première etape, envoi du CookiE)
474  * TODO : insert this mail string into the localization system
475  * @param string $newmail Nouveau mail souhaité pour le membre.
476  * @return string le cookie si le mail a bien été envoyé, FALSE sinon
477  */
478  function ChangeMail1($newmail) {
479  global $err,$db,$L_HOSTING,$L_FQDN,$cuid;
480  $err->log("mem","changemail1",$newmail);
481  $db->query("SELECT * FROM membres WHERE uid='$cuid';");
482  if (!$db->num_rows()) {
483  $err->raise("mem",_("This account is locked, contact the administrator"));
484  return false;
485  }
486  $db->next_record();
487 
488  // un cookie de 20 caractères pour le mail
489  $COOKIE=substr(md5(uniqid(rand(),1)),0,20);
490  // et de 6 pour la clé à entrer. ca me semble suffisant...
491  $KEY=substr(md5(uniqid(rand(),1)),0,6);
492  $link="https://$L_FQDN/mem_cm.php?usr=$cuid&cookie=$COOKIE";
493  $txt=sprintf(_("Hello,
494 
495 Someone (maybe you) requested an email's address modification of the account
496 %s on %s
497 To confirm your request, go to this url :
498 
499 %s
500 
501 (Warning : if this address is displayed on 2 lines, don't forgot to
502 take it on one line).
503 The panel will ask you the key given when the email address
504 modification was requested.
505 
506 If you didn't asked for this modification, it means that someone
507 did it instead of you. You can choose to ignore this message. If it happens
508 again, please contact your server's administrator.
509 
510 Cordially.
511 "), $db->f("login"), $L_HOSTING, $link);
512  mail($newmail,"Email modification request on $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
513  // Supprime les demandes précédentes de ce compte !
514  $db->query("DELETE FROM chgmail WHERE uid='$cuid';");
515  $db->query("INSERT INTO chgmail (cookie,ckey,uid,mail,ts) VALUES ('$COOKIE','$KEY','$cuid','$newmail',".time().");");
516  // Supprime les cookies de la veille :)
517  $lts=time()-86400;
518  $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
519  return $KEY;
520  }
521 
522  /* ----------------------------------------------------------------- */
523  /** Change le mail d'un membre (seconde etape, CookiE+clé = application)
524  * @param string $COOKIE Cookie envoyé par mail
525  * @param string $KEY clé affichée à l'écran
526  * @param integer $uid Utilisateur concerné (on est hors session)
527  * @return TRUE si le mail a bien été modifié, FALSE sinon
528  */
529  function ChangeMail2($COOKIE,$KEY,$uid) {
530  global $err,$db,$L_HOSTING,$L_FQDN;
531  $err->log("mem","changemail2",$uid);
532  $db->query("SELECT * FROM chgmail WHERE cookie='$COOKIE' and ckey='$KEY' and uid='$uid';");
533  if (!$db->num_rows()) {
534  $err->raise("mem",_("The information you entered is incorrect."));
535  return false;
536  }
537  $db->next_record();
538 
539  // met à jour le compte :
540  $db->query("UPDATE membres SET mail='".$db->f("mail")."' WHERE uid='$uid';");
541 
542  $db->query("DELETE FROM chgmail WHERE uid='$uid';");
543  // Supprime les cookies de la veille :)
544  $lts=time()-86400;
545  $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
546  return true;
547  }
548 
549  /* ----------------------------------------------------------------- */
550  /** Modifie le paramètre d'aide en ligne (1/0)
551  * @param integer $show Faut-il (1) ou non (0) afficher l'aide en ligne
552  */
553  function set_help_param($show) {
554  global $db,$err,$cuid;
555  $err->log("mem","set_help_param",$show);
556  $db->query("UPDATE membres SET show_help='$show' WHERE uid='$cuid';");
557  }
558 
559  /* ----------------------------------------------------------------- */
560  /** Dit si l'aide en ligne est demandée
561  * @return boolean TRUE si l'aide en ligne est demandée, FALSE sinon.
562  */
563  function get_help_param() {
564  return $this->user["show_help"];
565  }
566 
567  /* ----------------------------------------------------------------- */
568  /** Affiche (echo) l'aide contextuelle
569  * @param integer $file Numéro de fichier d'aide à afficher.
570  * @return TRUE si l'aide contextuelle a été trouvée, FALSE sinon
571  */
572  function show_help($file,$force=false) {
573  global $err;
574  if ($this->user["show_help"] || $force) {
575  $hlp=_("hlp_$file");
576  if ($hlp!="hlp_$file") {
577  $hlp=preg_replace(
578  "#HELPID_([0-9]*)#",
579  "<a href=\"javascript:help(\\1);\"><img src=\"/aide/help.png\" width=\"17\" height=\"17\" style=\"vertical-align: middle;\" alt=\""._("Help")."\" /></a>",$hlp);
580  echo "<p class=\"hlp\">".$hlp."</p>";
581  return true;
582  }
583  return false;
584  } else {
585  return true;
586  }
587  }
588 
590  global $db,$err;
591  $err->log("dom","get_creator_by_uid");
592  $uid=mysql_real_escape_string(intval($uid));
593  $db->query("select creator from membres where uid = '$uid';");
594  if (! $db->next_record()) return false;
595  return intval($db->f('creator') );
596  }
597 
598 
599  /* ----------------------------------------------------------------- */
600  /**
601  * Exports all the personnal user related information for an account.
602  * @access private
603  */
604  function alternc_export_conf() {
605  global $db,$err;
606  $err->log("mem","export");
607  $str=" <member>\n";
608  $users=$this->user;
609  $str.=" <uid>".$users["uid"]."</uid>\n";
610  $str.=" <login>".$users["login"]."</login>\n";
611  $str.=" <enabled>".$users["enabled"]."</enabled>\n";
612  $str.=" <su>".$users["su"]."</su>\n";
613  $str.=" <password>".$users["pass"]."</password>\n";
614  $str.=" <mail>".$users["mail"]."</mail>\n";
615  $str.=" <created>".$users["created"]."</created>\n";
616  $str.=" <lastip>".$users["lastip"]."</lastip>\n";
617  $str.=" <lastlogin>".$users["lastlogin"]."</lastlogin>\n";
618  $str.=" <lastfail>".$users["lastfail"]."</lastfail>\n";
619  $str.=" </member>\n";
620  return $str;
621  }
622 
624  global $uid;
625  if (empty($_COOKIE['session'])) return false;
626  $sid=$_COOKIE['session'];
627  if ( empty($_SESSION[$sid.'-'.$uid]) ) { // si pas de session de params tempo
628  return false;
629  }
630  $j=$_SESSION[$sid.'-'.$uid];
631  $j=json_decode($j, true);
632  if ( ! empty($j[$v] ) ) { // si on a bien qque chose a retourner :)
633  return $j[$v];
634  }
635  return false;
636  }
637 
638  function session_tempo_params_set($k, $v, $ecrase=false) {
639  global $uid;
640  if (empty($_COOKIE['session'])) return false;
641  $sid=$_COOKIE['session'];
642  $p=Array();
643  if ( ! empty($_SESSION[$sid.'-'.$uid]) ) {
644  $p = json_decode($_SESSION[$sid.'-'.$uid], true);
645  }
646  if (! $ecrase && (isset($p[$k]) && is_array($p[$k])) && is_array($v) ) {
647  $v=array_merge($p[$k], $v); // overwrite entry with the same name
648  }
649 
650  $p[$k]=$v;
651  $_SESSION[$sid.'-'.$uid]=json_encode($p);
652  return true;
653  }
654 
655 } /* Classe Membre */
656 
657 ?>