Jacek Kowalski
2012-08-26 7b043b4e8bade63ee508c5e8d5db6837bd3e5ada
commit | author | age
8bd4d9 1 <?php
JK 2 /**
3  * Klasa przechowująca dane użytkownika. Całość przypomina mechanizm sesji w PHP.
4  */
5 class BotSession {
6     private $PDO;
7     
8     /**
9      * Nazwa modułu, którego zmienne klasa przetwarza
57117d 10      * @var string max. 40 znaków
8bd4d9 11      */
7b043b 12     protected $class = '';
JK 13     protected $class_empty = TRUE;
8bd4d9 14     
JK 15     private $user;
16     
17     /**
18      * Inicjuje klasę w zależności od użytkownika
19      */
20     function __construct($user) {
21         $this->user = sha1($user);
22         $this->user_struct = parse_url($user);
23         
7b043b 24         $this->class_empty = FALSE;
8bd4d9 25     }
JK 26     
27     private function init() {
7b043b 28         if(strlen($this->class) == 0 && !$this->class_empty) {
57117d 29             throw new Exception('Przed użyciem $msg->session należy ustawić nazwę modułu za pomocą metody setClass - patrz "Poradnik tworzenia modułów", dział "Klasa BotMessage", rozdział "Pole $session".');
JK 30         }
31         
8bd4d9 32         if($this->PDO) {
JK 33             return NULL;
34         }
35         
36         if(is_file(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite')) {
37             $this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
38             $this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
39             $this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
40             return;
41         }
42         
43         try {
44             $this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
45             $this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
46             $this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
47             
48             $this->PDO->query(
49                 'CREATE TABLE data (
50                     class VARCHAR(50),
51                     name VARCHAR(40) NOT NULL,
52                     value TEXT NOT NULL,
53                     PRIMARY KEY (
54                         class ASC,
55                         name ASC
56                     )
57                 )'
58             );
59             
60             $files = glob(BOT_TOPDIR.'/db/*/'.$this->user_struct['user'].'.ggdb');
c661ee 61             if(!$files) {
JK 62                 return;
63             }
8bd4d9 64             
JK 65             $this->PDO->beginTransaction();
66             $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
67             
68             foreach($files as $file) {
69                 $data = unserialize(file_get_contents($file));
70                 foreach($data as $name => $value) {
71                     $st->execute(array($this->class, $name, $value));
72                 }
73             }
74             
75             $this->PDO->commit();
76             
77             foreach($files as $file) {
78                 unlink($file);
79             }
80         }
81         catch(Exception $e) {
d22cb4 82             if(file_exists(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite')) {
JK 83                 @unlink(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
84             }
8bd4d9 85             throw $e;
JK 86         }
87     }
88     
89     function __get($name) {
90         $this->init();
91         
92         $st = $this->PDO->prepare('SELECT value FROM data WHERE class=? AND name=?');
93         $st->execute(array($this->class, $name));
94         $st = $st->fetch(PDO::FETCH_ASSOC);
95         
96         if(is_array($st)) {
97             return unserialize($st['value']);
98         }
99         else
100         {
101             return NULL;
102         }
103     }
104     
105     function __set($name, $value) {
106         $this->init();
107         
108         $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
109         $st->execute(array($this->class, $name, serialize($value)));
110     }
111     
112     function __isset($name) {
113         $this->init();
114         
115         $st = $this->PDO->prepare('SELECT COUNT(name) FROM data WHERE class=? AND name=?');
116         $st->execute(array($this->class, $name));
117         $st = $st->fetch(PDO::FETCH_NUM);
118         
119         return ($st[0]>0);
120     }
121     
122     function __unset($name) {
123         $this->init();
124         
125         $st = $this->PDO->prepare('DELETE FROM data WHERE class=? AND name=?');
126         $st->execute(array($this->class, $name));
127     }
128     
129     function push($array) {
130         $this->PDO->beginTransaction();
131         foreach($array as $name => $value) {
132             $this->__set($name, $value);
133         }
134         $this->PDO->commit();
135     }
136     
137     function pull() {
138         $this->init();
139         
140         $st = $this->PDO->prepare('SELECT name, value FROM data WHERE class=?');
141         $st->execute(array($this->class));
142         $st = $st->fetchAll(PDO::FETCH_ASSOC);
143         
144         $return = array();
145         foreach($st as $row) {
146             $return[$row['name']] = $row['value'];
147         }
148         
149         return $return;
150     }
151     
57117d 152     function setClass($class) {
JK 153         $this->class = $class;
154     }
155     
8bd4d9 156     function truncate() {
JK 157         $this->init();
158         
159         $st = $this->PDO->prepare('DELETE FROM data WHERE class=?');
160         $st->execute(array($this->class));
161     }
162 }
79d1cc 163 ?>