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