PageRenderTime 39ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/pmfv2-1-0-alpha-1/inc/gedcom.inc.php

https://github.com/redbugz/rootstech2013
PHP | 504 lines | 468 code | 17 blank | 19 comment | 13 complexity | 1d50cdad3fcfdf5ecbf6ae7ebbcc4dab MD5 | raw file
Possible License(s): AGPL-1.0, BSD-3-Clause
  1. <?php
  2. //phpmyfamily - opensource genealogy webbuilder
  3. //Copyright (C) 2002 - 2005 Simon E Booth (simon.booth@giric.com)
  4. //This program is free software; you can redistribute it and/or
  5. //modify it under the terms of the GNU General Public License
  6. //as published by the Free Software Foundation; either version 2
  7. //of the License, or (at your option) any later version.
  8. //This program is distributed in the hope that it will be useful,
  9. //but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. //GNU General Public License for more details.
  12. //You should have received a copy of the GNU General Public License
  13. //along with this program; if not, write to the Free Software
  14. //Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. require_once("inc/DateUtil.php");
  16. require_once("classes/MiniEvent.php");
  17. error_reporting(E_ALL ^ E_NOTICE);
  18. #Sends errors to the screen instead of the log file
  19. //ini_set('display_errors', false);
  20. $gedname = $_FILES["gedfile"]["name"];
  21. $gedfile = $_FILES["gedfile"]["tmp_name"];
  22. $gedarray = array();
  23. $people = array();
  24. $indi = array();
  25. $family = array();
  26. $marriage = array();
  27. $text = array();
  28. $desc = array();
  29. $pref = array();
  30. $blocks = 0;
  31. $limit = 1000;
  32. // pick up the next auto value from table
  33. $query = "SHOW TABLE STATUS LIKE '".$tblprefix."people'";
  34. $result = mysql_query($query);
  35. while ($row = mysql_fetch_array($result))
  36. $autoval = $row["Auto_increment"];
  37. //This is used as a guess but the actual insert id is picked up into the idmap array
  38. ini_set("auto_detect_line_endings", TRUE);
  39. ?>
  40. <table class="header" width="100%">
  41. <tbody>
  42. <tr>
  43. <td><h3>Importing GedCom file: <?php echo $gedname; ?></h3> </td>
  44. </tr>
  45. </tbody>
  46. </table>
  47. <br>
  48. <!--Check we have a valid file-->
  49. Checking uploaded file is valid:
  50. <?php
  51. if (!empty($gedfile) && file_exists($gedfile)) {
  52. echo " OK<br>\n";
  53. } else {
  54. echo " NO!<br>\n";
  55. die("Error with gedcom file");
  56. }
  57. flush();
  58. ?>
  59. <!--Read the file into an array-->
  60. Reading in file:<br>
  61. <?php
  62. $handle = fopen ($gedfile, "r");
  63. while (!feof ($handle)) {
  64. $buffer = fgets($handle, 4096);
  65. // need to trim the annoying newline
  66. // from end of buffer
  67. if (substr($buffer, 0, 1) == "0")
  68. $blocks++;
  69. $gedarray[$blocks][] = rtrim($buffer);
  70. }
  71. fclose ($handle);
  72. echo ".....read ".($blocks - 1)." blocks<br>\n";
  73. $heads = 0;
  74. $indis = 0;
  75. $notes = 0;
  76. $fams = 0;
  77. $trlrs = 0;
  78. $subns = 0;
  79. $subms = 0;
  80. $sours = 0;
  81. $repos = 0;
  82. $objes = 0;
  83. $unkno = 0;
  84. for ($i = 0; $i < $blocks; $i++) {
  85. switch (substr($gedarray[$i][0], -4)) {
  86. case "HEAD":
  87. $heads++;
  88. break;
  89. case "INDI":
  90. $people[$indis++] = $gedarray[$i];
  91. break;
  92. case "NOTE":
  93. $text[$notes++] = $gedarray[$i];
  94. break;
  95. case " FAM":
  96. $family[$fams++] = $gedarray[$i];
  97. break;
  98. case "TRLR":
  99. $trlrs++;
  100. break;
  101. case "SUBN":
  102. $subns++;
  103. break;
  104. case "SUBM":
  105. $subms++;
  106. break;
  107. case "SOUR":
  108. $sours++;
  109. break;
  110. case "REPO":
  111. $repos++;
  112. break;
  113. case "OBJE":
  114. $objes++;
  115. break;
  116. case "":
  117. break;
  118. default:
  119. $unkno++;
  120. break;
  121. }
  122. }
  123. echo ".....read ".$heads." HEADS<br>\n";
  124. echo ".....read ".$indis." INDIS<br>\n";
  125. echo ".....read ".$fams." FAMS<br>\n";
  126. echo ".....read ".$notes." NOTES<br>\n";
  127. echo ".....read ".$subns." SUBNS<br>\n";
  128. echo ".....read ".$subms." SUBMS<br>\n";
  129. echo ".....read ".$sours." SOURS<br>\n";
  130. echo ".....read ".$objes." OBJES<br>\n";
  131. echo ".....read ".$repos." REPOS<br>\n";
  132. echo ".....read ".$trlrs." TRLRS<br>\n";
  133. if ($unkno > 0) echo ".....read ".$unkno." UNKNOWS<br>\n";
  134. flush();
  135. ?>
  136. <!--parse the array-->
  137. Verifying GedCom data:
  138. <?php
  139. if (in_array("1 GEDC", $gedarray[1]) && in_array("2 VERS 5.5", $gedarray[1]))
  140. echo " OK - correct version header found<br>\n";
  141. else {
  142. print_r($gedarray[1]);
  143. die ("Doesn't seem to be a valid GedCom file!");
  144. }
  145. flush();
  146. ?>
  147. <!--parse the notes first-->
  148. Parsing notes data:
  149. <?php
  150. // process each notes block in turn
  151. for ($i = 0; $i < $notes; $i++) {
  152. $count = count($text[$i]);
  153. // process each line ine the block
  154. for ($c = 0; $c < $count; $c++) {
  155. if ($c == 0)
  156. $temp = substr($text[$i][$c], 3, strlen($text[$i][$c]) - 9);
  157. switch (substr($text[$i][$c], 0, 6)) {
  158. case "1 CONC":
  159. case "1 CONT":
  160. if (array_key_exists($temp, $desc))
  161. $desc[$temp] = $desc[$temp]."\n".substr($text[$i][$c], 6, strlen($text[$i][$c]) - 6);
  162. else
  163. $desc[$temp] = substr($text[$i][$c], 6, strlen($text[$i][$c]) - 6);
  164. break;
  165. default:
  166. break;
  167. }
  168. }
  169. }
  170. echo " OK<br>\n";
  171. flush();
  172. ?>
  173. <!--parse the individual arrays-->
  174. Parsing individual data:
  175. <?php
  176. // process each individual in turn
  177. for ($i = 0; $i < $indis; $i++) {
  178. $count = count($people[$i]);
  179. $indi[$i]["person_id"] = ($autoval + $i - 1);
  180. $previous = "";
  181. // process each record in turn
  182. for ($c = 0; $c < $count; $c++) {
  183. if ($c == 0) {
  184. $temp = substr($people[$i][$c], 3, strlen($people[$i][$c]) - 9);
  185. $indi[$i]["ged_person_ref"] = $temp;
  186. $pref[$temp] = ($autoval + $i -1);
  187. }
  188. switch (substr($people[$i][$c], 0, 6)) {
  189. case "1 NAME":
  190. $indi[$i]["name"] = substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6);
  191. break;
  192. case "1 SEX ":
  193. $indi[$i]["gender"] = substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6);
  194. break;
  195. case "2 DATE":
  196. if ($e != null) {
  197. DateUtil::make_date(substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6),$e);
  198. }
  199. break;
  200. case "2 PLAC":
  201. if ($e != null) {
  202. $e->location->place = trim(htmlentities(substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6), ENT_QUOTES));
  203. }
  204. break;
  205. case "1 NOTE":
  206. if (substr($people[$i][$c], 7, 1) == "@") {
  207. $temp = substr($people[$i][$c], 8, strlen($people[$i][$c]) - 9);
  208. $indi[$i]["note"] = $desc[$temp];
  209. }
  210. else
  211. $indi[$i]["note"] = substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6);
  212. break;
  213. case "1 FAMC":
  214. $indi[$i]["ged_famc"] = substr($people[$i][$c], 8, strlen($people[$i][$c]) - 9);
  215. break;
  216. case "1 FAMS":
  217. $indi[$i]["ged_fams"] = substr($people[$i][$c], 8, strlen($people[$i][$c]) - 9);
  218. break;
  219. case "1 AFN": //permanent record file number of an individual record stored in Ancestral File
  220. case "1 _UID":
  221. $indi[$i]["uid"] = substr($people[$i][$c], 6, strlen($people[$i][$c]) - 6);
  222. default:
  223. break;
  224. }
  225. if (substr($people[$i][$c], 0, 1) == "1") {
  226. $previous = substr($people[$i][$c], 0, 6);
  227. $e = null;
  228. switch ($previous) {
  229. case "1 BIRT":
  230. $e = new MiniEvent();
  231. $e->type = BIRTH_EVENT;
  232. break;
  233. case "1 DEAT":
  234. $e = new MiniEvent();
  235. $e->type = DEATH_EVENT;
  236. break;
  237. case "1 CONF": //Confirmation
  238. case "1 CHR": //Christening
  239. case "1 BAPL": //LDS BAPM
  240. case "1 BAPM":
  241. $e = new MiniEvent();
  242. $e->type = BAPTISM_EVENT;
  243. $e->descrip = substr($previous, 2);
  244. break;
  245. case "1 CREM":
  246. case "1 BURI":
  247. $e = new MiniEvent();
  248. $e->type = BURIAL_EVENT;
  249. $e->descrip = substr($previous, 2);
  250. break;
  251. case "1 CENS":
  252. case "1 EDUC":
  253. case "1 EMIG":
  254. case "1 EVEN":
  255. case "1 OCCU":
  256. case "1 EVEN":
  257. $e = new Event();
  258. $e->type = OTHER_EVENT;
  259. $e->descrip = substr($previous, 2);
  260. break;
  261. }
  262. if ($e != null) {
  263. $indi[$i]["events"][] = $e;
  264. }
  265. }
  266. }
  267. }
  268. echo " OK<br>\n";
  269. flush();
  270. ?>
  271. <!--Parsing family data-->
  272. Parsing marriage data:
  273. <?php
  274. // process each family in turn
  275. for ($i = 0; $i < $fams; $i++) {
  276. $count = count($family[$i]);
  277. // process each row in turn
  278. $previous = "";
  279. for ($c = 0; $c < $count; $c++) {
  280. if ($c == 0)
  281. $marriage[$i]["ged_fam_ref"] = substr($family[$i][$c], 3, strlen($family[$i][$c]) - 8);
  282. switch (substr($family[$i][$c], 0, 6)) {
  283. case "1 HUSB":
  284. $temp = substr($family[$i][$c], 8, strlen($family[$i][$c]) - 9);
  285. $marriage[$i]["groom_id"] = $pref[$temp];
  286. $marriage[$i]["ged_husb_ref"] = $temp;
  287. break;
  288. case "1 WIFE":
  289. $temp = substr($family[$i][$c], 8, strlen($family[$i][$c]) - 9);
  290. $marriage[$i]["bride_id"] = $pref[$temp];
  291. $marriage[$i]["ged_wife_ref"] = $temp;
  292. break;
  293. case "2 DATE":
  294. if ($previous == "1 MARR")
  295. DateUtil::make_date(substr($family[$i][$c], 6, strlen($family[$i][$c]) - 6), $e);
  296. break;
  297. case "2 PLAC":
  298. if ($previous == "1 MARR")
  299. $e->location->place = trim(substr($family[$i][$c], 6, strlen($family[$i][$c]) - 6));
  300. break;
  301. default:
  302. break;
  303. }
  304. if (substr($family[$i][$c], 0, 1) == "1") {
  305. $previous = substr($family[$i][$c], 0, 6);
  306. $e = new MiniEvent();
  307. $marriage[$i]["event"] = $e;
  308. }
  309. }
  310. $parents[$marriage[$i]["ged_fam_ref"]] = $marriage[$i];
  311. }
  312. echo " OK<br>\n";
  313. flush();
  314. ?>
  315. <!--Sort and insert person data-->
  316. Inserting person data:
  317. <?php
  318. $dao = getPeopleDAO();
  319. $t = 0;
  320. $idmap["0"] = "0";
  321. $break = 0;
  322. while ($indis > 0) {
  323. for ($i = 0; $i < $indis; $i++) {
  324. $person = $indi[$i];
  325. // do some sanity checking
  326. if (!array_key_exists("name", $person))
  327. $person["name"] = "";
  328. if (!array_key_exists("gender", $person))
  329. $person["gender"] = "";
  330. if (!array_key_exists("note", $person))
  331. $person["note"] = "";
  332. if (!array_key_exists("father_id", $person))
  333. $person["father_id"] = "0";
  334. if (!array_key_exists("mother_id", $person))
  335. $person["mother_id"] = "0";
  336. $per = new PersonDetail();
  337. if (isset($person["events"])) {
  338. $per->events = $person["events"];
  339. } else {
  340. $per->events = array();
  341. }
  342. $per->gender = $person["gender"];
  343. $per->narrative = htmlspecialchars($person["note"], ENT_QUOTES);
  344. list($per->name->forenames,$per->name->surname,$per->name->suffix) = explode("/", htmlentities($person["name"],ENT_QUOTES));
  345. $per->name->forenames = trim($per->name->forenames);
  346. $per->name->surname = trim($per->name->surname);
  347. $per->name->suffix = trim($per->name->suffix);
  348. $per->mother->person_id = $person["mother_id"] ;
  349. $per->father->person_id = $person["father_id"] ;
  350. if (isset($person["ged_famc"])) {
  351. $fam = $parents[$person["ged_famc"]];
  352. $mid = $fam["ged_wife_ref"];
  353. $fid = $fam["ged_husb_ref"];
  354. $missingParents = false;
  355. if ((isset($fam["ged_wife_ref"]) && !isset($idmap[$mid])) ||
  356. (isset($fam["ged_husb_ref"]) && !isset($idmap[$fid]))) {
  357. if ($break < 2) {
  358. continue;
  359. } else {
  360. $missingParents = true;
  361. }
  362. }
  363. @$per->mother->person_id = $idmap[$mid];
  364. @$per->father->person_id = $idmap[$fid];
  365. }
  366. $resave = false;
  367. if (isset($idmap[$person["ged_person_ref"]])) {
  368. $per->person_id = $idmap[$person["ged_person_ref"]];
  369. $resave = true;
  370. }
  371. // print_r($per);
  372. if ($dao->savePersonDetails($per)) {
  373. $idmap[$person["ged_person_ref"]] = $per->person_id;
  374. @$uid[$person["ged_person_ref"]] = $indi[$i]["uid"];
  375. if (!$missingParents) {
  376. unset($indi[$i]);
  377. }
  378. $t++;
  379. } else {
  380. if (!$resave) {
  381. echo "Failed to save";
  382. print_r($per);
  383. }
  384. }
  385. }
  386. $x = array_values($indi);
  387. $indi = $x;
  388. $x = null;
  389. $oldindis = $indis;
  390. $indis = count($indi);
  391. if ($oldindis == $indis) {
  392. if ($break <= 1) {
  393. $x = array_reverse($indi);
  394. $indi = $x;
  395. }
  396. if ($break > 3) {
  397. break;
  398. }
  399. $break++;
  400. } else {
  401. $break = 0;
  402. }
  403. }
  404. echo "$t people inserted OK<br>\n";
  405. if ($indis > 0) {
  406. echo "$indis people failed to insert OK<br>\n";
  407. print_r($indis);
  408. }
  409. flush();
  410. ?>
  411. <!--sort and insert marriages-->
  412. Inserting marriage data:
  413. <?php
  414. $t = 0;
  415. for ($i = 0; $i < $fams; $i++) {
  416. if (!array_key_exists("groom_id", $marriage[$i])) {
  417. print_r($marriage[$i]);
  418. continue;
  419. }
  420. if (!array_key_exists("bride_id", $marriage[$i])) {
  421. print_r($marriage[$i]);
  422. continue;
  423. }
  424. if (!array_key_exists("dom", $marriage[$i]))
  425. $marriage[$i]["dom"] = "0000-00-00";
  426. if (!array_key_exists("place", $marriage[$i]))
  427. $marriage[$i]["place"] = "";
  428. if (!isset($idmap[$marriage[$i]["ged_husb_ref"]]) || !isset($idmap[$marriage[$i]["ged_wife_ref"]])) {
  429. echo "Missing spouse data for:";
  430. print_r($marriage[$i]);
  431. continue;
  432. }
  433. $rel = new Relationship();
  434. $rel->person->gender = "M";
  435. $rel->person->person_id = $idmap[$marriage[$i]["ged_husb_ref"]];
  436. $rel->relation->person_id = $idmap[$marriage[$i]["ged_wife_ref"]];
  437. $e = new Event();
  438. $e->type = MARRIAGE_EVENT;
  439. $e->person = $rel->person;
  440. $e->date1 = $marriage[$i]["dom"];
  441. $e->location->place = htmlspecialchars($marriage[$i]["place"], ENT_QUOTES);
  442. $rel->event = $e;
  443. if ($rel->dissolve_date == "") $rel->dissolve_date = "0000-00-00" ;
  444. $dao = getRelationsDAO();
  445. $dao->saveRelationshipDetails($rel);
  446. // inc the counter
  447. $t++;
  448. }
  449. echo " OK<br>\n";
  450. echo " $t marriages inserted<br>\n";
  451. include_once "modules/gedcom/GedcomDAO.php";
  452. $gdao = new GedcomDAO();
  453. foreach ($idmap as $ged => $db) {
  454. if ($db > 0) {
  455. $gdao->insertReference($ged, $idmap[$ged], $gedname, $uid[$ged]);
  456. }
  457. }
  458. ?>
  459. Done!!!!!!(Phew)<br>
  460. <br>
  461. Click <a href="index.php">here</a> to return to the homepage.<br>