00001 <?php
00002
00003 class SUserConfig extends SObject {
00004 private $types = array();
00005 private $default = array();
00006 private $user = array();
00007 private $session = array();
00008
00009 private $userId = null;
00010 private $project = null;
00011
00012 private $userToSave = array();
00013
00014 private $_result;
00015
00016 private static $DBI = null;
00017
00018 public function __construct($project = '*', $userId = null) {
00019 parent::__construct();
00020
00021 if(self::$DBI) {
00022 self::$DBI = new DBI2('userconfig', SConfig::getDefault('snap2.prod.dbhost'),
00023 SConfig::getDefault('snap2.prod.dbname'),
00024 SConfig::getDefault('snap2.prod.admin.dbuser'),
00025 SConfig::getDefault('snap2.prod.admin.dbpass'));
00026 }
00027
00028 if($userId === null) {
00029
00030 $guser = $GLOBALS['SWAT']->getGlobalUser();
00031 $ldap = $guser->getAuthModule('ldap');
00032 $userId = $ldap->getUID();
00033 }
00034
00035 $this->project = $project;
00036 $this->userId = $userId;
00037
00038 $this->loadDefaults();
00039 $this->loadUser();
00040 $this->loadSession();
00041
00042 register_shutdown_function(array($this, 'saveSession'));
00043 }
00044
00048 public function loadDefaults() {
00049 if(isset($GLOBALS['USER_CONFIG_DEFAULTS'])) {
00050 foreach($GLOBALS['USER_CONFIG_DEFAULTS'] as $entry) {
00051 $this->setDefault($entry[0], $entry[1], $entry[2], $entry[3]);
00052 }
00053 }
00054 }
00055
00059 public function loadUser() {
00060 $query = 'SELECT opt, page, value FROM UserConfig WHERE uid = ' . $this->userId
00061 . ' AND project = \'' . mysql_escape_string($this->project) . '\'';
00062 $result = self::$DBI->query($query);
00063 foreach($result as $r) {
00064 $this->setUser($r['opt'], $r['page'], $r['value']);
00065 }
00066 }
00067
00071 public function loadSession() {
00072 $key = 'SWATUC:' . $this->project . ':' . $this->userId;
00073 if(isset($_SESSION[$key]))
00074 $this->session = json_decode($_SESSION[$key], true);
00075 }
00076
00080 public function saveUser() {
00081 if(count($this->userToSave) == 0) {
00082 return true;}
00083
00084 $remove = array();
00085 $removeNum = 0;
00086 $add = array();
00087
00088 foreach($this->userToSave as $constraints => $keep) {
00089 $tmp = explode("\000", $constraints);
00090 $opt = $tmp[0];
00091 $page = $tmp[1];
00092 if($keep)
00093 $add[] = '(\'' . mysql_escape_string($this->project) . '\', ' . $this->userId . ', \''
00094 . mysql_escape_string($opt) . '\', \'' . mysql_escape_string($page) . '\', \''
00095 . mysql_escape_string($this->user[$opt][$page]) . '\')';
00096 else
00097 $remove[] = '(opt="' . mysql_escape_string($opt) . '"'
00098 . ' AND page="' . mysql_escape_string($page) . '"'
00099 . ' AND project="' . mysql_escape_string($this->project) . '"'
00100 . ' AND uid=' . $this->userId . ')';
00101 $removeNum++;
00102 }
00103
00104 self::$DBI->startTransaction();
00105
00106 if(!empty($add)) {
00107 $addQuery = 'REPLACE INTO UserConfig (project, uid, opt, page, value) VALUES ' . implode(',', $add);
00108 if(self::$DBI->query($addQuery) === null) {
00109 self::$DBI->cancelTransaction();
00110 return false;
00111 }
00112 }
00113
00114 if(!empty($remove)) {
00115 $delQuery = 'DELETE FROM UserConfig WHERE ' . implode(' OR ', $remove) . ' LIMIT ' . $removeNum;
00116 $delRes = self::$DBI->query($delQuery) !== null;
00117 if(self::$DBI->query($addQuery) === null) {
00118 self::$DBI->cancelTransaction();
00119 return false;
00120 }
00121 }
00122
00123 if(!self::$DBI->commitTransaction())
00124 return false;
00125
00126 $this->userToSave = array();
00127
00128 return true;
00129 }
00130
00134 public function sessionToUser() {
00135 foreach($this->session as $option => $pages) {
00136 foreach($pages as $page => $value) {
00137 if($value !== null) {
00138 $this->setUser($option, $page, $value);
00139 }
00140 }
00141 }
00142 }
00143
00153 public function unsetConfig($domain, $option, $page) {
00154 $delete = array();
00155 if($domain !== null) {
00156 if($domain == 'user') {
00157 $delete['user'] = $this->user;
00158 } elseif($domain == 'session') {
00159 $delete['session'] = $this->session;
00160 }
00161 }
00162
00163 if(empty($delete)) {
00164 $delete['user'] = $this->user;
00165 $delete['session'] = $this->session;
00166 }
00167 if($option !== null) {
00168 foreach($delete as $currentDomain => $currentOptions) {
00169 foreach($currentOptions as $currentOption => $currentPages) {
00170 if($currentOption != $option) {
00171 unset($delete[$currentDomain][$currentOption]);
00172 }
00173 }
00174 }
00175 }
00176 if($page !== null) {
00177 foreach($delete as $currentDomain => $currentOptions) {
00178 foreach($currentOptions as $currentOption => $currentPages) {
00179 foreach($currentPages as $currentPage => $value) {
00180 if($currentPage != $page) {
00181 unset($delete[$currentDomain][$currentOption][$currentPage]);
00182 }
00183 }
00184 }
00185 }
00186 }
00187 foreach($delete as $currentDomain => $currentOptions) {
00188 foreach($currentOptions as $currentOption => $currentPages) {
00189 foreach($currentPages as $currentPage => $value) {
00190 unset($this->{$currentDomain}[$currentOption][$currentPage]);
00191 if($currentDomain == 'user')
00192 $this->userToSave["$currentOption\000$currentPage"] = false;
00193 }
00194 if(empty($currentPages))
00195 unset($delete[$currentDomain][$currentOption]);
00196 }
00197 if(empty($currentOptions))
00198 unset($delete[$currentDomain]);
00199 }
00200 return $delete;
00201 }
00202
00206 public function saveSession() {
00207 $key = 'SWATUC:' . $this->project . ':' . $this->userId;
00208 $_SESSION[$key] = json_encode($this->session);
00209 }
00210
00218 public function setDefault($opt, $page, $val, $type = 'string') {
00219 if($val === null)
00220 unset($this->default[$opt][$page]);
00221 else {
00222 $this->default[$opt][$page] = $val;
00223 $this->types[$opt] = $type;
00224 }
00225 }
00226
00235 private function setInternal(&$array, $opt, $page, $val) {
00236 if(!isset($this->types[$opt])) {
00237 $this->setError('Invalid preference: ' . $opt);
00238 return false;
00239 }
00240 if($val === null)
00241 unset($array[$opt][$page]);
00242 else {
00243 switch($this->types[$opt]) {
00244 case 'integer':
00245 if(!ctype_digit($val)) {
00246 $this->setError("$opt requires an integer");
00247 return false;
00248 }
00249 break;
00250 case 'boolean':
00251 if($val !== true && $val !== false && $val != '0' && $val != '1'
00252 && $val != 'true' && $val != 'false' && $val != '')
00253 {
00254 $this->setError("$opt requires a boolean");
00255 return false;
00256 }
00257 if($val == '1' || $val == 'true' || $val === true)
00258 $val = true;
00259 else
00260 $val = false;
00261 break;
00262 }
00263 $array[$opt][$page] = $val;
00264 return true;
00265 }
00266 }
00267
00275 public function setUser($opt, $page, $val) {
00276 if($this->setInternal($this->user, $opt, $page, $val)) {
00277 $this->userToSave["$opt\000$page"] = true;
00278 }else
00279 return false;
00280 return true;
00281 }
00282
00290 public function setSession($opt, $page, $val) {
00291 $result = $this->setInternal($this->session, $opt, $page, $val);
00292 return $result;
00293 }
00294
00301 public function getOption($opt, $page = '*') {
00302 if($this->getOptionFrom($this->session, $opt, $page)) {
00303 return $this->_result;
00304 }
00305 if($this->getOptionFrom($this->user, $opt, $page)) {
00306 return $this->_result;
00307 }
00308 if($this->getOptionFrom($this->default, $opt, $page)) {
00309 return $this->_result;
00310 }
00311 return null;
00312 }
00313
00320 public function getDefault($opt, $page = '*') {
00321 if($this->getOptionFrom($this->default, $opt, $page))
00322 return $this->_result;
00323 else {
00324 foreach($this->default[$opt] as $pg => $val) {
00325 if($page == '*' || preg_match("!^$pg$!", $page))
00326 return $val;
00327 }
00328 return null;
00329 }
00330 }
00331
00338 public function getUser($opt, $page = '*') {
00339 if($this->getOptionFrom($this->user, $opt, $page))
00340 return $this->_result;
00341 else
00342 return null;
00343 }
00344
00351 public function getSession($opt, $page = '*') {
00352 if($this->getOptionFrom($this->session, $opt, $page))
00353 return $this->_result;
00354 else
00355 return null;
00356 }
00357
00363 public function getOptionType($opt) {
00364 if(isset($this->types[$opt]))
00365 return $this->types[$opt];
00366 else
00367 return null;
00368 }
00369
00376 public function getOptions() {
00377 $res = array();
00378 foreach($this->default as $opt => $info)
00379 foreach($info as $page => $val)
00380 $res[$opt][$page] = $val;
00381 foreach($this->user as $opt => $info)
00382 foreach($info as $page => $val)
00383 $res[$opt][$page] = $val;
00384 foreach($this->session as $opt => $info)
00385 foreach($info as $page => $val)
00386 $res[$opt][$page] = $val;
00387 return $res;
00388 }
00389
00393 private function getOptionFrom($array, $opt, $page) {
00394 if(!isset($array[$opt]))
00395 return false;
00396
00397 if(isset($array[$opt][$page])) {
00398 $this->_result = $array[$opt][$page];
00399 return true;
00400 }
00401 if(isset($array[$opt]['*'])) {
00402 $this->_result = $array[$opt]['*'];
00403 return true;
00404 }
00405 foreach($array[$opt] as $pg => $val) {
00406 if(preg_match("!^$pg$!", $page)) {
00407 $this->_result = $val;
00408 return true;
00409 }
00410 }
00411 return false;
00412 }
00413
00421 public static function regexEscape($str) {
00422 $chars = array('\\','^',')','$','.','[',']','|','(',')','?','*','+','{','}');
00423 $escape = array('\\\\','\\^','\\)','\\$','\\.','\\[','\\]','\\|','\\(','\\)','\\?','\\*','\\+','\\{','\\}');
00424 return str_replace($chars, $escape, $str);
00425 }
00426
00432 public static function regexUnescape($str) {
00433 $chars = array('\\\\','\\^','\\)','\\$','\\.','\\[','\\]','\\|','\\(','\\)','\\?','\\*','\\+','\\{','\\}');
00434 $escape = array('\\','^',')','$','.','[',']','|','(',')','?','*','+','{','}');
00435 return str_replace($chars, $escape, $str);
00436 }
00437
00445 public static function stripPrefix($str, $prefix = false) {
00446 if($prefix === false) {
00447 global $PATH;
00448 $prefix = $PATH['home'];
00449 }
00450 $len = strlen($prefix);
00451 if(substr($str, 0, $len) == $prefix) {
00452 $str = substr($str, $len);
00453 }
00454 return $str;
00455 }
00456 }
00457
00458 ?>