PageRenderTime 36ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/include/imports.php

https://gitlab.com/nexxuz/phpBMS
PHP | 500 lines | 325 code | 128 blank | 47 comment | 42 complexity | 55ae96ce3993d29bd1ebdaeeb8a62a5e MD5 | raw file
  1. <?php
  2. class phpbmsImport{
  3. var $table;
  4. var $error = "";
  5. var $docError = "";
  6. var $row = 0;
  7. var $transactionIDs = array();
  8. var $importType;
  9. var $data;
  10. var $revertID = 0;
  11. // Do not manually override
  12. var $transactionRecords = array();
  13. var $tempFileID = 0;
  14. var $pageType = "main";
  15. function phpbmsImport($table, $importType = "csv"){
  16. $this->table = $table;
  17. $this->importType = $importType;
  18. switch($this->importType){
  19. case "csv":
  20. $this->parser = new parseCSV;
  21. break;
  22. }//end switch
  23. $this->table->db->logError = true;
  24. //So, that, when there is a db error, it will go all the way through and not just stop
  25. $this->table->db->stopOnError = false;
  26. //Won't display db errors, just log them.
  27. $this->table->db->showError = false;
  28. }//end method --imports--
  29. function _parseFromData($data){
  30. switch($this->importType){
  31. case "csv":
  32. if(is_readable($data)){
  33. $contents = $this->_getFile($data);
  34. if(is_readable($contents)){
  35. $this->docError = "invalid csv document";
  36. return false;
  37. }//end if
  38. }//end if
  39. $this->parser->parse($data);
  40. if(!count($this->parser->titles) || !count($this->parser->data)){
  41. $this->docError = "invalid csv document";
  42. return false;
  43. }//end if
  44. return true;
  45. break;
  46. }//end swtich
  47. }//end method --_parseFromFile--
  48. function _getTransactionData(){
  49. //needs to be changed for more complicated tables
  50. $inStatement = "";
  51. foreach($this->transactionIDs as $theid)
  52. $inStatement .= $theid.",";
  53. if($inStatement){
  54. $inStatement = substr($inStatement, 0, -1);
  55. $querystatement = "
  56. SELECT
  57. *
  58. FROM
  59. `".$this->table->maintable."`
  60. WHERE
  61. `id` IN (".$inStatement.");
  62. ";
  63. $queryresult = $this->table->db->query($querystatement);
  64. while($therecord = $this->table->db->fetchArray($queryresult))
  65. $this->transactionRecords[] = $therecord;
  66. }//end if
  67. }//end method --_getTransactionData--
  68. function _getFile($fileName){
  69. if(function_exists('file_get_contents')){
  70. $file = addslashes(file_get_contents($fileName));
  71. }else{
  72. // If using PHP < 4.3.0 use the following:
  73. $file = addslashes(fread(fopen($fileName, 'r'), filesize($fileName)));
  74. }//end if
  75. return $file;
  76. }//end method --_getFile--
  77. //DO NOT CALL IN TRANSACTION
  78. function _storeTempCSV($fileName){
  79. $querystatement = "
  80. INSERT INTO
  81. `files`
  82. (
  83. `uuid`,
  84. `name`,
  85. `description`,
  86. `file`,
  87. `type`,
  88. `roleid`,
  89. `creationdate`,
  90. `createdby`,
  91. `modifiedby`
  92. )
  93. VALUES
  94. (
  95. '".uuid(getUuidPrefix($this->table->db, "tbld:80b4f38d-b957-bced-c0a0-ed08a0db6475"))."',
  96. 'temporary',
  97. 'This is a temporary import file',
  98. '".$this->_getFile($fileName)."',
  99. 'phpbms/temp',
  100. 'Admin',
  101. NOW(),
  102. '".$_SESSION["userinfo"]["id"]."',
  103. '".$_SESSION["userinfo"]["id"]."'
  104. )
  105. ";
  106. $this->table->db->query($querystatement);
  107. $id = $this->table->db->insertId();
  108. if($id)
  109. $this->tempFileID = ((int) $id);
  110. else
  111. $this->error .= '<li> inserting temporary file failure </li>';
  112. }//end method --_storeTempCSV--
  113. function _getTempCSV($tempFileID){
  114. if($tempFileID){
  115. $querystatement = "
  116. SELECT
  117. `file`
  118. FROM
  119. `files`
  120. WHERE
  121. id = ".((int)$tempFileID)."
  122. ";
  123. $queryresult = $this->table->db->query($querystatement);
  124. $therecord = $this->table->db->fetchArray($queryresult);
  125. return $therecord["file"];
  126. }//end if
  127. return false;
  128. }//end method --_getTempCSV--
  129. //DO NOT CALL IN TRANSACTION
  130. function _removeTempCSV($tempFileID = 0){
  131. $querystatement = "
  132. DELETE FROM
  133. `files`
  134. WHERE
  135. `type` = 'phpbms/temp'
  136. AND
  137. (
  138. `id` = ".((int)$tempFileID)."
  139. OR
  140. `creationdate` <= NOW() - INTERVAL 30 MINUTE
  141. );
  142. ";
  143. $queryresult = $this->table->db->query($querystatement);
  144. $querystatement = "
  145. ALTER TABLE
  146. `files`
  147. AUTO_INCREMENT = ".((int) $tempFileID).";
  148. ";
  149. $queryresult = $this->table->db->query($querystatement);
  150. }//end method --_removeTempCSV--
  151. //DO NOT USE THIS METHOD INSIDE AN OPEN TRANSACTION.
  152. //IT WILL AUTOMATICALLY COMMIT THE TRANSACTION
  153. function _revertAutoIncrement($revertID = 0){
  154. //check to see if there is a revert id (i.e. there was a valid insert)
  155. if($revertID)
  156. if(is_numeric($revertID)){
  157. $querystatement = "
  158. ALTER TABLE
  159. `".$this->table->maintable."`
  160. AUTO_INCREMENT = ".((int) $revertID).";
  161. ";
  162. $this->table->db->query($querystatement);
  163. }//end if
  164. }//end method --_revertAutoIncrement--
  165. function importRecords($rows, $titles){
  166. switch($this->importType){
  167. case "csv":
  168. //count total fieldnames (top row of csv document)
  169. $fieldNum = count($titles);
  170. //the file starts at line number 1, but since line 1 is
  171. //supposed to be the fieldnames in the table(s), the lines
  172. //being insereted start @ 2.
  173. $rowNum = 2;
  174. //get the data one row at a time
  175. foreach($rows as $rowData){
  176. $theid = 0; // set for when verifification does not pass
  177. $verify = array(); //set for when number of field rows does not match number of titles
  178. //trim off leading/trailing spaces
  179. $trimmedRowData = array();
  180. foreach($rowData as $name => $data)
  181. $trimmedRowData[$name] = trim($data);
  182. //check to see if number of fieldnames is consistent for each row
  183. $rowFieldNum = count($trimmedRowData);
  184. //if valid, insert, if not, log error and don't insert.
  185. if($rowFieldNum == $fieldNum){
  186. $verify = $this->table->verifyVariables($trimmedRowData);
  187. if(!count($verify)){
  188. $createdby = NULL;
  189. $overrideID = true;
  190. $replace = false;
  191. if(!isset($trimmedRowData["uuid"])){
  192. $useUuid = true;
  193. $thereturn = $this->table->insertRecord($trimmedRowData, $createdby, $overrideID, $replace, $useUuid);
  194. $theid = $thereturn["id"];
  195. }else{
  196. $useUuid = false;
  197. $thereturn = $this->table->insertRecord($trimmedRowData, $createdby, $overrideID, $replace, $useUuid);
  198. $theid = $thereturn;
  199. }
  200. }//end if
  201. }else
  202. $this->error .= '<li> incorrect amount of fields for line number '.$rowNum.'.</li>';
  203. if($theid){
  204. //keep track of the ids in the transaction to be able to select them
  205. //for preview purposes
  206. $this->transactionIDs[] = $theid;
  207. //get first id to correct auto increment
  208. if(!$this->revertID)
  209. $this->revertID = $theid;
  210. }else
  211. $this->error .= '<li> failed insert for line number '.$rowNum.'.</li>';
  212. foreach($verify as $error)
  213. $this->error .= '<li class="subError">'.$error.'</li>';
  214. $rowNum++;
  215. }//end foreach
  216. break;
  217. }//end switch
  218. }//end method --importRecords--
  219. function displayTransaction($recordsArray, $fieldsArray){
  220. //needs to be changed for more complicated tables
  221. if(count($recordsArray) && count($fieldsArray)){
  222. ?>
  223. <h2>Import Preview</h2>
  224. <div id="transactionDiv">
  225. <table id="transactionTable">
  226. <thead>
  227. <tr>
  228. <?php
  229. foreach($fieldsArray as $field => $junk){
  230. ?><th align="left" nowrap="nowrap"><?php
  231. echo formatVariable($field);
  232. ?></th><?php
  233. }//end foreach
  234. $field = NULL;
  235. ?>
  236. </tr>
  237. </thead>
  238. <tbody>
  239. <?php
  240. $i = 1;
  241. foreach($recordsArray as $record){
  242. ?><tr class="qr<?php echo $i ?>" ><?php
  243. foreach($fieldsArray as $field => $junk){
  244. ?><td nowrap="nowrap"><?php
  245. echo formatVariable($record[$field]);
  246. ?></td><?php
  247. }//end foreach
  248. ?></tr><?php
  249. $i = ($i == 1)?2:1;
  250. }//end while
  251. ?>
  252. </tbody>
  253. </table>
  254. </div>
  255. <?php
  256. }//end if
  257. }//end method --displayTransaction--
  258. function processImportPage(){
  259. $this->table->getTableInfo();
  260. if(isset($_POST["pageType"]))
  261. $this->pageType = $_POST["pageType"];
  262. if(isset($_POST["tempFileID"]))
  263. $this->tempFileID = ((int)$_POST["tempFileID"]);
  264. if(!isset($_POST["command"])){
  265. //happens upon first coming to page
  266. //remove any other temporary csv files in the `files` table
  267. //present from previous imports
  268. $this->_removeTempCSV();
  269. //check to see if user has the rights to be here.
  270. //If not, kick him to the no access page.
  271. if(!hasRights($this->table->importroleid))
  272. goURL(APP_PATH."noaccess.php");
  273. }else{
  274. //form has been submitted
  275. switch($_POST["command"]){
  276. //cancel button pressed.
  277. case "cancel":
  278. //Cancel button needs to do different things depending upon which page
  279. //its at.
  280. if($this->pageType == "main")
  281. goURL($this->table->backurl);
  282. else{
  283. $this->_removeTempCSV($this->tempFileID);
  284. $therecord["phpbmsStatus"] = "Record(s) Not Imported";
  285. $this->pageType = "main";
  286. }//end if
  287. break;
  288. case "upload":
  289. //check for valid file upload
  290. if(!$_FILES["import"]["error"] && ($_FILES["import"]["size"] > 0)){
  291. //check and parse the file
  292. if($this->_parseFromData($_FILES["import"]["tmp_name"])){
  293. //start transaction
  294. $this->table->db->startTransaction();
  295. $this->importRecords($this->parser->data, $this->parser->titles);
  296. //get data for preview purposes
  297. $this->_getTransactionData();
  298. //"undo" any inserts
  299. $this->table->db->rollbackTransaction();
  300. //DO NOT CALL IN TRANSACTION
  301. //ALTER TABLES AUTO COMMIT AND THE FILE NEEDS TO CARRY
  302. //OVER.
  303. $this->_revertAutoIncrement($this->revertID);
  304. $this->_storeTempCSV($_FILES["import"]["tmp_name"]);
  305. }//end if
  306. }else
  307. $this->docError .= "failed file upload";
  308. //switch page types
  309. $this->pageType = "confirm";
  310. if(!$this->error && !$this->docError){
  311. $therecord["phpbmsStatus"] = "Confirm Import";
  312. }elseif($this->docError){
  313. $therecord["phpbmsStatus"] = "Import Error: ".$this->docError;
  314. $this->pageType = "main";
  315. }else
  316. $therecord["phpbmsStatus"] = "Import Error";
  317. break;
  318. case "import":
  319. //get the contents of the stored csv document
  320. $CSVcontents = $this->_getTempCSV($this->tempFileID);
  321. //parser uses newline character to be able to parse the last line
  322. if(substr($CSVcontents,-1,1) != "\n")
  323. $CSVcontents .= "\n";
  324. $this->parser->parse($CSVcontents);
  325. $this->importRecords($this->parser->data, $this->parser->titles);
  326. $this->table->db->commitTransaction();
  327. //DO NOT CALL IN TRANSACTION
  328. //get rid of temporary csv document
  329. $this->_removeTempCSV($this->tempFileID);
  330. $therecord["phpbmsStatus"] = "Record(s) Imported";
  331. //change page type
  332. $this->pageType = "main";
  333. break;
  334. }//end command switch
  335. }// end if
  336. //display the title
  337. $therecord["title"] = $this->table->displayname." Import";
  338. return $therecord;
  339. }//end method --imports--
  340. }//end class --imports--
  341. //this class is to have different buttons, and no created/modified.
  342. if(class_exists("phpbmsForm")){
  343. class importForm extends phpbmsForm{
  344. function importForm($action = NULL, $method="post", $name="record", $onsubmit="return validateForm(this);", $dontSubmit = true){
  345. parent::phpbmsForm($action,$method,$name,$onsubmit,$dontSubmit);
  346. }//end method --importForm--
  347. function startForm($pageTitle, $pageType, $numberOfRecords = 0){
  348. ?><form action="<?php echo htmlentities($this->action) ?>" method="<?php echo $this->method?>" name="<?php echo $this->name?>" onsubmit="<?php echo $this->onsubmit?>" <?php
  349. if(isset($this->enctype)) echo ' enctype="'.$this->enctype.'" ';
  350. if(isset($this->id)) echo ' id="'.$this->id.'" ';
  351. ?>><?php
  352. if($this->dontSubmit){
  353. ?><div id="dontSubmit"><input type="submit" value=" " onclick="return false;" /></div><?php
  354. } ?>
  355. <div id="topButtons"><?php $this->showButtons(1, $pageType, $numberOfRecords); ?></div>
  356. <h1 id="h1Title"><span><?php echo $pageTitle ?></span></h1><?php
  357. }//end method --startForm--
  358. function showButtons($ids = 1, $pageType = "main", $numberOfRecords = 0){
  359. ?>
  360. <div class="importCancels">
  361. <?php if($pageType == "main"){ ?>
  362. <input <?php if($ids==1) {?>accesskey="u"<?php }?> title="Upload (alt+u)" id="uploadButton<?php echo $ids?>" name="command" type="submit" value="upload" class="Buttons" />
  363. <input id="cancelButton<?php echo $ids?>" name="command" type="submit" value="cancel" class="Buttons" <?php if($ids==1) {?>accesskey="x" <?php }?> title="(access key+x)" />
  364. <?php }else{?>
  365. <input type="submit" class="Buttons" value="import" name="command" id="import<?php echo $ids?>" title="commit" <?php if($ids==1) {?>accesskey="i"<?php }?> <?php echo ($numberOfRecords? '':'disabled="disabled"') ?>/>
  366. <input type="submit" class="Buttons" value="cancel" name="command" id="cancelButton<?php echo $ids?>" <?php if($ids==1) {?>accesskey="x"<?php }?> title="rollback"/>
  367. <?php }//end if ?>
  368. </div><?php
  369. }//end method --showButtons--
  370. }//end class --importForm--
  371. }
  372. ?>