/** * Populates the cache from current state of the source file. * @param $created \string Unix timestamp when the cache is created (for automatic updates). */ public function create($created = false) { $this->close(); // Close the reader instance just to be sure $messages = $this->group->load($this->code); if (!count($messages) && !$this->group instanceof SingleFileBasedMessageGroup) { if ($this->exists()) { // Delete stale cache files unlink($this->getCacheFileName()); } return; // Don't create empty caches } $hash = md5(file_get_contents($this->group->getSourceFilePath($this->code))); $cache = CdbWriter::open($this->getCacheFileName()); $keys = array_keys($messages); $cache->set('#keys', serialize($keys)); foreach ($messages as $key => $value) { $cache->set($key, $value); } $cache->set('#created', $created ? $created : wfTimestamp()); $cache->set('#updated', wfTimestamp()); $cache->set('#filehash', $hash); $cache->set('#msgcount', count($messages)); ksort($messages); $cache->set('#msghash', md5(serialize($messages))); $cache->set('#version', '3'); $cache->close(); }
/** * Do some conflict resolution for translations. * @param string $code Language code. * @param bool|int $startTs Time of the last export (changes in wiki after * this will conflict) * @param bool|int $endTs Time of the last export (changes in source before * this won't conflict) * @param bool|int $changeTs When change happened in the source. */ public function checkConflicts($code, $startTs = false, $endTs = false, $changeTs = false) { $messages = $this->group->load($code); if (!count($messages)) { return; } $collection = $this->group->initCollection($code); $collection->filter('ignored'); $collection->loadTranslations(); foreach ($messages as $key => $translation) { if (!isset($collection[$key])) { continue; } // @todo Temporary exception. Should be fixed elsewhere more generically. if ($translation == '{{PLURAL:GETTEXT|}}') { return; } $title = Title::makeTitleSafe($this->group->getNamespace(), "{$key}/{$code}"); $page = $title->getPrefixedText(); if ($collection[$key]->translation() === null) { $this->reportProgress("Importing {$page} as a new translation\n", 'importing'); $this->import($title, $translation, 'Importing a new translation'); continue; } $current = str_replace(TRANSLATE_FUZZY, '', $collection[$key]->translation()); $translation = str_replace(TRANSLATE_FUZZY, '', $translation); if ($translation === $current) { continue; } $this->reportProgress("Conflict in " . $this->color('bold', $page) . "!", $page); $iso = 'xnY-xnm-xnd"T"xnH:xni:xns'; $lang = RequestContext::getMain()->getLanguage(); // Finally all is ok, now lets start comparing timestamps // Make sure we are comparing timestamps in same format $wikiTs = $this->getLastGoodChange($title, $startTs); if ($wikiTs) { $wikiTs = wfTimestamp(TS_UNIX, $wikiTs); $wikiDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $wikiTs)); } else { $wikiDate = 'Unknown'; } if ($startTs) { $startTs = wfTimestamp(TS_UNIX, $startTs); } if ($endTs) { $endTs = wfTimestamp(TS_UNIX, $endTs); } if ($changeTs) { $changeTs = wfTimestamp(TS_UNIX, $changeTs); $changeDate = $lang->sprintfDate($iso, wfTimestamp(TS_MW, $changeTs)); } else { $changeDate = 'Unknown'; } if ($changeTs) { if ($wikiTs > $startTs && $changeTs <= $endTs) { $this->reportProgress(" →Changed in wiki after export: IGNORE", $page); continue; } elseif (!$wikiTs || $changeTs > $endTs && $wikiTs < $startTs) { $this->reportProgress(" →Changed in source after export: IMPORT", $page); $this->import($title, $translation, 'Updating translation from external source'); continue; } } if (!$this->interactive) { continue; } $this->reportProgress(" →Needs manual resolution", $page); $this->reportProgress("Source translation at {$changeDate}:", 'source'); $this->reportProgress($this->color('blue', $translation), 'source'); $this->reportProgress("Wiki translation at {$wikiDate}:", 'translation'); $this->reportProgress($this->color('green', $current), 'translation'); do { $this->reportProgress("Resolution: [S]kip [I]mport [C]onflict: ", 'foo'); // @todo Find an elegant way to use Maintenance::readconsole(). $action = fgets(STDIN); $action = strtoupper(trim($action)); if ($action === 'S') { break; } if ($action === 'I') { $this->import($title, $translation, 'Updating translation from external source'); break; } if ($action === 'C') { $this->import($title, TRANSLATE_FUZZY . $translation, 'Edit conflict between wiki and source'); break; } } while (true); } }