/** * print fact PLACe TEMPle STATus * * @param Fact $event gedcom fact record * @param bool $anchor to print a link to placelist * @param bool $sub_records to print place subrecords * @param bool $lds to print LDS TEMPle and STATus * * @return string HTML */ public static function formatFactPlace(Fact $event, $anchor = false, $sub_records = false, $lds = false) { if ($anchor) { // Show the full place name, for facts/events tab $html = '<a href="' . $event->getPlace()->getURL() . '">' . $event->getPlace()->getFullName() . '</a>'; } else { // Abbreviate the place name, for chart boxes return ' - ' . $event->getPlace()->getShortName(); } if ($sub_records) { $placerec = Functions::getSubRecord(2, '2 PLAC', $event->getGedcom()); if (!empty($placerec)) { if (preg_match_all('/\\n3 (?:_HEB|ROMN) (.+)/', $placerec, $matches)) { foreach ($matches[1] as $match) { $wt_place = new Place($match, $event->getParent()->getTree()); $html .= ' - ' . $wt_place->getFullName(); } } $map_lati = ""; $cts = preg_match('/\\d LATI (.*)/', $placerec, $match); if ($cts > 0) { $map_lati = $match[1]; $html .= '<br><span class="label">' . GedcomTag::getLabel('LATI') . ': </span>' . $map_lati; } $map_long = ''; $cts = preg_match('/\\d LONG (.*)/', $placerec, $match); if ($cts > 0) { $map_long = $match[1]; $html .= ' <span class="label">' . GedcomTag::getLabel('LONG') . ': </span>' . $map_long; } if ($map_lati && $map_long) { $map_lati = trim(strtr($map_lati, "NSEW,�", " - -. ")); // S5,6789 ==> -5.6789 $map_long = trim(strtr($map_long, "NSEW,�", " - -. ")); // E3.456� ==> 3.456 $html .= ' <a rel="nofollow" href="https://maps.google.com/maps?q=' . $map_lati . ',' . $map_long . '" class="icon-googlemaps" title="' . I18N::translate('Google Maps™') . '"></a>'; $html .= ' <a rel="nofollow" href="https://www.bing.com/maps/?lvl=15&cp=' . $map_lati . '~' . $map_long . '" class="icon-bing" title="' . I18N::translate('Bing Maps™') . '"></a>'; $html .= ' <a rel="nofollow" href="https://www.openstreetmap.org/#map=15/' . $map_lati . '/' . $map_long . '" class="icon-osm" title="' . I18N::translate('OpenStreetMap™') . '"></a>'; } if (preg_match('/\\d NOTE (.*)/', $placerec, $match)) { $html .= '<br>' . self::printFactNotes($placerec, 3); } } } if ($lds) { if (preg_match('/2 TEMP (.*)/', $event->getGedcom(), $match)) { $html .= '<br>' . I18N::translate('LDS temple') . ': ' . GedcomCodeTemp::templeName($match[1]); } if (preg_match('/2 STAT (.*)/', $event->getGedcom(), $match)) { $html .= '<br>' . I18N::translate('Status') . ': ' . GedcomCodeStat::statusName($match[1]); if (preg_match('/3 DATE (.*)/', $event->getGedcom(), $match)) { $date = new Date($match[1]); $html .= ', ' . GedcomTag::getLabel('STAT:DATE') . ': ' . $date->display(); } } } return $html; }
/** * Print a row for the notes tab on the individual page. * * @param Fact $fact * @param int $level */ public static function printMainNotes(Fact $fact, $level) { $factrec = $fact->getGedcom(); $fact_id = $fact->getFactId(); $parent = $fact->getParent(); $pid = $parent->getXref(); if ($fact->isPendingAddition()) { $styleadd = ' new'; $can_edit = $level == 1 && $fact->canEdit(); } elseif ($fact->isPendingDeletion()) { $styleadd = ' old'; $can_edit = false; } else { $styleadd = ''; $can_edit = $level == 1 && $fact->canEdit(); } $ct = preg_match_all("/{$level} NOTE (.*)/", $factrec, $match, PREG_SET_ORDER); for ($j = 0; $j < $ct; $j++) { // Note object, or inline note? if (preg_match("/{$level} NOTE @(.*)@/", $match[$j][0], $nmatch)) { $note = Note::getInstance($nmatch[1], $fact->getParent()->getTree()); if ($note && !$note->canShow()) { continue; } } else { $note = null; } if ($level >= 2) { echo '<tr class="row_note2"><td class="descriptionbox rela ', $styleadd, ' width20">'; } else { echo '<tr><td class="descriptionbox ', $styleadd, ' width20">'; } if ($can_edit) { echo '<a onclick="return edit_record(\'', $pid, '\', \'', $fact_id, '\');" href="#" title="', I18N::translate('Edit'), '">'; if ($level < 2) { if ($fact->getParent()->getTree()->getPreference('SHOW_FACT_ICONS')) { echo '<i class="icon-note"></i> '; } if ($note) { echo GedcomTag::getLabel('SHARED_NOTE'); } else { echo GedcomTag::getLabel('NOTE'); } echo '</a>'; echo '<div class="editfacts">'; echo "<div class=\"editlink\"><a class=\"editicon\" onclick=\"return edit_record('{$pid}', '{$fact_id}');\" href=\"#\" title=\"" . I18N::translate('Edit') . "\"><span class=\"link_text\">" . I18N::translate('Edit') . "</span></a></div>"; echo '<div class="copylink"><a class="copyicon" href="#" onclick="return copy_fact(\'', $pid, '\', \'', $fact_id, '\');" title="' . I18N::translate('Copy') . '"><span class="link_text">' . I18N::translate('Copy') . '</span></a></div>'; echo "<div class=\"deletelink\"><a class=\"deleteicon\" onclick=\"return delete_fact('" . I18N::translate('Are you sure you want to delete this fact?') . "', '{$pid}', '{$fact_id}');\" href=\"#\" title=\"" . I18N::translate('Delete') . "\"><span class=\"link_text\">" . I18N::translate('Delete') . "</span></a></div>"; if ($note) { echo '<a class="icon-note" href="', $note->getHtmlUrl(), '" title="' . I18N::translate('View') . '"><span class="link_text">' . I18N::translate('View') . '</span></a>'; } echo '</div>'; } } else { if ($level < 2) { if ($fact->getParent()->getTree()->getPreference('SHOW_FACT_ICONS')) { echo '<i class="icon-note"></i> '; } if ($note) { echo GedcomTag::getLabel('SHARED_NOTE'); } else { echo GedcomTag::getLabel('NOTE'); } } $factlines = explode("\n", $factrec); // 1 BIRT Y\n2 NOTE ... $factwords = explode(" ", $factlines[0]); // 1 BIRT Y $factname = $factwords[1]; // BIRT $parent = GedcomRecord::getInstance($pid, $fact->getParent()->getTree()); if ($factname == 'EVEN' || $factname == 'FACT') { // Add ' EVEN' to provide sensible output for an event with an empty TYPE record $ct = preg_match("/2 TYPE (.*)/", $factrec, $ematch); if ($ct > 0) { $factname = trim($ematch[1]); echo $factname; } else { echo GedcomTag::getLabel($factname, $parent); } } elseif ($factname != 'NOTE') { // Note is already printed echo GedcomTag::getLabel($factname, $parent); if ($note) { echo '<div class="editfacts"><a class="icon-note" href="', $note->getHtmlUrl(), '" title="' . I18N::translate('View') . '"><span class="link_text">' . I18N::translate('View') . '</span></a></div>'; } } } echo '</td>'; if ($note) { // Note objects if (Module::getModuleByName('GEDFact_assistant')) { // If Census assistant installed, allow it to format the note $text = CensusAssistantModule::formatCensusNote($note); } else { $text = Filter::formatText($note->getNote(), $fact->getParent()->getTree()); } } else { // Inline notes $nrec = Functions::getSubRecord($level, "{$level} NOTE", $factrec, $j + 1); $text = $match[$j][1] . Functions::getCont($level + 1, $nrec); $text = Filter::formatText($text, $fact->getParent()->getTree()); } echo '<td class="optionbox', $styleadd, ' wrap">'; echo $text; if (!empty($noterec)) { echo self::printFactSources($noterec, 1); } // 2 RESN tags. Note, there can be more than one, such as "privacy" and "locked" if (preg_match_all("/\n2 RESN (.+)/", $factrec, $matches)) { foreach ($matches[1] as $match) { echo '<br><span class="label">', GedcomTag::getLabel('RESN'), ':</span> <span class="field">'; switch ($match) { case 'none': // Note: "2 RESN none" is not valid gedcom, and the GUI will not let you add it. // However, webtrees privacy rules will interpret it as "show an otherwise private fact to public". echo '<i class="icon-resn-none"></i> ', I18N::translate('Show to visitors'); break; case 'privacy': echo '<i class="icon-resn-privacy"></i> ', I18N::translate('Show to members'); break; case 'confidential': echo '<i class="icon-resn-confidential"></i> ', I18N::translate('Show to managers'); break; case 'locked': echo '<i class="icon-resn-locked"></i> ', I18N::translate('Only managers can edit'); break; default: echo $match; break; } echo '</span>'; } } echo '</td></tr>'; } }
/** * Places administration. */ private function adminPlaces() { global $WT_TREE; $action = Filter::get('action'); $parent = Filter::get('parent'); $inactive = Filter::getBool('inactive'); $deleteRecord = Filter::get('deleteRecord'); if (!isset($parent)) { $parent = 0; } $controller = new PageController(); $controller->restrictAccess(Auth::isAdmin()); if ($action == 'ExportFile' && Auth::isAdmin()) { $tmp = $this->placeIdToHierarchy($parent); $maxLevel = $this->getHighestLevel(); if ($maxLevel > 8) { $maxLevel = 8; } $tmp[0] = 'places'; $outputFileName = preg_replace('/[:;\\/\\\\(\\)\\{\\}\\[\\] $]/', '_', implode('-', $tmp)) . '.csv'; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $outputFileName . '"'); echo '"', I18N::translate('Level'), '";"', I18N::translate('Country'), '";'; if ($maxLevel > 0) { echo '"', I18N::translate('State'), '";'; } if ($maxLevel > 1) { echo '"', I18N::translate('County'), '";'; } if ($maxLevel > 2) { echo '"', I18N::translate('City'), '";'; } if ($maxLevel > 3) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 4) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 5) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 6) { echo '"', I18N::translate('Place'), '";'; } if ($maxLevel > 7) { echo '"', I18N::translate('Place'), '";'; } echo '"', I18N::translate('Longitude'), '";"', I18N::translate('Latitude'), '";'; echo '"', I18N::translate('Zoom level'), '";"', I18N::translate('Icon'), '";', WT_EOL; $this->outputLevel($parent); exit; } $controller->setPageTitle(I18N::translate('Google Maps™'))->pageHeader(); ?> <ol class="breadcrumb small"> <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?> </a></li> <li><a href="admin_modules.php"><?php echo I18N::translate('Module administration'); ?> </a></li> <li class="active"><?php echo $controller->getPageTitle(); ?> </li> </ol> <ul class="nav nav-tabs nav-justified" role="tablist"> <li role="presentation"> <a href="?mod=googlemap&mod_action=admin_config" role="tab"> <?php echo I18N::translate('Google Maps™ preferences'); ?> </a> </li> <li role="presentation" class="active"> <a href="#"> <?php echo I18N::translate('Geographic data'); ?> </a> </li> <li role="presentation"> <a href="?mod=googlemap&mod_action=admin_placecheck"> <?php echo I18N::translate('Place check'); ?> </a> </li> </ul> <h2><?php echo I18N::translate('Geographic data'); ?> </h2> <?php if ($action == 'ImportGedcom') { $placelist = array(); $j = 0; $gedcom_records = Database::prepare("SELECT i_gedcom FROM `##individuals` WHERE i_file=? UNION ALL SELECT f_gedcom FROM `##families` WHERE f_file=?")->execute(array($WT_TREE->getTreeId(), $WT_TREE->getTreeId()))->fetchOneColumn(); foreach ($gedcom_records as $gedrec) { $i = 1; $placerec = Functions::getSubRecord(2, '2 PLAC', $gedrec, $i); while (!empty($placerec)) { if (preg_match("/2 PLAC (.+)/", $placerec, $match)) { $placelist[$j] = array(); $placelist[$j]['place'] = trim($match[1]); if (preg_match("/4 LATI (.*)/", $placerec, $match)) { $placelist[$j]['lati'] = trim($match[1]); if ($placelist[$j]['lati'][0] != 'N' && $placelist[$j]['lati'][0] != 'S') { if ($placelist[$j]['lati'] < 0) { $placelist[$j]['lati'][0] = 'S'; } else { $placelist[$j]['lati'] = 'N' . $placelist[$j]['lati']; } } } else { $placelist[$j]['lati'] = null; } if (preg_match("/4 LONG (.*)/", $placerec, $match)) { $placelist[$j]['long'] = trim($match[1]); if ($placelist[$j]['long'][0] != 'E' && $placelist[$j]['long'][0] != 'W') { if ($placelist[$j]['long'] < 0) { $placelist[$j]['long'][0] = 'W'; } else { $placelist[$j]['long'] = 'E' . $placelist[$j]['long']; } } } else { $placelist[$j]['long'] = null; } $j = $j + 1; } $i = $i + 1; $placerec = Functions::getSubRecord(2, '2 PLAC', $gedrec, $i); } } asort($placelist); $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k => $place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $j = $j + 1; } elseif ($place['place'] == $prevPlace && ($place['lati'] != $prevLati || $place['long'] != $prevLong)) { if ($placelistUniq[$j - 1]['lati'] == 0 || $placelistUniq[$j - 1]['long'] == 0) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; } elseif ($place['lati'] != '0' || $place['long'] != '0') { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '<br>'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $highestIndex = $this->getHighestIndex(); $default_zoom_level = array(4, 7, 10, 12); foreach ($placelistUniq as $k => $place) { $parent = preg_split('/ *, */', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { if (!isset($default_zoom_level[$i])) { $default_zoom_level[$i] = $default_zoom_level[$i - 1]; } $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ?")->execute(array($i, $parent_id, $escparent))->fetchOneRow(); if ($i < count($parent) - 1) { // Create higher-level places, if necessary if (empty($row)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom) VALUES (?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '<br>'; $parent_id = $highestIndex; } else { $parent_id = $row->pl_id; } } else { // Create lowest-level place, if necessary if (empty($row->pl_id)) { $highestIndex++; Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom) VALUES (?, ?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $default_zoom_level[$i])); echo Filter::escapeHtml($escparent), '<br>'; } else { if (empty($row->pl_long) && empty($row->pl_lati) && $place['lati'] != '0' && $place['long'] != '0') { Database::prepare("UPDATE `##placelocation` SET pl_lati=?, pl_long=? WHERE pl_id=?")->execute(array($place['lati'], $place['long'], $row->pl_id)); echo Filter::escapeHtml($escparent), '<br>'; } } } } } $parent = 0; } if ($action === 'ImportFile') { $placefiles = $this->findFiles(WT_MODULES_DIR . 'googlemap/extra'); sort($placefiles); ?> <form class="form-horizontal" method="post" enctype="multipart/form-data" id="importfile" name="importfile" action="module.php?mod=googlemap&mod_action=admin_places&action=ImportFile2"> <!-- PLACES FILE --> <div class="form-group"> <label class="control-label col-sm-4" for="placesfile"> <?php echo I18N::translate('File containing places (CSV)'); ?> </label> <div class="col-sm-8"> <div class="btn btn-default"> <input id="placesfile" type="file" name="placesfile"> </div> </div> </div> <!-- LOCAL FILE --> <?php if (count($placefiles) > 0) { ?> <div class="form-group"> <label class="control-label col-sm-4" for="localfile"> <?php echo I18N::translate('Server file containing places (CSV)'); ?> </label> <div class="col-sm-8"> <div class="input-group"> <span class="input-group-addon"> <?php echo WT_MODULES_DIR . 'googlemap/extra/'; ?> </span> <?php foreach ($placefiles as $p => $placefile) { unset($placefiles[$p]); $p = Filter::escapeHtml($placefile); if (substr($placefile, 0, 1) == "/") { $placefiles[$p] = substr($placefile, 1); } else { $placefiles[$p] = $placefile; } } echo FunctionsEdit::selectEditControl('localfile', $placefiles, '', '', 'class="form-control"'); ?> </div> </div> </div> <?php } ?> <!-- CLEAR DATABASE --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Delete all existing geographic data before importing the file.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('cleardatabase', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- UPDATE ONLY --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Do not create new locations, just import coordinates for existing locations.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('updateonly', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- OVERWRITE DATA --> <fieldset class="form-group"> <legend class="control-label col-sm-4"> <?php echo I18N::translate('Overwrite existing coordinates.'); ?> </legend> <div class="col-sm-8"> <?php echo FunctionsEdit::editFieldYesNo('overwritedata', 0, 'class="radio-inline"'); ?> </div> </fieldset> <!-- SAVE BUTTON --> <div class="form-group"> <div class="col-sm-offset-4 col-sm-8"> <button type="submit" class="btn btn-primary"> <i class="fa fa-check"></i> <?php echo I18N::translate('Continue adding'); ?> </button> </div> </div> </form> <?php exit; } if ($action === 'ImportFile2') { $country_names = array(); $stats = new Stats($WT_TREE); foreach ($stats->iso3166() as $key => $value) { $country_names[$key] = I18N::translate($key); } if (Filter::postBool('cleardatabase')) { Database::exec("DELETE FROM `##placelocation` WHERE 1=1"); } if (!empty($_FILES['placesfile']['tmp_name'])) { $lines = file($_FILES['placesfile']['tmp_name']); } elseif (!empty($_REQUEST['localfile'])) { $lines = file(WT_MODULES_DIR . 'googlemap/extra' . $_REQUEST['localfile']); } // Strip BYTE-ORDER-MARK, if present if (!empty($lines[0]) && substr($lines[0], 0, 3) === WT_UTF8_BOM) { $lines[0] = substr($lines[0], 3); } asort($lines); $highestIndex = $this->getHighestIndex(); $placelist = array(); $j = 0; $maxLevel = 0; foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if ($fieldrec[0] > $maxLevel) { $maxLevel = $fieldrec[0]; } } $fields = count($fieldrec); $set_icon = true; if (!is_dir(WT_MODULES_DIR . 'googlemap/places/flags/')) { $set_icon = false; } foreach ($lines as $p => $placerec) { $fieldrec = explode(';', $placerec); if (is_numeric($fieldrec[0]) && $fieldrec[0] <= $maxLevel) { $placelist[$j] = array(); $placelist[$j]['place'] = ''; for ($ii = $fields - 4; $ii > 1; $ii--) { if ($fieldrec[0] > $ii - 2) { $placelist[$j]['place'] .= $fieldrec[$ii] . ','; } } foreach ($country_names as $countrycode => $countryname) { if ($countrycode == strtoupper($fieldrec[1])) { $fieldrec[1] = $countryname; break; } } $placelist[$j]['place'] .= $fieldrec[1]; $placelist[$j]['long'] = $fieldrec[$fields - 4]; $placelist[$j]['lati'] = $fieldrec[$fields - 3]; $placelist[$j]['zoom'] = $fieldrec[$fields - 2]; if ($set_icon) { $placelist[$j]['icon'] = trim($fieldrec[$fields - 1]); } else { $placelist[$j]['icon'] = ''; } $j = $j + 1; } } $prevPlace = ''; $prevLati = ''; $prevLong = ''; $placelistUniq = array(); $j = 0; foreach ($placelist as $k => $place) { if ($place['place'] != $prevPlace) { $placelistUniq[$j] = array(); $placelistUniq[$j]['place'] = $place['place']; $placelistUniq[$j]['lati'] = $place['lati']; $placelistUniq[$j]['long'] = $place['long']; $placelistUniq[$j]['zoom'] = $place['zoom']; $placelistUniq[$j]['icon'] = $place['icon']; $j = $j + 1; } elseif ($place['place'] == $prevPlace && ($place['lati'] != $prevLati || $place['long'] != $prevLong)) { if ($placelistUniq[$j - 1]['lati'] == 0 || $placelistUniq[$j - 1]['long'] == 0) { $placelistUniq[$j - 1]['lati'] = $place['lati']; $placelistUniq[$j - 1]['long'] = $place['long']; $placelistUniq[$j - 1]['zoom'] = $place['zoom']; $placelistUniq[$j - 1]['icon'] = $place['icon']; } elseif ($place['lati'] != '0' || $place['long'] != '0') { echo 'Difference: previous value = ', $prevPlace, ', ', $prevLati, ', ', $prevLong, ' current = ', $place['place'], ', ', $place['lati'], ', ', $place['long'], '<br>'; } } $prevPlace = $place['place']; $prevLati = $place['lati']; $prevLong = $place['long']; } $default_zoom_level = array(); $default_zoom_level[0] = 4; $default_zoom_level[1] = 7; $default_zoom_level[2] = 10; $default_zoom_level[3] = 12; foreach ($placelistUniq as $k => $place) { $parent = explode(',', $place['place']); $parent = array_reverse($parent); $parent_id = 0; for ($i = 0; $i < count($parent); $i++) { $escparent = $parent[$i]; if ($escparent == '') { $escparent = 'Unknown'; } $row = Database::prepare("SELECT pl_id, pl_long, pl_lati, pl_zoom, pl_icon FROM `##placelocation` WHERE pl_level=? AND pl_parent_id=? AND pl_place LIKE ? ORDER BY pl_place")->execute(array($i, $parent_id, $escparent))->fetchOneRow(); if (empty($row)) { // this name does not yet exist: create entry if (!Filter::postBool('updateonly')) { $highestIndex = $highestIndex + 1; if ($i + 1 == count($parent)) { $zoomlevel = $place['zoom']; } elseif (isset($default_zoom_level[$i])) { $zoomlevel = $default_zoom_level[$i]; } else { $zoomlevel = $this->getSetting('GM_MAX_ZOOM'); } if ($place['lati'] == '0' || $place['long'] == '0' || $i + 1 < count($parent)) { Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $zoomlevel, $place['icon'])); } else { //delete leading zero $pl_lati = str_replace(array('N', 'S', ','), array('', '-', '.'), $place['lati']); $pl_long = str_replace(array('E', 'W', ','), array('', '-', '.'), $place['long']); if ($pl_lati >= 0) { $place['lati'] = 'N' . abs($pl_lati); } elseif ($pl_lati < 0) { $place['lati'] = 'S' . abs($pl_lati); } if ($pl_long >= 0) { $place['long'] = 'E' . abs($pl_long); } elseif ($pl_long < 0) { $place['long'] = 'W' . abs($pl_long); } Database::prepare("INSERT INTO `##placelocation` (pl_id, pl_parent_id, pl_level, pl_place, pl_long, pl_lati, pl_zoom, pl_icon) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")->execute(array($highestIndex, $parent_id, $i, $escparent, $place['long'], $place['lati'], $zoomlevel, $place['icon'])); } $parent_id = $highestIndex; } } else { $parent_id = $row->pl_id; if (Filter::postBool('overwritedata') && $i + 1 == count($parent)) { Database::prepare("UPDATE `##placelocation` SET pl_lati = ?, pl_long = ?, pl_zoom = ?, pl_icon = ? WHERE pl_id = ?")->execute(array($place['lati'], $place['long'], $place['zoom'], $place['icon'], $parent_id)); } else { // Update only if existing data is missing if (!$row->pl_long && !$row->pl_lati) { Database::prepare("UPDATE `##placelocation` SET pl_lati = ?, pl_long = ? WHERE pl_id = ?")->execute(array($place['lati'], $place['long'], $parent_id)); } if (!$row->pl_icon && $place['icon']) { Database::prepare("UPDATE `##placelocation` SET pl_icon = ? WHERE pl_id = ?")->execute(array($place['icon'], $parent_id)); } } } } } $parent = 0; } if ($action == 'DeleteRecord') { $exists = Database::prepare("SELECT 1 FROM `##placelocation` WHERE pl_parent_id=?")->execute(array($deleteRecord))->fetchOne(); if (!$exists) { Database::prepare("DELETE FROM `##placelocation` WHERE pl_id=?")->execute(array($deleteRecord)); } else { echo '<table class="facts_table"><tr><td>', I18N::translate('Location not removed: this location contains sub-locations'), '</td></tr></table>'; } } ?> <script> function updateList(inactive) { window.location.href='<?php if (strstr($_SERVER['REQUEST_URI'], '&inactive', true)) { $uri = strstr($_SERVER['REQUEST_URI'], '&inactive', true); } else { $uri = $_SERVER['REQUEST_URI']; } echo $uri, '&inactive='; ?> '+inactive; } function edit_place_location(placeid) { window.open('module.php?mod=googlemap&mod_action=places_edit&action=update&placeid='+placeid, '_blank', gmap_window_specs); return false; } function add_place_location(placeid) { window.open('module.php?mod=googlemap&mod_action=places_edit&action=add&placeid='+placeid, '_blank', gmap_window_specs); return false; } function delete_place(placeid) { var answer=confirm('<?php echo I18N::translate('Remove this location?'); ?> '); if (answer == true) { window.location = '<?php echo Functions::getQueryUrl(array('action' => 'DeleteRecord')); ?> &action=DeleteRecord&deleteRecord=' + placeid; } } </script> <p id="gm_breadcrumb"> <?php $where_am_i = $this->placeIdToHierarchy($parent); foreach (array_reverse($where_am_i, true) as $id => $place) { if ($id == $parent) { if ($place != 'Unknown') { echo Filter::escapeHtml($place); } else { echo I18N::translate('unknown'); } } else { echo '<a href="module.php?mod=googlemap&mod_action=admin_places&parent=', $id, '&inactive=', $inactive, '">'; if ($place != 'Unknown') { echo Filter::escapeHtml($place), '</a>'; } else { echo I18N::translate('unknown'), '</a>'; } } echo ' - '; } ?> <a href="module.php?mod=googlemap&mod_action=admin_places&parent=0&inactive=', $inactive, '"><?php echo I18N::translate('Top level'); ?> </a> </p> <form class="form-inline" name="active" method="post" action="module.php?mod=googlemap&mod_action=admin_places&parent=', $parent, '&inactive=', $inactive, '"> <div class="checkbox"> <label for="inactive"> <?php echo FunctionsEdit::checkbox('inactive', $inactive, 'onclick="updateList(this.checked)"'); ?> <?php echo I18N::translate('Show inactive places'); ?> </label> </div> <p class="small text-muted"> <?php echo I18N::translate('By default, the list shows only those places which can be found in your family trees. You may have details for other places, such as those imported in bulk from an external file. Selecting this option will show all places, including ones that are not currently used.'); ?> <?php echo I18N::translate('If you have a large number of inactive places, it can be slow to generate the list.'); ?> </p> </form> <?php $placelist = $this->getPlaceListLocation($parent, $inactive); echo '<div class="gm_plac_edit">'; echo '<table class="table table-bordered table-condensed table-hover"><tr>'; echo '<th>', GedcomTag::getLabel('PLAC'), '</th>'; echo '<th>', GedcomTag::getLabel('LATI'), '</th>'; echo '<th>', GedcomTag::getLabel('LONG'), '</th>'; echo '<th>', I18N::translate('Zoom level'), '</th>'; echo '<th>', I18N::translate('Icon'), '</th>'; echo '<th>'; echo I18N::translate('Edit'), '</th><th>', I18N::translate('Delete'), '</th></tr>'; if (count($placelist) == 0) { echo '<tr><td colspan="7">', I18N::translate('No places found'), '</td></tr>'; } foreach ($placelist as $place) { echo '<tr><td><a href="module.php?mod=googlemap&mod_action=admin_places&parent=', $place['place_id'], '&inactive=', $inactive, '">'; if ($place['place'] != 'Unknown') { echo Filter::escapeHtml($place['place']), '</a></td>'; } else { echo I18N::translate('unknown'), '</a></td>'; } echo '<td>', $place['lati'], '</td>'; echo '<td>', $place['long'], '</td>'; echo '<td>', $place['zoom'], '</td>'; echo '<td>'; if ($place['icon']) { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/', $place['icon'], '" width="25" height="15">'; } else { if ($place['lati'] || $place['long']) { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/mm_20_red.png">'; } else { echo '<img src="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/images/mm_20_yellow.png">'; } } echo '</td>'; echo '<td class="narrow"><a href="#" onclick="edit_place_location(', $place['place_id'], ');return false;" class="icon-edit" title="', I18N::translate('Edit'), '"></a></td>'; $noRows = Database::prepare("SELECT COUNT(pl_id) FROM `##placelocation` WHERE pl_parent_id=?")->execute(array($place['place_id']))->fetchOne(); if ($noRows == 0) { ?> <td><a href="#" onclick="delete_place(<?php echo $place['place_id']; ?> );return false;" class="icon-delete" title="<?php echo I18N::translate('Remove'); ?> "></a></td> <?php } else { ?> <td><i class="icon-delete-grey"></i></td> <?php } ?> </tr> <?php } ?> </table> </div> <hr> <form class="form-horizontal" action="?" onsubmit="add_place_location(this.parent_id.options[this.parent_id.selectedIndex].value); return false;"> <div class="form-group"> <label class="form-control-static col-sm-4" for="parent_id"> <?php echo I18N::translate('Add a new geographic location'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('parent_id', $where_am_i, I18N::translate('Top level'), $parent, 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-plus"></i> <?php echo I18N::translate('Add'); ?> </button> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ImportGedcom"> <div class="form-group"> <label class="form-control-static col-sm-4" for="ged"> <?php echo I18N::translate('Import all places from a family tree'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('ged', Tree::getNameList(), null, $WT_TREE->getName(), 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-upload"></i> <?php echo I18N::translate('Import'); ?> </button> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ImportFile"> <div class="form-group"> <label class="form-control-static col-sm-4"> <?php echo I18N::translate('Upload geographic data'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <button type="submit" class="btn btn-default"> <i class="fa fa-upload"></i> <?php echo I18N::translate('Upload'); ?> </button> </div> </div> </div> </form> <form class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="admin_places"> <input type="hidden" name="action" value="ExportFile"> <div class="form-group"> <label class="form-control-static col-sm-4"> <?php echo I18N::translate('Download geographic data'); ?> </label> <div class="col-sm-8"> <div class="col-sm-6"> <?php echo FunctionsEdit::selectEditControl('parent', $where_am_i, I18N::translate('All'), $WT_TREE->getTreeId(), 'class="form-control"'); ?> </div> <button type="submit" class="btn btn-default"> <i class="fa fa-download"></i> <?php echo I18N::translate('Download'); ?> </button> </div> </div> </form> <?php }
/** * get gedcom tag value * * @param string $tag The tag to find, use : to delineate subtags * @param int $level The gedcom line level of the first tag to find, setting level to 0 will cause it to use 1+ the level of the incoming record * @param string $gedrec The gedcom record to get the value from * * @return string the value of a gedcom tag from the given gedcom record */ private function getGedcomValue($tag, $level, $gedrec) { global $WT_TREE; if (empty($gedrec)) { return ''; } $tags = explode(':', $tag); $origlevel = $level; if ($level == 0) { $level = $gedrec[0] + 1; } $subrec = $gedrec; foreach ($tags as $t) { $lastsubrec = $subrec; $subrec = Functions::getSubRecord($level, "{$level} {$t}", $subrec); if (empty($subrec) && $origlevel == 0) { $level--; $subrec = Functions::getSubRecord($level, "{$level} {$t}", $lastsubrec); } if (empty($subrec)) { if ($t == "TITL") { $subrec = Functions::getSubRecord($level, "{$level} ABBR", $lastsubrec); if (!empty($subrec)) { $t = "ABBR"; } } if (empty($subrec)) { if ($level > 0) { $level--; } $subrec = Functions::getSubRecord($level, "@ {$t}", $gedrec); if (empty($subrec)) { return ''; } } } $level++; } $level--; $ct = preg_match("/{$level} {$t}(.*)/", $subrec, $match); if ($ct == 0) { $ct = preg_match("/{$level} @.+@ (.+)/", $subrec, $match); } if ($ct == 0) { $ct = preg_match("/@ {$t} (.+)/", $subrec, $match); } if ($ct > 0) { $value = trim($match[1]); if ($t == 'NOTE' && preg_match('/^@(.+)@$/', $value, $match)) { $note = Note::getInstance($match[1], $WT_TREE); if ($note) { $value = $note->getNote(); } else { //-- set the value to the id without the @ $value = $match[1]; } } if ($level != 0 || $t != "NOTE") { $value .= Functions::getCont($level + 1, $subrec); } return $value; } return ""; }