require './includes/session.php'; // Don't use ged=XX as we want to be able to run without changing the current gedcom. // This will let us load several gedcoms together, or to edit one while loading another. $gedcom_id = Filter::getInteger('gedcom_id'); $tree = Tree::findById($gedcom_id); if (!$tree || !Auth::isManager($tree, Auth::user())) { http_response_code(403); return; } $controller = new AjaxController(); $controller->pageHeader(); // Don't allow the user to cancel the request. We do not want to be left // with an incomplete transaction. ignore_user_abort(true); // Run in a transaction Database::beginTransaction(); // Only allow one process to import each gedcom at a time Database::prepare("SELECT * FROM `##gedcom_chunk` WHERE gedcom_id=? FOR UPDATE")->execute(array($gedcom_id)); // What is the current import status? $row = Database::prepare("SELECT" . " SUM(IF(imported, LENGTH(chunk_data), 0)) AS import_offset," . " SUM(LENGTH(chunk_data)) AS import_total" . " FROM `##gedcom_chunk` WHERE gedcom_id=?")->execute(array($gedcom_id))->fetchOneRow(); if ($row->import_offset == $row->import_total) { Tree::findById($gedcom_id)->setPreference('imported', '1'); // Finished? Show the maintenance links, similar to admin_trees_manage.php Database::commit(); $controller->addInlineJavascript('jQuery("#import' . $gedcom_id . '").addClass("hidden");' . 'jQuery("#actions' . $gedcom_id . '").removeClass("hidden");'); return; } // Calculate progress so far $progress = $row->import_offset / $row->import_total; ?> <div class="progress" id="progress<?php
/** * {inhericDoc} * @see \MyArtJaub\Webtrees\Module\AdminTasks\Model\TaskProviderInterface::deleteTask() */ public function deleteTask($task_name) { try { Database::beginTransaction(); Database::prepare('DELETE FROM `##maj_admintasks` WHERE majat_name= :task_name')->execute(array('task_name' => $task_name)); Database::prepare('DELETE FROM `##gedcom_setting` WHERE setting_name LIKE :setting_name')->execute(array('setting_name' => 'MAJ_AT_' . $task_name . '%')); Database::commit(); Log::addConfigurationLog('Admin Task ' . $task_name . ' has been deleted from disk - deleting it from DB'); return true; } catch (\Exception $ex) { Database::rollback(); Log::addErrorLog('An error occurred while deleting Admin Task ' . $task_name . '. Exception: ' . $ex->getMessage()); return false; } }
/** * Import data from a gedcom file into this tree. * * @param string $path The full path to the (possibly temporary) file. * @param string $filename The preferred filename, for export/download. * * @throws \Exception */ public function importGedcomFile($path, $filename) { // Read the file in blocks of roughly 64K. Ensure that each block // contains complete gedcom records. This will ensure we don’t split // multi-byte characters, as well as simplifying the code to import // each block. $file_data = ''; $fp = fopen($path, 'rb'); // Don’t allow the user to cancel the request. We do not want to be left with an incomplete transaction. ignore_user_abort(true); Database::beginTransaction(); $this->deleteGenealogyData($this->getPreference('keep_media')); $this->setPreference('gedcom_filename', $filename); $this->setPreference('imported', '0'); while (!feof($fp)) { $file_data .= fread($fp, 65536); // There is no strrpos() function that searches for substrings :-( for ($pos = strlen($file_data) - 1; $pos > 0; --$pos) { if ($file_data[$pos] === '0' && ($file_data[$pos - 1] === "\n" || $file_data[$pos - 1] === "\r")) { // We’ve found the last record boundary in this chunk of data break; } } if ($pos) { Database::prepare("INSERT INTO `##gedcom_chunk` (gedcom_id, chunk_data) VALUES (?, ?)")->execute(array($this->tree_id, substr($file_data, 0, $pos))); $file_data = substr($file_data, $pos); } } Database::prepare("INSERT INTO `##gedcom_chunk` (gedcom_id, chunk_data) VALUES (?, ?)")->execute(array($this->tree_id, $file_data)); Database::commit(); fclose($fp); }
/** * Update a geodispersion analysis in the database, in transactional manner. * When successful, returns the updated GeoAnalysis object * * @param GeoAnalysis $ga * @return GeoAnalysis */ public function updateGeoAnalysis(GeoAnalysis $ga) { try { Database::beginTransaction(); Database::prepare('UPDATE `##maj_geodispersion`' . ' SET majgd_descr = :description,' . ' majgd_sublevel = :analysis_level,' . ' majgd_map = :map,' . ' majgd_toplevel = :map_top_level,' . ' majgd_useflagsgen = :use_flags,' . ' majgd_detailsgen = :gen_details' . ' WHERE majgd_file = :gedcom_id AND majgd_id = :ga_id')->execute(array('gedcom_id' => $this->tree->getTreeId(), 'ga_id' => $ga->getId(), 'description' => $ga->getTitle(), 'analysis_level' => $ga->getAnalysisLevel(), 'use_flags' => $ga->getOptions() && $ga->getOptions()->isUsingFlags() ? 'yes' : 'no', 'gen_details' => $ga->getOptions() ? $ga->getOptions()->getMaxDetailsInGen() : 0, 'map' => $ga->hasMap() ? $ga->getOptions()->getMap()->getFileName() : null, 'map_top_level' => $ga->hasMap() ? $ga->getOptions()->getMapLevel() : -100)); $ga = $this->getGeoAnalysis($ga->getId(), false); Database::commit(); } catch (\Exception $ex) { Database::rollback(); Log::addErrorLog('The Geo Analysis ID “' . $ga->getId() . '” failed to be updated. Transaction rollbacked. Exception: ' . $ex->getMessage()); $ga = null; } return $ga; }