wiki illustrations et team osm fr
This commit is contained in:
parent
d7a54458dc
commit
77ad76cc7e
13 changed files with 78859 additions and 13414 deletions
|
@ -11,7 +11,7 @@ class WikiController extends AbstractController
|
|||
/**
|
||||
* Detects incorrect heading hierarchies in a list of sections
|
||||
* For example, h4 directly under h2 without h3 in between
|
||||
*
|
||||
*
|
||||
* @param array $sections List of sections with 'level' and 'title' keys
|
||||
* @return array List of section indices with hierarchy errors
|
||||
*/
|
||||
|
@ -19,44 +19,44 @@ class WikiController extends AbstractController
|
|||
{
|
||||
$errors = [];
|
||||
$lastLevel = 0;
|
||||
|
||||
|
||||
foreach ($sections as $index => $section) {
|
||||
$currentLevel = isset($section['level']) ? (int)$section['level'] : 0;
|
||||
|
||||
|
||||
// Skip if level is not set or is 0
|
||||
if ($currentLevel === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If this is the first section, just record its level
|
||||
if ($lastLevel === 0) {
|
||||
$lastLevel = $currentLevel;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Check if the level jump is more than 1
|
||||
// For example, h2 -> h4 (skipping h3)
|
||||
if ($currentLevel > $lastLevel + 1) {
|
||||
$errors[] = $index;
|
||||
}
|
||||
|
||||
|
||||
$lastLevel = $currentLevel;
|
||||
}
|
||||
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds an aligned list of sections for English and French
|
||||
* Adds empty placeholders in the French column for sections that exist in English but not in French
|
||||
*
|
||||
*
|
||||
* @param array $sectionComparison Section comparison data with 'common', 'en_only', and 'fr_only' keys
|
||||
* @return array Aligned section list with 'en' and 'fr' columns
|
||||
*/
|
||||
private function buildAlignedSectionList(array $sectionComparison): array
|
||||
{
|
||||
$alignedSections = [];
|
||||
|
||||
|
||||
// First, process common sections (they already have both en and fr)
|
||||
if (isset($sectionComparison['common']) && is_array($sectionComparison['common'])) {
|
||||
foreach ($sectionComparison['common'] as $section) {
|
||||
|
@ -66,7 +66,7 @@ class WikiController extends AbstractController
|
|||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Then, process English-only sections and add empty placeholders for French
|
||||
if (isset($sectionComparison['en_only']) && is_array($sectionComparison['en_only'])) {
|
||||
foreach ($sectionComparison['en_only'] as $section) {
|
||||
|
@ -83,7 +83,7 @@ class WikiController extends AbstractController
|
|||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Finally, process French-only sections (these will be shown at the end)
|
||||
if (isset($sectionComparison['fr_only']) && is_array($sectionComparison['fr_only'])) {
|
||||
foreach ($sectionComparison['fr_only'] as $section) {
|
||||
|
@ -100,9 +100,10 @@ class WikiController extends AbstractController
|
|||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $alignedSections;
|
||||
}
|
||||
|
||||
#[Route('/wiki/recent-changes', name: 'app_admin_wiki_recent_changes')]
|
||||
public function recentChanges(): Response
|
||||
{
|
||||
|
@ -617,7 +618,7 @@ class WikiController extends AbstractController
|
|||
'status' => $proposal['status'] ?? 'Voting',
|
||||
'type' => 'voting'
|
||||
];
|
||||
|
||||
|
||||
// Add voting information if available
|
||||
if (isset($proposal['votes'])) {
|
||||
$formattedProposal['votes'] = $proposal['votes'];
|
||||
|
@ -626,7 +627,7 @@ class WikiController extends AbstractController
|
|||
$formattedProposal['oppose_percentage'] = $proposal['oppose_percentage'] ?? 0;
|
||||
$formattedProposal['abstain_percentage'] = $proposal['abstain_percentage'] ?? 0;
|
||||
}
|
||||
|
||||
|
||||
$formattedProposals[] = $formattedProposal;
|
||||
}
|
||||
|
||||
|
@ -692,21 +693,21 @@ class WikiController extends AbstractController
|
|||
'page' => $randomPage
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
#[Route('/wiki/create-french/{key}', name: 'app_admin_wiki_create_french')]
|
||||
public function createFrench(string $key): Response
|
||||
{
|
||||
// Construct the URLs for the English page and the French page creation form
|
||||
$englishUrl = "https://wiki.openstreetmap.org/wiki/Key:{$key}";
|
||||
$frenchEditUrl = "https://wiki.openstreetmap.org/w/index.php?title=FR:{$key}&action=edit";
|
||||
|
||||
|
||||
return $this->render('admin/wiki_create_french.html.twig', [
|
||||
'key' => $key,
|
||||
'english_url' => $englishUrl,
|
||||
'french_edit_url' => $frenchEditUrl
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
#[Route('/wiki/archived-proposals', name: 'app_admin_wiki_archived_proposals')]
|
||||
public function archivedProposals(\Symfony\Component\HttpFoundation\Request $request): Response
|
||||
{
|
||||
|
@ -723,7 +724,7 @@ class WikiController extends AbstractController
|
|||
if ($forceRefresh) {
|
||||
$this->refreshArchivedProposalsData($limit);
|
||||
$this->addFlash('success', 'Les données des propositions archivées ont été rafraîchies.');
|
||||
|
||||
|
||||
// Preserve the limit parameter in the redirect if it was provided
|
||||
if ($limit) {
|
||||
return $this->redirectToRoute('app_admin_wiki_archived_proposals', ['limit' => $limit]);
|
||||
|
@ -751,7 +752,7 @@ class WikiController extends AbstractController
|
|||
if ($diff->days > 1) {
|
||||
$this->refreshArchivedProposalsData($limit);
|
||||
$this->addFlash('info', 'Les données des propositions archivées ont été automatiquement mises à jour car elles dataient de plus d\'un jour.');
|
||||
|
||||
|
||||
// Preserve the limit parameter in the redirect if it was provided
|
||||
if ($limit) {
|
||||
return $this->redirectToRoute('app_admin_wiki_archived_proposals', ['limit' => $limit]);
|
||||
|
@ -766,7 +767,7 @@ class WikiController extends AbstractController
|
|||
// Check if the file was created
|
||||
if (file_exists($jsonFile)) {
|
||||
$this->addFlash('success', 'Le fichier des propositions archivées a été généré avec succès.');
|
||||
|
||||
|
||||
// Preserve the limit parameter in the redirect if it was provided
|
||||
if ($limit) {
|
||||
return $this->redirectToRoute('app_admin_wiki_archived_proposals', ['limit' => $limit]);
|
||||
|
@ -784,10 +785,10 @@ class WikiController extends AbstractController
|
|||
'limit' => $limit
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the archived proposals data by running the fetch_archived_proposals.py script
|
||||
*
|
||||
*
|
||||
* @param int|null $limit Optional limit for the number of proposals to process
|
||||
*/
|
||||
private function refreshArchivedProposalsData(?int $limit = null): void
|
||||
|
@ -796,12 +797,12 @@ class WikiController extends AbstractController
|
|||
$scriptPath = $this->getParameter('kernel.project_dir') . '/wiki_compare/fetch_archived_proposals.py';
|
||||
if (file_exists($scriptPath)) {
|
||||
$command = 'python3 ' . $scriptPath;
|
||||
|
||||
|
||||
// Add limit parameter if provided
|
||||
if ($limit !== null) {
|
||||
$command .= ' --limit ' . $limit;
|
||||
}
|
||||
|
||||
|
||||
exec($command . ' 2>&1', $output, $returnCode);
|
||||
|
||||
if ($returnCode !== 0) {
|
||||
|
@ -873,6 +874,7 @@ class WikiController extends AbstractController
|
|||
$missingTranslations[$key] = $languages['en'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate differences between English and French versions
|
||||
foreach ($wikiPages as $key => $languages) {
|
||||
|
@ -1027,80 +1029,80 @@ class WikiController extends AbstractController
|
|||
|
||||
// Get link comparison data
|
||||
$linkComparison = $page['link_comparison'] ?? null;
|
||||
|
||||
|
||||
// Sort links alphabetically by URL if link comparison exists
|
||||
if ($linkComparison) {
|
||||
// Sort English-only links
|
||||
if (isset($linkComparison['en_only']) && is_array($linkComparison['en_only'])) {
|
||||
usort($linkComparison['en_only'], function($a, $b) {
|
||||
usort($linkComparison['en_only'], function ($a, $b) {
|
||||
return strcmp($a['href'], $b['href']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Sort French-only links
|
||||
if (isset($linkComparison['fr_only']) && is_array($linkComparison['fr_only'])) {
|
||||
usort($linkComparison['fr_only'], function($a, $b) {
|
||||
usort($linkComparison['fr_only'], function ($a, $b) {
|
||||
return strcmp($a['href'], $b['href']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Sort common links
|
||||
if (isset($linkComparison['common']) && is_array($linkComparison['common'])) {
|
||||
usort($linkComparison['common'], function($a, $b) {
|
||||
usort($linkComparison['common'], function ($a, $b) {
|
||||
return strcmp($a['en']['href'], $b['en']['href']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get section comparison data and filter out "Contents" sections and navigation sections
|
||||
$sectionComparison = $page['section_comparison'] ?? null;
|
||||
|
||||
|
||||
// Sections to exclude from comparison (navigation elements)
|
||||
$excludedSections = [
|
||||
'Contents', 'Sommaire',
|
||||
'Contents', 'Sommaire',
|
||||
'Personal tools', 'Namespaces', 'Views', 'Search', 'Site', 'Tools', 'In other projects'
|
||||
];
|
||||
|
||||
|
||||
// Filter out excluded sections if section comparison exists
|
||||
if ($sectionComparison) {
|
||||
// Filter common sections
|
||||
if (isset($sectionComparison['common']) && is_array($sectionComparison['common'])) {
|
||||
$sectionComparison['common'] = array_filter($sectionComparison['common'], function($section) use ($excludedSections) {
|
||||
$sectionComparison['common'] = array_filter($sectionComparison['common'], function ($section) use ($excludedSections) {
|
||||
// Skip if either English or French title is in the excluded list
|
||||
return !(in_array($section['en']['title'], $excludedSections) || in_array($section['fr']['title'], $excludedSections));
|
||||
});
|
||||
// Re-index array
|
||||
$sectionComparison['common'] = array_values($sectionComparison['common']);
|
||||
}
|
||||
|
||||
|
||||
// Filter English-only sections
|
||||
if (isset($sectionComparison['en_only']) && is_array($sectionComparison['en_only'])) {
|
||||
$sectionComparison['en_only'] = array_filter($sectionComparison['en_only'], function($section) use ($excludedSections) {
|
||||
$sectionComparison['en_only'] = array_filter($sectionComparison['en_only'], function ($section) use ($excludedSections) {
|
||||
return !in_array($section['title'], $excludedSections);
|
||||
});
|
||||
// Re-index array
|
||||
$sectionComparison['en_only'] = array_values($sectionComparison['en_only']);
|
||||
}
|
||||
|
||||
|
||||
// Filter French-only sections
|
||||
if (isset($sectionComparison['fr_only']) && is_array($sectionComparison['fr_only'])) {
|
||||
$sectionComparison['fr_only'] = array_filter($sectionComparison['fr_only'], function($section) use ($excludedSections) {
|
||||
$sectionComparison['fr_only'] = array_filter($sectionComparison['fr_only'], function ($section) use ($excludedSections) {
|
||||
return !in_array($section['title'], $excludedSections);
|
||||
});
|
||||
// Re-index array
|
||||
$sectionComparison['fr_only'] = array_values($sectionComparison['fr_only']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate adjusted section counts (excluding "Contents" sections)
|
||||
$enSectionCount = $enPage['sections'];
|
||||
$frSectionCount = $frPage['sections'];
|
||||
|
||||
|
||||
// Adjust section counts if we have section comparison data
|
||||
if ($sectionComparison) {
|
||||
// Count how many sections were filtered out
|
||||
$filteredCount = 0;
|
||||
|
||||
|
||||
// Check common sections that were filtered
|
||||
if (isset($page['section_comparison']['common']) && is_array($page['section_comparison']['common'])) {
|
||||
foreach ($page['section_comparison']['common'] as $section) {
|
||||
|
@ -1109,7 +1111,7 @@ class WikiController extends AbstractController
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check English-only sections that were filtered
|
||||
if (isset($page['section_comparison']['en_only']) && is_array($page['section_comparison']['en_only'])) {
|
||||
foreach ($page['section_comparison']['en_only'] as $section) {
|
||||
|
@ -1118,7 +1120,7 @@ class WikiController extends AbstractController
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check French-only sections that were filtered
|
||||
if (isset($page['section_comparison']['fr_only']) && is_array($page['section_comparison']['fr_only'])) {
|
||||
foreach ($page['section_comparison']['fr_only'] as $section) {
|
||||
|
@ -1127,47 +1129,47 @@ class WikiController extends AbstractController
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adjust section counts
|
||||
$enSectionCount -= $filteredCount;
|
||||
$frSectionCount -= $filteredCount;
|
||||
}
|
||||
|
||||
|
||||
// Check for incorrect heading hierarchies
|
||||
$enHierarchyErrors = [];
|
||||
$frHierarchyErrors = [];
|
||||
|
||||
|
||||
// Check English sections
|
||||
if (isset($sectionComparison['en_only']) && is_array($sectionComparison['en_only'])) {
|
||||
$enHierarchyErrors = $this->detectHeadingHierarchyErrors($sectionComparison['en_only']);
|
||||
}
|
||||
|
||||
|
||||
// Also check common sections (English side)
|
||||
if (isset($sectionComparison['common']) && is_array($sectionComparison['common'])) {
|
||||
$commonEnSections = array_map(function($section) {
|
||||
$commonEnSections = array_map(function ($section) {
|
||||
return $section['en'];
|
||||
}, $sectionComparison['common']);
|
||||
|
||||
|
||||
$enHierarchyErrors = array_merge($enHierarchyErrors, $this->detectHeadingHierarchyErrors($commonEnSections));
|
||||
}
|
||||
|
||||
|
||||
// Check French sections
|
||||
if (isset($sectionComparison['fr_only']) && is_array($sectionComparison['fr_only'])) {
|
||||
$frHierarchyErrors = $this->detectHeadingHierarchyErrors($sectionComparison['fr_only']);
|
||||
}
|
||||
|
||||
|
||||
// Also check common sections (French side)
|
||||
if (isset($sectionComparison['common']) && is_array($sectionComparison['common'])) {
|
||||
$commonFrSections = array_map(function($section) {
|
||||
$commonFrSections = array_map(function ($section) {
|
||||
return $section['fr'];
|
||||
}, $sectionComparison['common']);
|
||||
|
||||
|
||||
$frHierarchyErrors = array_merge($frHierarchyErrors, $this->detectHeadingHierarchyErrors($commonFrSections));
|
||||
}
|
||||
|
||||
|
||||
// Build aligned section list for better visualization of missing sections
|
||||
$alignedSections = $this->buildAlignedSectionList($sectionComparison);
|
||||
|
||||
|
||||
$detailedComparison = [
|
||||
'section_comparison' => $sectionComparison,
|
||||
'aligned_sections' => $alignedSections,
|
||||
|
@ -1355,11 +1357,11 @@ class WikiController extends AbstractController
|
|||
if ($frPage && isset($frPage['url']) && is_array($frPage['url'])) {
|
||||
$frPage['url'] = json_encode($frPage['url']);
|
||||
}
|
||||
|
||||
|
||||
if ($enPage && isset($enPage['url']) && is_array($enPage['url'])) {
|
||||
$enPage['url'] = json_encode($enPage['url']);
|
||||
}
|
||||
|
||||
|
||||
return $this->render('admin/wiki_compare.html.twig', [
|
||||
'key' => $key,
|
||||
'en_page' => $enPage,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue