. */ /** * Class batch_update_WT_Module */ class batch_update_WT_Module extends Module implements ModuleConfigInterface { /** @var string Form parameter: chosen plugin*/ private $plugin; /** @var string Form parameter: record to update */ private $xref; /** @var string Form parameter: how to update record */ private $action; /** @var string Form parameter: additional details for $action */ private $data; /** @var BatchUpdateBasePlugin[] All available plugins */ private $plugins; /** @var @var BatchUpdateBasePlugin The current plugin */ private $PLUGIN; /** @var string[] n array of all xrefs that might need to be updated */ private $all_xrefs; /** @var string The previous xref to process */ private $prev_xref; /** @var String The current xref being process */ private $curr_xref; /** @var string The next xref to process */ private $next_xref; /** @var GedcomRecord The record corresponding to $curr_xref */ private $record; /** {@inheritdoc} */ public function getTitle() { return /* I18N: Name of a module */ I18N::translate('Batch update'); } /** {@inheritdoc} */ public function getDescription() { return /* I18N: Description of the “Batch update” module */ I18N::translate('Apply automatic corrections to your genealogy data.'); } /** {@inheritdoc} */ public function modAction($mod_action) { switch ($mod_action) { case 'admin_batch_update': $controller = new PageController; $controller ->setPageTitle(I18N::translate('Batch update')) ->restrictAccess(Auth::isAdmin()) ->pageHeader(); echo $this->main(); break; default: http_response_code(404); break; } } /** * Main entry point * * @return string */ function main() { $this->plugins = $this->getPluginList(); // List of available plugins $this->plugin = Filter::get('plugin'); // User parameters $this->xref = Filter::get('xref', WT_REGEX_XREF); $this->action = Filter::get('action'); $this->data = Filter::get('data'); // Don't do any processing until a plugin is chosen. if ($this->plugin && array_key_exists($this->plugin, $this->plugins)) { $this->PLUGIN = new $this->plugin; $this->PLUGIN->getOptions(); $this->getAllXrefs(); switch ($this->action) { case 'update': $record = self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]); if ($this->PLUGIN->doesRecordNeedUpdate($this->xref, $record)) { $newrecord = $this->PLUGIN->updateRecord($this->xref, $record); if ($newrecord != $record) { if ($newrecord) { GedcomRecord::getInstance($this->xref)->updateRecord($newrecord, $this->PLUGIN->chan); } else { GedcomRecord::getInstance($this->xref)->deleteRecord(); } } } $this->xref = $this->findNextXref($this->xref); break; case 'update_all': foreach ($this->all_xrefs as $xref=>$type) { $record = self::getLatestRecord($xref, $type); if ($this->PLUGIN->doesRecordNeedUpdate($xref, $record)) { $newrecord = $this->PLUGIN->updateRecord($xref, $record); if ($newrecord != $record) { if ($newrecord) { GedcomRecord::getInstance($this->xref)->updateRecord($newrecord, $this->PLUGIN->chan); } else { GedcomRecord::getInstance($this->xref)->deleteRecord(); } } } } $this->xref = ''; return ''; } // Make sure that our requested record really does need updating. // It may have been updated in another session, or may not have // been specified at all. if (array_key_exists($this->xref, $this->all_xrefs) && $this->PLUGIN->doesRecordNeedUpdate($this->xref, self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]))) { $this->curr_xref = $this->xref; } // The requested record doesn't need updating - find one that does if (!$this->curr_xref) { $this->curr_xref = $this->findNextXref($this->xref); } if (!$this->curr_xref) { $this->curr_xref = $this->findPrevXref($this->xref); } // If we've found a record to update, get details and look for the next/prev if ($this->curr_xref) { $this->record = self::getLatestRecord($this->curr_xref, $this->all_xrefs[$this->curr_xref]); $this->prev_xref = $this->findPrevXref($this->curr_xref); $this->next_xref = $this->findNextXref($this->curr_xref); } } // HTML common to all pages $html = $this->getJavascript() . '
' . '' . '' . '' . '' . // will be set by javascript for next update '' . // will be set by javascript for next update '' . '' . ''; if (!Auth::user()->getPreference('auto_accept')) { $html .= ''; } // If a plugin is selected, display the details if ($this->PLUGIN) { $html .= $this->PLUGIN->getOptionsForm(); if (substr($this->action, -4) == '_all') { // Reset - otherwise we might "undo all changes", which refreshes the // page, which makes them all again! $html .= ''; } else { if ($this->curr_xref) { // Create an object, so we can get the latest version of the name. $this->record = GedcomRecord::getInstance($this->curr_xref); $html .= '
' . I18N::translate('Family tree') . '' . select_edit_control('ged', Tree::getNameList(), '', WT_GEDCOM, 'onchange="reset_reload();"') . '
' . I18N::translate('Batch update') . ''; if ($this->PLUGIN) { $html .= '
' . $this->PLUGIN->getDescription() . ''; } $html .= '
' . I18N::translate('Your user account does not have “automatically approve changes” enabled. You will only be able to change one record at a time.') . '
' . ''; } else { $html .= ''; } } } $html .= '
' . self::createSubmitButton(I18N::translate('previous'), $this->prev_xref) . self::createSubmitButton(I18N::translate('next'), $this->next_xref) . '' . $this->record->getFullName() . '' . '
' . '
' . implode('
', $this->PLUGIN->getActionButtons($this->curr_xref, $this->record)) . '
' . '
' . $this->PLUGIN->getActionPreview($this->record) . '
' . I18N::translate('Nothing found.') . '
'; return $html; } /** * Find the next record that needs to be updated. * * @param string $xref * * @return string|null */ private function findNextXref($xref) { foreach (array_keys($this->all_xrefs) as $key) { if ($key > $xref) { $record = self::getLatestRecord($key, $this->all_xrefs[$key]); if ($this->PLUGIN->doesRecordNeedUpdate($key, $record)) { return $key; } } } return null; } /** * Find the previous record that needs to be updated. * * @param string $xref * * @return string|null */ private function findPrevXref($xref) { foreach (array_reverse(array_keys($this->all_xrefs)) as $key) { if ($key < $xref) { $record = self::getLatestRecord($key, $this->all_xrefs[$key]); if ($this->PLUGIN->doesRecordNeedUpdate($key, $record)) { return $key; } } } return null; } /** * Generate a list of all XREFs. */ private function getAllXrefs() { $sql = array(); $vars = array(); foreach ($this->PLUGIN->getRecordTypesToUpdate() as $type) { switch ($type) { case 'INDI': $sql[] = "SELECT i_id, 'INDI' FROM `##individuals` WHERE i_file=?"; $vars[] = WT_GED_ID; break; case 'FAM': $sql[] = "SELECT f_id, 'FAM' FROM `##families` WHERE f_file=?"; $vars[] = WT_GED_ID; break; case 'SOUR': $sql[] = "SELECT s_id, 'SOUR' FROM `##sources` WHERE s_file=?"; $vars[] = WT_GED_ID; break; case 'OBJE': $sql[] = "SELECT m_id, 'OBJE' FROM `##media` WHERE m_file=?"; $vars[] = WT_GED_ID; break; default: $sql[] = "SELECT o_id, ? FROM `##other` WHERE o_type=? AND o_file=?"; $vars[] = $type; $vars[] = $type; $vars[] = WT_GED_ID; break; } } $this->all_xrefs = Database::prepare(implode(' UNION ', $sql) . ' ORDER BY 1 ASC') ->execute($vars) ->fetchAssoc(); } /** * Scan the plugin folder for a list of plugins * * @return BatchUpdateBasePlugin[] */ private function getPluginList() { $plugins = array(); $dir_handle = opendir(__DIR__); while ($file = readdir($dir_handle)) { if (substr($file, -10) == 'Plugin.php' && $file !== 'BatchUpdateBasePlugin.php') { $class = __NAMESPACE__ . '\\' . basename($file, '.php'); $plugins[$class] = new $class; } } closedir($dir_handle); return $plugins; } /** * Javascript that gets included on every page * * @return string */ private function getJavascript() { return ''; } /** * Create a submit button for our form * * @param string $text * @param string $xref * @param string $action * @param string $data * * @return string */ public static function createSubmitButton($text, $xref, $action = '', $data = '') { return ''; } /** * Get the current view of a record, allowing for pending changes * * @param string $xref * @param string $type * * @return string */ public static function getLatestRecord($xref, $type) { switch ($type) { case 'INDI': return Individual::getInstance($xref)->getGedcom(); case 'FAM': return Family::getInstance($xref)->getGedcom(); case 'SOUR': return Source::getInstance($xref)->getGedcom(); case 'REPO': return Repository::getInstance($xref)->getGedcom(); case 'OBJE': return Media::getInstance($xref)->getGedcom(); case 'NOTE': return Note::getInstance($xref)->getGedcom(); default: return GedcomRecord::getInstance($xref)->getGedcom(); } } /** {@inheritdoc} */ public function getConfigLink() { return 'module.php?mod=' . $this->getName() . '&mod_action=admin_batch_update'; } }