Jacek Kowalski
2013-09-05 0868e0642f694bf5c08951f67f5a4b7eadde041a
commit | author | age
8bd4d9 1 <?php
JK 2 /**
0868e0 3  * Klasa przechowująca dane przekazane przez użytkownika,
JK 4  * w szczególności jego ustawienia.
8bd4d9 5  */
JK 6 class BotSession {
7     private $PDO;
8     
9     /**
10      * Nazwa modułu, którego zmienne klasa przetwarza
0868e0 11      * @var string $class max. 40 znaków
8bd4d9 12      */
7b043b 13     protected $class = '';
JK 14     protected $class_empty = TRUE;
8bd4d9 15     
0868e0 16     /**
JK 17      * Pseudo-URL użytkownika.
18      * @see BotUser
19      * @var string $user URL użytkownika
20      */
8bd4d9 21     private $user;
0868e0 22     /**
JK 23      * Klasa z identyfikatorem użytkownika
24      * @var BotUser $user_struct
25      */
26     private $user_struct;
8bd4d9 27     
JK 28     /**
29      * Inicjuje klasę w zależności od użytkownika
30      */
31     function __construct($user) {
32         $this->user = sha1($user);
33         $this->user_struct = parse_url($user);
34         
7b043b 35         $this->class_empty = FALSE;
8bd4d9 36     }
JK 37     
38     private function init() {
7b043b 39         if(strlen($this->class) == 0 && !$this->class_empty) {
57117d 40             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 41         }
42         
8bd4d9 43         if($this->PDO) {
JK 44             return NULL;
45         }
46         
47         if(is_file(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite')) {
48             $this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
49             $this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
50             $this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
d0a0d9 51             
JK 52             $st = $this->PDO->query('SELECT value FROM data WHERE class=\'\' AND name=\'_version\'');
11a929 53             $row = $st->fetch(PDO::FETCH_ASSOC);
JK 54             if(is_array($row)) {
d0a0d9 55                 $version = (int)$row['value'];
JK 56             }
57             else
58             {
59                 $version = 0;
60             }
61             $st->closeCursor();
62             
63             if($version < 1) {
64                 $this->PDO->query('UPDATE data SET class=\'kino\' WHERE class=\'\' AND name=\'kino\'');
65                 $this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 1)');
66                 $version = 1;
67             }
68             
0868e0 69             if($version < 4) {
f93f55 70                 $this->PDO->query('DELETE FROM data WHERE class IS NULL AND name=\'user_struct\'');
0868e0 71                 $this->PDO->query('INSERT OR REPLACE INTO data (class, name, value) VALUES (\'\', \'_version\', 4)');
JK 72                 $version = 4;
3c97a4 73             }
JK 74             
8bd4d9 75             return;
JK 76         }
77         
78         try {
79             $this->PDO = new PDO('sqlite:'.BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
80             $this->PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
81             $this->PDO->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_TO_STRING);
82             
83             $this->PDO->query(
84                 'CREATE TABLE data (
0868e0 85                     class VARCHAR(50) NOT NULL DEFAULT \'\',
8bd4d9 86                     name VARCHAR(40) NOT NULL,
JK 87                     value TEXT NOT NULL,
88                     PRIMARY KEY (
89                         class ASC,
90                         name ASC
91                     )
92                 )'
93             );
94             
0868e0 95             $this->PDO->query('INSERT INTO data (class, name, value) VALUES (\'\', \'_version\', 4)');
JK 96             
8bd4d9 97             $files = glob(BOT_TOPDIR.'/db/*/'.$this->user_struct['user'].'.ggdb');
c661ee 98             if(!$files) {
JK 99                 return;
100             }
8bd4d9 101             
JK 102             $this->PDO->beginTransaction();
103             $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
104             
105             foreach($files as $file) {
106                 $data = unserialize(file_get_contents($file));
107                 foreach($data as $name => $value) {
0868e0 108                     $st->execute(array($this->class, $name, serialize($value)));
8bd4d9 109                 }
JK 110             }
111             
112             $this->PDO->commit();
113             
114             foreach($files as $file) {
115                 unlink($file);
116             }
117         }
118         catch(Exception $e) {
d22cb4 119             if(file_exists(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite')) {
JK 120                 @unlink(BOT_TOPDIR.'/database/'.sha1($this->user).'.sqlite');
121             }
8bd4d9 122             throw $e;
JK 123         }
124     }
125     
0868e0 126     /**
JK 127      * Ustawia nazwę modułu/klasy, której zmienne będą przetwarzane
128      * @param string $class Nazwa modułu
129      */
130     function setClass($class) {
131         $this->class = $class;
132     }
133     
134     /**
135      * Pobiera zmienną modułu o podanej nazwie (getter).
136      * @param string $name Nazwa zmiennej
137      * @return mixed Wartość zmiennej lub NULL
138      */
8bd4d9 139     function __get($name) {
JK 140         $this->init();
141         
142         $st = $this->PDO->prepare('SELECT value FROM data WHERE class=? AND name=?');
143         $st->execute(array($this->class, $name));
144         $st = $st->fetch(PDO::FETCH_ASSOC);
145         
146         if(is_array($st)) {
147             return unserialize($st['value']);
148         }
149         else
150         {
151             return NULL;
152         }
153     }
154     
0868e0 155     /**
JK 156      * Ustawia zmienną o podanej nazwie
157      * @param string $name Nazwa zmiennej
158      * @param mixed $value Wartość zmiennej
159      */
8bd4d9 160     function __set($name, $value) {
JK 161         $this->init();
162         
163         $st = $this->PDO->prepare('INSERT OR REPLACE INTO data (class, name, value) VALUES (?, ?, ?)');
164         $st->execute(array($this->class, $name, serialize($value)));
165     }
166     
0868e0 167     /**
JK 168      * Sprawdza czy podana zmienna została ustawiona.
169      * @param string $name Nazwa zmiennej
170      * @return bool Czy zmienna istnieje?
171      */
8bd4d9 172     function __isset($name) {
JK 173         $this->init();
174         
175         $st = $this->PDO->prepare('SELECT COUNT(name) FROM data WHERE class=? AND name=?');
176         $st->execute(array($this->class, $name));
177         $st = $st->fetch(PDO::FETCH_NUM);
178         
179         return ($st[0]>0);
180     }
181     
0868e0 182     /**
JK 183      * Usuwa zmienną o podanej nazwie
184      * @param string $name Nazwa zmiennej
185      */
8bd4d9 186     function __unset($name) {
JK 187         $this->init();
188         
189         $st = $this->PDO->prepare('DELETE FROM data WHERE class=? AND name=?');
190         $st->execute(array($this->class, $name));
191     }
192     
0868e0 193     /**
JK 194      * Zapamiętuje tablicę zmiennych danego modułu
195      * @param array $array Tablica zmiennych
196      */
8bd4d9 197     function push($array) {
JK 198         $this->PDO->beginTransaction();
199         foreach($array as $name => $value) {
200             $this->__set($name, $value);
201         }
202         $this->PDO->commit();
203     }
204     
0868e0 205     /**
JK 206      * Zwraca wszystkie ustawione zmienne danego modułu
207      * @return array Lista wszystkich zmiennych
208      */
8bd4d9 209     function pull() {
JK 210         $this->init();
211         
212         $st = $this->PDO->prepare('SELECT name, value FROM data WHERE class=?');
213         $st->execute(array($this->class));
214         $st = $st->fetchAll(PDO::FETCH_ASSOC);
215         
216         $return = array();
217         foreach($st as $row) {
0868e0 218             $return[$row['name']] = unserialize($row['value']);
8bd4d9 219         }
JK 220         
221         return $return;
222     }
223     
0868e0 224     /**
JK 225      * Usuwa wszystkie zmienne sesyjne danego modułu.
226      */
8bd4d9 227     function truncate() {
JK 228         $this->init();
229         
230         $st = $this->PDO->prepare('DELETE FROM data WHERE class=?');
231         $st->execute(array($this->class));
232     }
233 }
79d1cc 234 ?>