Jacek Kowalski
2012-09-17 d0a0d9e70b92e25ebcf9fc7851fb5b44030faa6f
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);
d0a0d9 40             
JK 41             $st = $this->PDO->query('SELECT value FROM data WHERE class=\'\' AND name=\'_version\'');
42             if($st->rowCount > 0) {
43                 $row = $st->fetch(PDO::FETCH_ASSOC);
44                 $version = (int)$row['value'];
45             }
46             else
47             {
48                 $version = 0;
49             }
50             $st->closeCursor();
51             
52             if($version < 1) {
53                 $this->PDO->query('UPDATE data SET class=\'kino\' WHERE class=\'\' AND name=\'kino\'');
54                 $this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 1)');
55                 $version = 1;
56             }
57             
8bd4d9 58             return;
JK 59         }
60         
61         try {
62             $this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
63             $this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
64             $this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
65             
66             $this->PDO->query(
67                 'CREATE TABLE data (
68                     class VARCHAR(50),
69                     name VARCHAR(40) NOT NULL,
70                     value TEXT NOT NULL,
71                     PRIMARY KEY (
72                         class ASC,
73                         name ASC
74                     )
75                 )'
76             );
77             
78             $files = glob(BOT_TOPDIR.'/db/*/'.$this->user_struct['user'].'.ggdb');
c661ee 79             if(!$files) {
JK 80                 return;
81             }
8bd4d9 82             
JK 83             $this->PDO->beginTransaction();
84             $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
85             
d0a0d9 86             $st->execute(array('', '_version', 1));
JK 87             
8bd4d9 88             foreach($files as $file) {
JK 89                 $data = unserialize(file_get_contents($file));
90                 foreach($data as $name => $value) {
91                     $st->execute(array($this->class, $name, $value));
92                 }
93             }
94             
95             $this->PDO->commit();
96             
97             foreach($files as $file) {
98                 unlink($file);
99             }
100         }
101         catch(Exception $e) {
d22cb4 102             if(file_exists(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite')) {
JK 103                 @unlink(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
104             }
8bd4d9 105             throw $e;
JK 106         }
107     }
108     
109     function __get($name) {
110         $this->init();
111         
112         $st = $this->PDO->prepare('SELECT value FROM data WHERE class=? AND name=?');
113         $st->execute(array($this->class, $name));
114         $st = $st->fetch(PDO::FETCH_ASSOC);
115         
116         if(is_array($st)) {
117             return unserialize($st['value']);
118         }
119         else
120         {
121             return NULL;
122         }
123     }
124     
125     function __set($name, $value) {
126         $this->init();
127         
128         $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
129         $st->execute(array($this->class, $name, serialize($value)));
130     }
131     
132     function __isset($name) {
133         $this->init();
134         
135         $st = $this->PDO->prepare('SELECT COUNT(name) FROM data WHERE class=? AND name=?');
136         $st->execute(array($this->class, $name));
137         $st = $st->fetch(PDO::FETCH_NUM);
138         
139         return ($st[0]>0);
140     }
141     
142     function __unset($name) {
143         $this->init();
144         
145         $st = $this->PDO->prepare('DELETE FROM data WHERE class=? AND name=?');
146         $st->execute(array($this->class, $name));
147     }
148     
149     function push($array) {
150         $this->PDO->beginTransaction();
151         foreach($array as $name => $value) {
152             $this->__set($name, $value);
153         }
154         $this->PDO->commit();
155     }
156     
157     function pull() {
158         $this->init();
159         
160         $st = $this->PDO->prepare('SELECT name, value FROM data WHERE class=?');
161         $st->execute(array($this->class));
162         $st = $st->fetchAll(PDO::FETCH_ASSOC);
163         
164         $return = array();
165         foreach($st as $row) {
166             $return[$row['name']] = $row['value'];
167         }
168         
169         return $return;
170     }
171     
57117d 172     function setClass($class) {
JK 173         $this->class = $class;
174     }
175     
8bd4d9 176     function truncate() {
JK 177         $this->init();
178         
179         $st = $this->PDO->prepare('DELETE FROM data WHERE class=?');
180         $st->execute(array($this->class));
181     }
182 }
79d1cc 183 ?>