diff options
| author | Greg Roach <fisharebest@gmail.com> | 2015-03-02 08:02:00 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@gmail.com> | 2015-03-02 15:55:40 +0000 |
| commit | 8c2e82270a639a3acf607b432e54721116dae723 (patch) | |
| tree | 6e9829818d82ad365229bbcad744b9b4999bb0fb /app/Module/BatchUpdate | |
| parent | 7126668f8fb92b0cac155adc02efde34bbd890ce (diff) | |
| download | webtrees-8c2e82270a639a3acf607b432e54721116dae723.tar.gz webtrees-8c2e82270a639a3acf607b432e54721116dae723.tar.bz2 webtrees-8c2e82270a639a3acf607b432e54721116dae723.zip | |
Module API
Diffstat (limited to 'app/Module/BatchUpdate')
7 files changed, 771 insertions, 0 deletions
diff --git a/app/Module/BatchUpdate/BatchUpdateBasePlugin.php b/app/Module/BatchUpdate/BatchUpdateBasePlugin.php new file mode 100644 index 0000000000..3d9d034920 --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateBasePlugin.php @@ -0,0 +1,190 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateBasePlugin + * + * Each plugin should extend this class, and implement these two functions: + * + * bool doesRecordNeedUpdate($xref, $gedrec) + * string updateRecord($xref, $gedrec) + */ +class BatchUpdateBasePlugin { + public $chan = false; // User option; update change record + + /** + * Default is to operate on INDI records + * + * @return string[] + */ + function getRecordTypesToUpdate() { + return array('INDI'); + } + + /** + * Default option is just the "don't update CHAN record" + */ + function getOptions() { + $this->chan = Filter::getBool('chan'); + } + + /** + * Default option is just the "don't update CHAN record" + * + * @return string + */ + function getOptionsForm() { + return + '<tr><th>' . I18N::translate('Do not update the “last change” record') . '</th>' . + '<td><select name="chan" onchange="this.form.submit();">' . + '<option value="0" ' . ($this->chan ? '' : 'selected') . '>' . I18N::translate('yes') . '</option>' . + '<option value="1" ' . ($this->chan ? 'selected' : '') . '>' . I18N::translate('no') . '</option>' . + '</select></td></tr>'; + } + + /** + * Default buttons are update and update_all + * + * @param string $xref + * + * @return string[] + */ + function getActionButtons($xref) { + if (Auth::user()->getPreference('auto_accept')) { + return array( + BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'), + BatchUpdateModule::createSubmitButton(I18N::translate('Update all'), $xref, 'update_all') + ); + } else { + return array( + BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update') + ); + } + } + + /** + * Default previewer for plugins with no custom preview. + * + * @param GedcomRecord $record + * + * @return string + */ + function getActionPreview(GedcomRecord $record) { + $old_lines = preg_split('/[\n]+/', $record->getGedcom()); + $new_lines = preg_split('/[\n]+/', $this->updateRecord($record->getXref(), $record->getGedcom())); + // Find matching lines using longest-common-subsequence algorithm. + $lcs = self::LongestCommonSubsequence($old_lines, $new_lines, 0, count($old_lines) - 1, 0, count($new_lines) - 1); + + $diff_lines = array(); + $last_old = -1; + $last_new = -1; + while ($lcs) { + list($old, $new) = array_shift($lcs); + while ($last_old < $old - 1) { + $diff_lines[] = self::decorateDeletedText($old_lines[++$last_old]); + } + while ($last_new < $new - 1) { + $diff_lines[] = self::decorateInsertedText($new_lines[++$last_new]); + } + $diff_lines[] = $new_lines[$new]; + $last_old = $old; + $last_new = $new; + } + while ($last_old < count($old_lines) - 1) { + $diff_lines[] = self::decorateDeletedText($old_lines[++$last_old]); + } + while ($last_new < count($new_lines) - 1) { + $diff_lines[] = self::decorateInsertedText($new_lines[++$last_new]); + } + + return '<pre>' . self::createEditLinks(implode("\n", $diff_lines)) . '</pre>'; + } + + /** + * Longest Common Subsequence. + * + * @param string[] $X + * @param string[] $Y + * @param integer $x1 + * @param integer $x2 + * @param integer $y1 + * @param integer $y2 + * + * @return array + */ + private static function LongestCommonSubsequence($X, $Y, $x1, $x2, $y1, $y2) { + if ($x2 - $x1 >= 0 && $y2 - $y1 >= 0) { + if ($X[$x1] == $Y[$y1]) { + // Match at start of sequence + $tmp = self::LongestCommonSubsequence($X, $Y, $x1 + 1, $x2, $y1 + 1, $y2); + array_unshift($tmp, array($x1, $y1)); + return $tmp; + } elseif ($X[$x2] == $Y[$y2]) { + // Match at end of sequence + $tmp = self::LongestCommonSubsequence($X, $Y, $x1, $x2 - 1, $y1, $y2 - 1); + array_push($tmp, array($x2, $y2)); + return $tmp; + } else { + // No match. Look for subsequences + $tmp1 = self::LongestCommonSubsequence($X, $Y, $x1, $x2, $y1, $y2 - 1); + $tmp2 = self::LongestCommonSubsequence($X, $Y, $x1, $x2 - 1, $y1, $y2); + return count($tmp1) > count($tmp2) ? $tmp1 : $tmp2; + } + } else { + // One array is empty - end recursion + return array(); + } + } + + /** + * Decorate inserted text + * + * @param string $text + * + * @return string + */ + static function decorateInsertedText($text) { + return '<span class="added_text">' . $text . '</span>'; + } + + /** + * Decorate deleted text + * + * @param string $text + * + * @return string + */ + static function decorateDeletedText($text) { + return '<span class="deleted_text">' . $text . '</span>'; + } + + /** + * Converted gedcom links into editable links + * + * @param string $gedrec + * + * @return string + */ + static function createEditLinks($gedrec) { + return preg_replace( + "/@([^#@\n]+)@/m", + '<a href="#" onclick="return edit_raw(\'\\1\');">@\\1@</a>', + $gedrec + ); + } +} diff --git a/app/Module/BatchUpdate/BatchUpdateDuplicateLinksPlugin.php b/app/Module/BatchUpdate/BatchUpdateDuplicateLinksPlugin.php new file mode 100644 index 0000000000..16a7542c8d --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateDuplicateLinksPlugin.php @@ -0,0 +1,84 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateDuplicateLinksPlugin Batch Update plugin: remove duplicate links in records + */ +class BatchUpdateDuplicateLinksPlugin extends BatchUpdateBasePlugin { + /** + * User-friendly name for this plugin. + * + * @return string + */ + public function getName() { + return I18N::translate('Remove duplicate links'); + } + + /** + * Description / help-text for this plugin. + * + * @return string + */ + public function getDescription() { + return I18N::translate('A common error is to have multiple links to the same record, for example listing the same child more than once in a family record.'); + } + + /** + * This plugin will update all types of record. + * + * @return string[] + */ + public function getRecordTypesToUpdate() { + return array('INDI', 'FAM', 'SOUR', 'REPO', 'NOTE', 'OBJE'); + } + + /** + * Does this record need updating? + * + * @param string $xref + * @param string $gedrec + * + * @return boolean + */ + public function doesRecordNeedUpdate($xref, $gedrec) { + return + preg_match('/(\n1.*@.+@.*(?:(?:\n[2-9].*)*))(?:\n1.*(?:\n[2-9].*)*)*\1/', $gedrec) || + preg_match('/(\n2.*@.+@.*(?:(?:\n[3-9].*)*))(?:\n2.*(?:\n[3-9].*)*)*\1/', $gedrec) || + preg_match('/(\n3.*@.+@.*(?:(?:\n[4-9].*)*))(?:\n3.*(?:\n[4-9].*)*)*\1/', $gedrec); + } + + /** + * Apply any updates to this record + * + * @param string $xref + * @param string $gedrec + * + * @return string + */ + public function updateRecord($xref, $gedrec) { + return preg_replace( + array( + '/(\n1.*@.+@.*(?:(?:\n[2-9].*)*))((?:\n1.*(?:\n[2-9].*)*)*\1)/', + '/(\n2.*@.+@.*(?:(?:\n[3-9].*)*))((?:\n2.*(?:\n[3-9].*)*)*\1)/', + '/(\n3.*@.+@.*(?:(?:\n[4-9].*)*))((?:\n3.*(?:\n[4-9].*)*)*\1)/' + ), + '$2', + $gedrec + ); + } +} diff --git a/app/Module/BatchUpdate/BatchUpdateMarriedNamesPlugin.php b/app/Module/BatchUpdate/BatchUpdateMarriedNamesPlugin.php new file mode 100644 index 0000000000..371a11705f --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateMarriedNamesPlugin.php @@ -0,0 +1,152 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateMarriedNamesPlugin Batch Update plugin: add missing 2 _MARNM records + */ +class BatchUpdateMarriedNamesPlugin extends BatchUpdateBasePlugin { + /** @var string User option: add or replace husband’s surname */ + private $surname; + + /** + * User-friendly name for this plugin. + * + * @return string + */ + public function getName() { + return I18N::translate('Add missing married names'); + } + + /** + * Description / help-text for this plugin. + * + * @return string + */ + public function getDescription() { + return I18N::translate('You can make it easier to search for married women by recording their married name.<br>However not all women take their husband’s surname, so beware of introducing incorrect information into your database.'); + } + + /** + * Does this record need updating? + * + * @param string $xref + * @param string $gedrec + * + * @return boolean + */ + public function doesRecordNeedUpdate($xref, $gedrec) { + return preg_match('/^1 SEX F/m', $gedrec) && preg_match('/^1 NAME /m', $gedrec) && self::surnamesToAdd($xref, $gedrec); + } + + /** + * Apply any updates to this record + * + * @param string $xref + * @param string $gedrec + * + * @return string + */ + public function updateRecord($xref, $gedrec) { + global $WT_TREE; + + $SURNAME_TRADITION = $WT_TREE->getPreference('SURNAME_TRADITION'); + + preg_match('/^1 NAME (.*)/m', $gedrec, $match); + $wife_name = $match[1]; + $married_names = array(); + foreach (self::surnamesToAdd($xref, $gedrec) as $surname) { + switch ($this->surname) { + case 'add': + $married_names[] = "\n2 _MARNM " . str_replace('/', '', $wife_name) . ' /' . $surname . '/'; + break; + case 'replace': + if ($SURNAME_TRADITION === 'polish') { + $surname = preg_replace(array('/ski$/', '/cki$/', '/dzki$/'), array('ska', 'cka', 'dzka'), $surname); + } + $married_names[] = "\n2 _MARNM " . preg_replace('!/.*/!', '/' . $surname . '/', $wife_name); + break; + } + } + return preg_replace('/(^1 NAME .*([\r\n]+[2-9].*)*)/m', '\\1' . implode('', $married_names), $gedrec, 1); + } + + /** + * @param string $xref + * @param string $gedrec + * + * @return string[] + */ + private function surnamesToAdd($xref, $gedrec) { + $wife_surnames = self::surnames($xref, $gedrec); + $husb_surnames = array(); + $missing_surnames = array(); + preg_match_all('/^1 FAMS @(.+)@/m', $gedrec, $fmatch); + foreach ($fmatch[1] as $famid) { + $famrec = BatchUpdateModule::getLatestRecord($famid, 'FAM'); + if (preg_match('/^1 MARR/m', $famrec) && preg_match('/^1 HUSB @(.+)@/m', $famrec, $hmatch)) { + $husbrec = BatchUpdateModule::getLatestRecord($hmatch[1], 'INDI'); + $husb_surnames = array_unique(array_merge($husb_surnames, self::surnames($hmatch[1], $husbrec))); + } + } + foreach ($husb_surnames as $husb_surname) { + if (!in_array($husb_surname, $wife_surnames)) { + $missing_surnames[] = $husb_surname; + } + } + + return $missing_surnames; + } + + /** + * @param string $xref + * @param string $gedrec + * + * @return string[] + */ + private function surnames($xref, $gedrec) { + if (preg_match_all('/^(?:1 NAME|2 _MARNM) .*\/(.+)\//m', $gedrec, $match)) { + return $match[1]; + } else { + return array(); + } + } + + /** + * Process the user-supplied options. + */ + public function getOptions() { + parent::getOptions(); + $this->surname = Filter::get('surname', 'add|replace', 'replace'); + } + + /** + * Generate a form to ask the user for options. + * + * @return string + */ + public function getOptionsForm() { + return + parent::getOptionsForm() . + '<tr valign="top"><th>' . I18N::translate('Surname option') . '</th>' . + '<td class="optionbox"><select name="surname" onchange="reset_reload();"><option value="replace" ' . + ($this->surname == 'replace' ? 'selected' : '') . + '">' . I18N::translate('Wife’s surname replaced by husband’s surname') . '</option><option value="add" ' . + ($this->surname == 'add' ? 'selected' : '') . + '">' . I18N::translate('Wife’s maiden surname becomes new given name') . '</option></select></td></tr>'; + } +} diff --git a/app/Module/BatchUpdate/BatchUpdateMissingDeathPlugin.php b/app/Module/BatchUpdate/BatchUpdateMissingDeathPlugin.php new file mode 100644 index 0000000000..50ff0a56f4 --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateMissingDeathPlugin.php @@ -0,0 +1,64 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateMissingDeathPlugin Batch Update plugin: add missing 1 BIRT/DEAT Y + */ +class BatchUpdateMissingDeathPlugin extends BatchUpdateBasePlugin { + /** + * User-friendly name for this plugin. + * + * @return string + */ + public function getName() { + return I18N::translate('Add missing death records'); + } + + /** + * Description / help-text for this plugin. + * + * @return string + */ + public function getDescription() { + return I18N::translate('You can speed up the privacy calculations by adding a death record to individuals whose death can be inferred from other dates, but who do not have a record of death, burial, cremation, etc.'); + } + + /** + * Does this record need updating? + * + * @param string $xref + * @param string $gedrec + * + * @return boolean + */ + public function doesRecordNeedUpdate($xref, $gedrec) { + return !preg_match('/\n1 (' . WT_EVENTS_DEAT . ')/', $gedrec) && Individual::getInstance($xref)->isDead(); + } + + /** + * Apply any updates to this record + * + * @param string $xref + * @param string $gedrec + * + * @return string + */ + public function updateRecord($xref, $gedrec) { + return $gedrec . "\n1 DEAT Y"; + } +} diff --git a/app/Module/BatchUpdate/BatchUpdateNameFormatPlugin.php b/app/Module/BatchUpdate/BatchUpdateNameFormatPlugin.php new file mode 100644 index 0000000000..c3728070d0 --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateNameFormatPlugin.php @@ -0,0 +1,76 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateNameFormatPlugin Batch Update plugin: fix spacing in names, particularly that before/after the surname slashes + */ +class BatchUpdateNameFormatPlugin extends BatchUpdateBasePlugin { + /** + * User-friendly name for this plugin. + * + * @return string + */ + public function getName() { + return I18N::translate('Fix name slashes and spaces'); + } + + /** + * Description / help-text for this plugin. + * + * @return string + */ + public function getDescription() { + return I18N::translate('Correct NAME records of the form “John/DOE/” or “John /DOE”, as produced by older genealogy programs.'); + } + + /** + * Does this record need updating? + * + * @param string $xref + * @param string $gedrec + * + * @return boolean + */ + public function doesRecordNeedUpdate($xref, $gedrec) { + return + preg_match('/^(?:1 NAME|2 (?:FONE|ROMN|_MARNM|_AKA|_HEB)) [^\/\n]*\/[^\/\n]*$/m', $gedrec) || + preg_match('/^(?:1 NAME|2 (?:FONE|ROMN|_MARNM|_AKA|_HEB)) [^\/\n]*[^\/ ]\//m', $gedrec); + } + + /** + * Apply any updates to this record + * + * @param string $xref + * @param string $gedrec + * + * @return string + */ + public function updateRecord($xref, $gedrec) { + return preg_replace( + array( + '/^((?:1 NAME|2 (?:FONE|ROMN|_MARNM|_AKA|_HEB)) [^\/\n]*\/[^\/\n]*)$/m', + '/^((?:1 NAME|2 (?:FONE|ROMN|_MARNM|_AKA|_HEB)) [^\/\n]*[^\/ ])(\/)/m', + ), + array( + '$1/', + '$1 $2', + ), + $gedrec + ); + } +} diff --git a/app/Module/BatchUpdate/BatchUpdateSearchReplacePlugin.php b/app/Module/BatchUpdate/BatchUpdateSearchReplacePlugin.php new file mode 100644 index 0000000000..2489d1b132 --- /dev/null +++ b/app/Module/BatchUpdate/BatchUpdateSearchReplacePlugin.php @@ -0,0 +1,153 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BatchUpdateSearchReplacePlugin Batch Update plugin: search/replace + */ +class BatchUpdateSearchReplacePlugin extends BatchUpdateBasePlugin { + var $search = null; // Search string + var $replace = null; // Replace string + var $method = null; // simple/wildcards/regex + var $regex = null; // Search string, converted to a regex + var $case = null; // "i" for case insensitive, "" for case sensitive + var $error = null; // Message for bad user parameters + + /** + * User-friendly name for this plugin. + * + * @return string + */ + public function getName() { + return I18N::translate('Search and replace'); + } + + /** + * Description / help-text for this plugin. + * + * @return string + */ + public function getDescription() { + return /* I18N: Description of the “Search and replace” option of the batch update module */ I18N::translate('Search and replace text, using simple searches or advanced pattern matching.'); + } + + /** + * This plugin will update all types of record. + * + * @return string[] + */ + public function getRecordTypesToUpdate() { + return array('INDI', 'FAM', 'SOUR', 'REPO', 'NOTE', 'OBJE'); + } + + /** + * Does this record need updating? + * + * @param string $xref + * @param string $gedrec + * + * @return boolean + */ + public function doesRecordNeedUpdate($xref, $gedrec) { + return !$this->error && preg_match('/(?:' . $this->regex . ')/mu' . $this->case, $gedrec); + } + + /** + * Apply any updates to this record + * + * @param string $xref + * @param string $gedrec + * + * @return string + */ + public function updateRecord($xref, $gedrec) { + // Allow "\n" to indicate a line-feed in replacement text. + // Back-references such as $1, $2 are handled automatically. + return preg_replace('/' . $this->regex . '/mu' . $this->case, str_replace('\n', "\n", $this->replace), $gedrec); + } + + /** + * Process the user-supplied options. + */ + public function getOptions() { + parent::getOptions(); + $this->search = Filter::get('search'); + $this->replace = Filter::get('replace'); + $this->method = Filter::get('method', 'exact|words|wildcards|regex', 'exact'); + $this->case = Filter::get('case', 'i'); + + $this->error = ''; + switch ($this->method) { + case 'exact': + $this->regex = preg_quote($this->search, '/'); + break; + case 'words': + $this->regex = '\b' . preg_quote($this->search, '/') . '\b'; + break; + case 'wildcards': + $this->regex = '\b' . str_replace(array('\*', '\?'), array('.*', '.'), preg_quote($this->search, '/')) . '\b'; + break; + case 'regex': + $this->regex = $this->search; + // Check for invalid regular expressions. + // A valid regex on a null string returns zero. + // An invalid regex on a null string returns false and throws a warning. + try { + preg_match('/' . $this->search . '/', null); + } catch (\ErrorException $ex) { + $this->error = '<div class="alert alert-danger">' . I18N::translate('The regex appears to contain an error. It can’t be used.') . '</div>'; + } + break; + } + } + + /** + * Generate a form to ask the user for options. + * + * @return string + */ + public function getOptionsForm() { + $descriptions = array( + 'exact' => I18N::translate('Match the exact text, even if it occurs in the middle of a word.'), + 'words' => I18N::translate('Match the exact text, unless it occurs in the middle of a word.'), + 'wildcards' => I18N::translate('Use a “?” to match a single character, use “*” to match zero or more characters.'), + 'regex' => /* I18N: http://en.wikipedia.org/wiki/Regular_expression */ I18N::translate('Regular expressions are an advanced pattern matching technique.') . '<br>' . /* I18N: %s is a URL */ I18N::translate('See %s for more information.', '<a href="http://php.net/manual/regexp.reference.php" target="_blank">php.net/manual/regexp.reference.php</a>'), + ); + + return + '<tr><th>' . I18N::translate('Search text/pattern') . '</th>' . + '<td>' . + '<input name="search" size="40" value="' . Filter::escapeHtml($this->search) . + '" onchange="this.form.submit();"></td></tr>' . + '<tr><th>' . I18N::translate('Replacement text') . '</th>' . + '<td>' . + '<input name="replace" size="40" value="' . Filter::escapeHtml($this->replace) . + '" onchange="this.form.submit();"></td></tr>' . + '<tr><th>' . I18N::translate('Search method') . '</th>' . + '<td><select name="method" onchange="this.form.submit();">' . + '<option value="exact" ' . ($this->method == 'exact' ? 'selected' : '') . '>' . I18N::translate('Exact text') . '</option>' . + '<option value="words" ' . ($this->method == 'words' ? 'selected' : '') . '>' . I18N::translate('Whole words only') . '</option>' . + '<option value="wildcards" ' . ($this->method == 'wildcards' ? 'selected' : '') . '>' . I18N::translate('Wildcards') . '</option>' . + '<option value="regex" ' . ($this->method == 'regex' ? 'selected' : '') . '>' . I18N::translate('Regular expression') . '</option>' . + '</select><br><em>' . $descriptions[$this->method] . '</em>' . $this->error . '</td></tr>' . + '<tr><th>' . I18N::translate('Case insensitive') . '</th>' . + '<td>' . + '<input type="checkbox" name="case" value="i" ' . ($this->case == 'i' ? 'checked' : '') . '" onchange="this.form.submit();">' . + '<br><em>' . I18N::translate('Tick this box to match both upper and lower case letters.') . '</em></td></tr>' . + parent::getOptionsForm(); + } +} diff --git a/app/Module/BatchUpdate/BirthDeathMarriageReportModule.php b/app/Module/BatchUpdate/BirthDeathMarriageReportModule.php new file mode 100644 index 0000000000..4364a60a01 --- /dev/null +++ b/app/Module/BatchUpdate/BirthDeathMarriageReportModule.php @@ -0,0 +1,52 @@ +<?php +namespace Fisharebest\Webtrees; + +/** + * webtrees: online genealogy + * Copyright (C) 2015 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class BirthDeathMarriageReportModule + */ +class BirthDeathMarriageReportModule extends Module implements ModuleReportInterface { + /** {@inheritdoc} */ + public function getTitle() { + // This text also appears in the .XML file - update both together + return /* I18N: Name of a module/report. “Vital records” are life events - birth/marriage/death */ I18N::translate('Vital records'); + } + + /** {@inheritdoc} */ + public function getDescription() { + // This text also appears in the .XML file - update both together + return /* I18N: Description of the “Vital records” module. “Vital records” are life events - birth/marriage/death */ I18N::translate('A report of vital records for a given date or place.'); + } + + /** {@inheritdoc} */ + public function defaultAccessLevel() { + return WT_PRIV_PUBLIC; + } + + /** {@inheritdoc} */ + public function getReportMenus() { + $menus = array(); + $menu = new Menu( + $this->getTitle(), + 'reportengine.php?ged=' . WT_GEDURL . '&action=setup&report=' . WT_MODULES_DIR . $this->getName() . '/report.xml', + 'menu-report-' . $this->getName() + ); + $menus[] = $menu; + + return $menus; + } +} |
