public function compare_versions($article, $from, $to) { if ($from == 0 || $to == 0) { trigger_error('NO_VERSIONS_SELECTED'); } require $this->phpbb_root_path . 'includes/diff/diff.' . $this->php_ext; require $this->phpbb_root_path . 'includes/diff/engine.' . $this->php_ext; require $this->phpbb_root_path . 'includes/diff/renderer.' . $this->php_ext; $sql = 'SELECT article_text, bbcode_uid, bbcode_bitfield, article_sources, article_description FROM ' . $this->article_table . ' WHERE article_id = ' . (int) $from; $result = $this->db->sql_query($sql); $from_row = $this->db->sql_fetchrow($result); $sql = 'SELECT article_text, bbcode_uid, bbcode_bitfield, article_sources, article_description FROM ' . $this->article_table . ' WHERE article_id = ' . (int) $to; $result = $this->db->sql_query($sql); $to_row = $this->db->sql_fetchrow($result); $from_article = generate_text_for_edit($from_row['article_text'], $from_row['bbcode_uid'], $from_row['bbcode_bitfield'], 3, true); $to_article = generate_text_for_edit($to_row['article_text'], $to_row['bbcode_uid'], $to_row['bbcode_bitfield'], 3, true); $u_from = $this->helper->route('tas2580_wiki_index', array('id' => $from)); $u_to = $this->helper->route('tas2580_wiki_index', array('id' => $to)); $article_diff = new \diff($from_article['text'], $to_article['text']); $article_diff_empty = $article_diff->is_empty(); $sources_diff = new \diff($from_row['article_sources'], $to_row['article_sources']); $sources_diff_empty = $sources_diff->is_empty(); $description_diff = new \diff($from_row['article_description'], $to_row['article_description']); $descriptiondiff_empty = $sources_diff->is_empty(); $renderer = new \diff_renderer_inline(); $this->template->assign_vars(array('HEADLINE' => sprintf($this->user->lang['VERSION_COMPARE_HEADLINE'], $from, $to, $u_from, $u_to), 'DIFF' => $article_diff_empty ? '' : $renderer->get_diff_content($article_diff), 'DIFF_SOURCE' => $sources_diff_empty ? '' : $renderer->get_diff_content($sources_diff), 'DIFF_DESCRIPTION' => $descriptiondiff_empty ? '' : $renderer->get_diff_content($description_diff))); return $this->helper->render('article_compare.html', $this->user->lang['VERSIONS_OF_ARTICLE']); }
/** * Compare files for storage in update_list */ function make_update_diff(&$update_list, $original_file, $file, $custom = false) { global $phpbb_root_path, $user; $update_ary = array('filename' => $file, 'custom' => $custom); if ($custom) { $update_ary['original'] = $original_file; } // On a successfull update the new location file exists but the old one does not exist. // Check for this circumstance, the new file need to be up-to-date with the current file then... if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file)) { $tmp = array( 'file1' => file_get_contents($this->new_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); // We need to diff the contents here to make sure the file is really the one we expect $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty = $diff->is_empty(); unset($tmp, $diff); // if there are no differences we have an up-to-date file... if ($empty) { $update_list['up_to_date'][] = $update_ary; return; } // If no other status matches we have another file in the way... $update_list['new_conflict'][] = $update_ary; return; } // Old file removed? if (file_exists($this->old_location . $original_file) && !file_exists($this->new_location . $original_file)) { return; } // Check for existance, else abort immediately if (!file_exists($this->old_location . $original_file) || !file_exists($this->new_location . $original_file)) { trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); } $tmp = array( 'file1' => file_get_contents($this->old_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); // We need to diff the contents here to make sure the file is really the one we expect $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty_1 = $diff->is_empty(); unset($tmp, $diff); $tmp = array( 'file1' => file_get_contents($this->new_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); // We need to diff the contents here to make sure the file is really the one we expect $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty_2 = $diff->is_empty(); unset($tmp, $diff); // If the file is not modified we are finished here... if ($empty_1) { // Further check if it is already up to date - it could happen that non-modified files // slip through if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; } $update_list['not_modified'][] = $update_ary; return; } // If the file had been modified then we need to check if it is already up to date // if there are no differences we have an up-to-date file... if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; } // if the file is modified we try to make sure a merge succeed $tmp = array( 'file1' => file_get_contents($this->old_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), 'file3' => file_get_contents($this->new_location . $original_file), ); $diff = new diff3($tmp['file1'], $tmp['file2'], $tmp['file3'], false); unset($tmp); if ($diff->merged_output(false, false, false, true)) { $update_ary['conflicts'] = $diff->_conflicting_blocks; // There is one special case... users having merged with a conflicting file... we need to check this $tmp = array( 'file1' => file_get_contents($phpbb_root_path . $file), 'file2' => implode("\n", $diff->merged_orig_output()), ); $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty = $diff->is_empty(); if ($empty) { unset($update_ary['conflicts']); unset($diff); $update_list['up_to_date'][] = $update_ary; return; } $update_list['conflict'][] = $update_ary; unset($diff); return; } $tmp = array( 'file1' => file_get_contents($phpbb_root_path . $file), 'file2' => implode("\n", $diff->merged_output()), ); // now compare the merged output with the original file to see if the modified file is up to date $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty = $diff->is_empty(); if ($empty) { unset($diff); $update_list['up_to_date'][] = $update_ary; return; } // If no other status matches we have a modified file... $update_list['modified'][] = $update_ary; }
/** * Compare files for storage in update_list */ function make_update_diff(&$update_list, $original_file, $file, $custom = false) { global $phpbb_root_path, $user; $update_ary = array('filename' => $file, 'custom' => $custom); if ($custom) { $update_ary['original'] = $original_file; } // we only want to know if the files are successfully merged and newlines could result in errors (duplicate addition of lines and such things) // Therefore we check for empty diffs with two methods, preserving newlines and not preserving them (which mostly works best, therefore the first option) // On a successfull update the new location file exists but the old one does not exist. // Check for this circumstance, the new file need to be up-to-date with the current file then... if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file)) { $tmp = array( 'file1' => file_get_contents($this->new_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); // We need to diff the contents here to make sure the file is really the one we expect $diff = new diff($tmp['file1'], $tmp['file2'], false); $empty = $diff->is_empty(); unset($tmp, $diff); // if there are no differences we have an up-to-date file... if ($empty) { $update_list['up_to_date'][] = $update_ary; return; } // If no other status matches we have another file in the way... $update_list['new_conflict'][] = $update_ary; return; } // Old file removed? if (file_exists($this->old_location . $original_file) && !file_exists($this->new_location . $original_file)) { return; } // Check for existance, else abort immediately if (!file_exists($this->old_location . $original_file) || !file_exists($this->new_location . $original_file)) { trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); } $preserve_cr_ary = array(false, true); foreach ($preserve_cr_ary as $preserve_cr) { $tmp = array( 'file1' => file_get_contents($this->old_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); // We need to diff the contents here to make sure the file is really the one we expect $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); $empty_1 = $diff->is_empty(); unset($tmp, $diff); $tmp = array( 'file1' => file_get_contents($this->new_location . $original_file), 'file2' => file_get_contents($phpbb_root_path . $file), ); $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); $empty_2 = $diff->is_empty(); unset($tmp, $diff); // If the file is not modified we are finished here... if ($empty_1) { // Further check if it is already up to date - it could happen that non-modified files // slip through if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; } $update_list['not_modified'][] = $update_ary; return; } // If the file had been modified then we need to check if it is already up to date // if there are no differences we have an up-to-date file... if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; } } $conflicts = false; foreach ($preserve_cr_ary as $preserve_cr) { // if the file is modified we try to make sure a merge succeed $tmp = array( 'orig' => file_get_contents($this->old_location . $original_file), 'final1' => file_get_contents($phpbb_root_path . $file), 'final2' => file_get_contents($this->new_location . $original_file), ); $diff = new diff3($tmp['orig'], $tmp['final1'], $tmp['final2'], $preserve_cr); unset($tmp); if (!$diff->get_num_conflicts()) { $tmp = array( 'file1' => file_get_contents($phpbb_root_path . $file), 'file2' => implode("\n", $diff->merged_output()), ); // now compare the merged output with the original file to see if the modified file is up to date $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); $empty = $diff2->is_empty(); unset($diff, $diff2); if ($empty) { $update_list['up_to_date'][] = $update_ary; return; } // If we preserve cr tag it as modified because the conflict would not show in this mode anyway if ($preserve_cr) { $update_list['modified'][] = $update_ary; return; } } else { // There is one special case... users having merged with a conflicting file... we need to check this $tmp = array( 'file1' => file_get_contents($phpbb_root_path . $file), 'file2' => implode("\n", $diff->merged_new_output()), ); $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); $empty = $diff2->is_empty(); if (!$empty) { unset($tmp, $diff2); // We check if the user merged with his output $tmp = array( 'file1' => file_get_contents($phpbb_root_path . $file), 'file2' => implode("\n", $diff->merged_orig_output()), ); $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); $empty = $diff2->is_empty(); } if (!$empty) { $conflicts = $diff->get_num_conflicts(); } unset($diff, $diff2); if ($empty) { // A conflict got resolved... $update_list['up_to_date'][] = $update_ary; return; } } } if ($conflicts !== false) { $update_ary['conflicts'] = $conflicts; $update_list['conflict'][] = $update_ary; return; } // If no other status matches we have a modified file... $update_list['modified'][] = $update_ary; }