PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/install/installer/assets/class.databases.php

https://gitlab.com/billyprice1/ClanCaller
PHP | 375 lines | 222 code | 49 blank | 104 comment | 36 complexity | b599df0ed86250b8ee8b5ce2e1db70e1 MD5 | raw file
  1. <?php if(!defined('INST_BASEDIR')) die('Direct access is not allowed!');
  2. /* ====================================================================
  3. *
  4. * PHP Setup Wizard
  5. *
  6. * -= DATABASE INTERACTION =-
  7. *
  8. * ================================================================= */
  9. /**
  10. * Connects to database and executes queries
  11. */
  12. class Inst_Databases
  13. {
  14. private $connection, $dbselected, $dbname;
  15. /**
  16. * Connects to database and executes queries
  17. */
  18. function Inst_Databases()
  19. {
  20. $this->connection = false; # Default connection
  21. $this->dbselected = false; # Database link
  22. $this->dbname = ''; # Selected database name
  23. }
  24. /*==============================================[ DATABASE CONNECTION ]==============================================*/
  25. /**
  26. * Connect to database server
  27. */
  28. function Connect($host='', $user='', $pass='', $port='')
  29. {
  30. // This method accepts $keywords['connection'] array to be passed
  31. // for $host, othervice the other two will be used instead
  32. if(is_array($host))
  33. {
  34. $hostport = $host['hostname'];
  35. if(strlen($host['dbport']) > 0)
  36. $hostport = $hostport.':'.$host['dbport'];
  37. $this->connection = mysql_connect($hostport, $host['username'], $host['password']);
  38. }
  39. else
  40. {
  41. if(strlen($port) > 0)
  42. $host = $host.':'.$port;
  43. $this->connection = mysql_connect($host, $user, $pass);
  44. }
  45. }
  46. /**
  47. * Disconnect from the database server
  48. */
  49. function Disconnect()
  50. {
  51. if($this->IsConnected())
  52. {
  53. mysql_close($this->connection);
  54. $this->dbselected = false;
  55. $this->dbname = false;
  56. }
  57. }
  58. /**
  59. * If the resource is connected to the database
  60. */
  61. function IsConnected()
  62. {
  63. return ($this->connection) ? true : false;
  64. }
  65. /**
  66. * Get an error message from database
  67. */
  68. function GetDatabaseError()
  69. {
  70. return mysql_error();
  71. }
  72. /**
  73. * Run a query to the selected database, or run
  74. * multiple queries (if parameter is an array)
  75. */
  76. function RunQuery($query)
  77. {
  78. if(is_array($query))
  79. {
  80. $results = array();
  81. foreach($query as $q)
  82. {
  83. // Do not process empty queries
  84. $q = trim($q);
  85. if(strlen($q) == 0)
  86. continue;
  87. // Execute the query and return the results with
  88. // success state and error message if set
  89. $result = mysql_query($q, $this->connection);
  90. if($result)
  91. $results[] = array('success'=>true, 'data'=>$result, 'error'=>'');
  92. else $results[] = array('success'=>false, 'data'=>$result, 'error'=>$this->GetDatabaseError());
  93. }
  94. return $results;
  95. }
  96. else
  97. {
  98. return mysql_query($query, $this->connection);
  99. }
  100. }
  101. /*==============================================[ DATABASES ]==============================================*/
  102. /**
  103. * Select a database to run queries in
  104. */
  105. function SelectDatabase($database)
  106. {
  107. $this->dbselected = mysql_select_db($database, $this->connection);
  108. if($this->IsDatabaseSelected())
  109. $this->dbname = $database;
  110. else $this->dbname = false;
  111. }
  112. /**
  113. * Has a database been selected
  114. */
  115. function IsDatabaseSelected()
  116. {
  117. return ($this->dbselected) ? true : false;
  118. }
  119. /**
  120. * Get the name of the selected database. NOTE: If no database
  121. * has been selected then false is returned.
  122. */
  123. function GetDatabaseName()
  124. {
  125. return $this->dbname;
  126. }
  127. /**
  128. * If you want to create a database, this function must approve
  129. * the name of the new database in order for it to be created!
  130. * The string must be on the form: a-z, 0-9 or _
  131. */
  132. function IsDatabaseFriendly($database)
  133. {
  134. return preg_match("/^[a-z0-9_]*$/i", strtolower($database));
  135. }
  136. /**
  137. * Create new database whitin the resource connected to
  138. */
  139. function CreateNewDatabase($database)
  140. {
  141. // The database name must be approved first!
  142. if(!$this->IsDatabaseFriendly($database))
  143. return false;
  144. // The $database contains legal values
  145. $query = "CREATE DATABASE ".$database.";";
  146. $result = $this->RunQuery($query);
  147. if(mysql_affected_rows($this->connection) > 0)
  148. return true;
  149. else return false;
  150. }
  151. /**
  152. * Does a database exist or not
  153. */
  154. function DoesDatabaseExist($database)
  155. {
  156. $database = strtolower($database);
  157. $dblist = $this->GetDatabaseList();
  158. foreach($dblist as $idx=>$db)
  159. {
  160. if($db['name'] == $database)
  161. return true;
  162. }
  163. return false;
  164. }
  165. /**
  166. * Get a list of databases and their table count
  167. */
  168. function GetDatabaseList($includeSelectedDatabase=true)
  169. {
  170. /*
  171. * NOTE: In some cases the query "SHOW DATABASES;" will be denied on the target
  172. * webserver. If that happens, the returned list here will always be empty.
  173. *
  174. * All functionality that relays on the fact that this list WILL give the
  175. * list of "available databases" will most likely expect the selected database
  176. * to be in it!
  177. *
  178. * However, if this workaround [$includeSelectedDatabase] is not set to true,
  179. * the list will be empty if denied. So, if a database has been selected and
  180. * that selected database is NOT in this list here - add it anyway!
  181. */
  182. // Only return array if connected to MySQL server
  183. if($this->IsConnected())
  184. {
  185. $dblist = array();
  186. $result = $this->RunQuery('SHOW DATABASES;');
  187. // If the result has data - then user
  188. // has SHOW DATABASE privilege
  189. if($result)
  190. {
  191. while ($row = mysql_fetch_object($result))
  192. {
  193. $tbresult = $this->RunQuery("SHOW TABLES FROM ".$row->Database);
  194. $dblist[] = array(
  195. 'name' => $row->Database,
  196. 'tbcount' => mysql_num_rows($tbresult)
  197. );
  198. }
  199. // If to make sure the selected database is in the list
  200. if($includeSelectedDatabase && $this->IsDatabaseSelected())
  201. {
  202. $notInList = true;
  203. foreach($dblist as $db)
  204. {
  205. if($db['name'] == $this->GetDatabaseName())
  206. {
  207. $notInList = false;
  208. break;
  209. }
  210. }
  211. if($notInList)
  212. {
  213. $tbresult = $this->RunQuery("SHOW TABLES FROM ".$this->GetDatabaseName());
  214. $dblist[] = array(
  215. 'name' => $this->GetDatabaseName(),
  216. 'tbcount' => mysql_num_rows($tbresult)
  217. );
  218. }
  219. }
  220. return $dblist;
  221. }
  222. // SHOW DATABASE; query does not return anything or user does not
  223. // have permission to run this query
  224. else
  225. {
  226. // Making sure the selected database will be in the list
  227. $dblist = array();
  228. if($includeSelectedDatabase && $this->IsDatabaseSelected())
  229. {
  230. // Get table count from the selected database (if that is allowed =))
  231. $tbresult = $this->RunQuery("SHOW TABLES FROM ".$this->GetDatabaseName());
  232. $dblist[] = array(
  233. 'name' => $this->GetDatabaseName(),
  234. 'tbcount' => mysql_num_rows($tbresult)
  235. );
  236. }
  237. // Return empty array, or an array with selected database only
  238. return $dblist;
  239. }
  240. }
  241. return false;
  242. }
  243. /**
  244. * Get a list of database names only
  245. */
  246. function GetDatabaseNameList()
  247. {
  248. $dbList = $this->GetDatabaseList();
  249. $output = array();
  250. foreach($dbList as $idx=>$db)
  251. {
  252. $output[] = $db['name'];
  253. }
  254. return $output;
  255. }
  256. /**
  257. * Get a list of tables that are within the selected database. NOTE: If
  258. * there is no database selected, an empty array will be returned.
  259. */
  260. function GetTableListFromDatabase()
  261. {
  262. if($this->IsConnected() && $this->IsDatabaseSelected() && strlen($this->GetDatabaseName()) > 0)
  263. {
  264. $list = array();
  265. $result = $this->RunQuery("SHOW TABLES FROM ".$this->GetDatabaseName());
  266. if($result && mysql_num_rows($result) > 0)
  267. {
  268. while ($row = mysql_fetch_row($result))
  269. $list[] = $row[0];
  270. }
  271. return $list;
  272. }
  273. else
  274. return array();
  275. }
  276. /*==============================================[ TESTING PRIVILEGES ]==============================================*/
  277. /**
  278. * Run few queries to see if the user has the access needed to create the tables for
  279. * the system being installed, and the privileges to manipulate data. If any of these
  280. * will fail the system being installed might not work properly due to limited privileges
  281. */
  282. function TestUserPrivileges()
  283. {
  284. $outcome = array();
  285. $totalSuccess = true;
  286. $testTable = 'installer_query_testing_table';
  287. // The testing queries
  288. $testing = array
  289. (
  290. 'create' => "CREATE TABLE `".$testTable."` ( ".
  291. "`id` INT NOT NULL AUTO_INCREMENT , ".
  292. "`text` VARCHAR( 255 ) NOT NULL , ".
  293. "PRIMARY KEY ( `id` ))",
  294. 'insert' => "INSERT INTO `".$testTable."` (`id`, `text`) VALUES ".
  295. "(NULL , 'this is the first row'), (NULL , 'this is the second row');",
  296. 'select' => "SELECT * FROM `".$testTable."`;",
  297. 'update' => "UPDATE `".$testTable."` SET `text` = 'text updated' ".
  298. "WHERE `".$testTable."`.`id` = '2';",
  299. 'delete' => "DELETE FROM `".$testTable."` WHERE `id` = '1';",
  300. 'alter' => "ALTER TABLE `".$testTable."` ADD UNIQUE (`text`)",
  301. 'drop' => "DROP TABLE `".$testTable."`"
  302. );
  303. // First, check if the testing table exists, if it does, try
  304. // to drop it. If "drop" or "show tables" are denied then the
  305. // testing queries will as well.This process will not be shown
  306. // in the outcome of the tests - just tries to be sure that
  307. // CREATE TABLE command will be executed when the table does not exist!
  308. if($this->RunQuery("SHOW TABLES LIKE '".$testTable."'"))
  309. $this->RunQuery("DROP TABLE `".$testTable."`");
  310. // Do all the testing queries
  311. foreach($testing as $test=>$query)
  312. {
  313. $result = $this->RunQuery($query);
  314. if($result)
  315. $outcome[$test] = array('success'=>true, 'query'=>$query, 'error'=>'');
  316. else
  317. {
  318. $totalSuccess = false;
  319. $outcome[$test] = array('success'=>false, 'query'=>$query, 'error'=>$this->GetDatabaseError());
  320. }
  321. }
  322. // Add more info to the $outcome before returning
  323. $outcome['totalsuccess'] = $totalSuccess;
  324. return $outcome;
  325. }
  326. }