/*
======================
REPLIES + CONTENT (OPTIMISĂ)
======================
*/
private function migrateReplies(){
global $wpdb;
// đč dernier topic WP traitĂ©
$last_topic_wp = (int) $this->getLast_Topic();
// ======================
// STEP 1 : batch topics WP
// ======================
$topic_rows = $wpdb->get_results($wpdb->prepare("
SELECT p.ID AS wp_topic_id, pm.meta_value AS xoops_topic_id
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm
ON pm.post_id = p.ID
AND pm.meta_key = 'bbex_topic_id'
WHERE p.post_type = 'topic'
AND p.ID > %d
ORDER BY p.ID ASC
LIMIT 2000
", $last_topic_wp));
if(!$topic_rows){
$this->log('đ REPLIES DONE â plus aucun topic WP Ă traiter');
update_option('bbex_replies_done', 1, false);
return;
}
// ======================
// BUILD MAP
// ======================
$topic_map = [];
$xoops_topic_ids = [];
foreach($topic_rows as $t){
$topic_map[(int)$t->xoops_topic_id] = (int)$t->wp_topic_id;
$xoops_topic_ids[] = (int)$t->xoops_topic_id;
}
$ids_sql = implode(',', $xoops_topic_ids);
$this->log("đ REPLIES BATCH START");
$this->log("WP topics batch: " . count($topic_rows));
$this->log("XOOPS topics batch: " . count($xoops_topic_ids));
$this->log("XOOPS range: " . (min($xoops_topic_ids) ?? 0) . " â " . (max($xoops_topic_ids) ?? 0));
// ======================
// STEP 2 : GET POSTS
// ======================
$posts = $wpdb->get_results("
SELECT p.post_id, p.topic_id AS xoops_topic_id, p.uid, p.pid, p.post_time, pt.post_text
FROM {$this->getTable('posts')} p
JOIN {$this->getTable('posts_text')} pt ON pt.post_id = p.post_id
WHERE p.topic_id IN ($ids_sql)
ORDER BY p.post_id ASC
");
if(!$posts){
$max_wp_topic = max(array_column($topic_rows, 'wp_topic_id'));
$this->setLast_Topic($max_wp_topic);
$this->log("â ïž Aucun post trouvĂ©");
$this->log("âĄïž Skip batch â last_topic_wp=$max_wp_topic");
return;
}
// ======================
// STATS
// ======================
$inserted = 0;
$skipped = 0;
$updated = 0;
$total = count($posts);
$i = 0;
// ======================
// PROCESS
// ======================
foreach($posts as $p){
$i++;
// đč progression %
if($i % 200 === 0 || $i === $total){
$pct = round(($i / $total) * 100, 2);
$this->log("âł Progress replies: $i/$total ($pct%) | inserted=$inserted skipped=$skipped updated=$updated");
}
// user check
if(empty($this->user_map[$p->uid])){
$skipped++;
continue;
}
$wp_tid = $topic_map[(int)$p->xoops_topic_id] ?? 0;
if(!$wp_tid){
$skipped++;
continue;
}
// ======================
// MAIN TOPIC POST â CONTENT
// ======================
if($p->pid == 0){
$wpdb->query($wpdb->prepare("
UPDATE {$wpdb->posts}
SET post_content = IF(post_content = '', %s, post_content)
WHERE ID = %d
", $p->post_text, $wp_tid));
$updated++;
continue;
}
// ======================
// ANTI DOUBLON (IMPORTANT FIX)
// ======================
$exists = $wpdb->get_var($wpdb->prepare("
SELECT 1 FROM bbex_post_lookup
WHERE xoops_post_id = %d AND type = 'reply'
LIMIT 1
", $p->post_id));
if($exists){
$skipped++;
continue;
}
// ======================
// INSERT REPLY
// ======================
$wpdb->insert($wpdb->posts, [
'post_author' => $this->user_map[$p->uid],
'post_date' => date('Y-m-d H:i:s', $p->post_time),
'post_content' => $p->post_text,
'post_status' => 'publish',
'post_type' => 'reply',
'post_parent' => $wp_tid
]);
$rid = (int) $wpdb->insert_id;
if(!$rid){
$skipped++;
continue;
}
$inserted++;
// meta topic
$wpdb->insert($wpdb->postmeta,[
'post_id' => $rid,
'meta_key' => '_bbp_topic_id',
'meta_value' => $wp_tid
]);
// forum
$forum_id = $wpdb->get_var($wpdb->prepare("
SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d
", $wp_tid));
if($forum_id){
$wpdb->insert($wpdb->postmeta,[
'post_id' => $rid,
'meta_key' => '_bbp_forum_id',
'meta_value' => $forum_id
]);
}
// lookup
$wpdb->query($wpdb->prepare("
INSERT INTO bbex_post_lookup (xoops_post_id, wp_post_id, type)
VALUES (%d, %d, 'reply')
ON DUPLICATE KEY UPDATE wp_post_id = wp_post_id
", $p->post_id, $rid));
}
// ======================
// SAVE PROGRESSION
// ======================
$max_wp_topic = max(array_column($topic_rows, 'wp_topic_id'));
$this->setLast_Topic($max_wp_topic);
// ======================
// FINAL LOG
// ======================
$this->log("====================================");
$this->log("đ REPLIES BATCH FINISHED");
$this->log("đ total=$total | inserted=$inserted | updated=$updated | skipped=$skipped");
$this->log("âĄïž last_topic_wp=$max_wp_topic");
$this->log("====================================");
}
add_action('init', function(){
if(!isset($_GET['bbex_batch_sans_mirror'])) return;
if($_GET['bbex_batch_sans_mirror'] !== 'run') return;
if(!isset($_GET['key']) || $_GET['key'] !== 'oasis-cron'){
die('clé invalide');
}
$migration = new BBExBatchMigration();
$migration->setSource('live');
$migration->run();
echo "Batch LIVE exécuté";
exit;
});private function migrateReplies(){
global $wpdb;
// đč dernier topic WP traitĂ© pour les replies
$last_topic_wp = (int) $this->getLast_Topic();
// STEP 1 : batch topics WP
$topic_rows = $wpdb->get_results($wpdb->prepare("
SELECT p.ID AS wp_topic_id, pm.meta_value AS xoops_topic_id
FROM {$wpdb->posts} p
JOIN {$wpdb->postmeta} pm
ON pm.post_id = p.ID
AND pm.meta_key = 'bbex_topic_id'
WHERE p.post_type = 'topic'
AND p.ID > %d
ORDER BY p.ID ASC
LIMIT 2000
", $last_topic_wp));
if(!$topic_rows){
$this->log('đ REPLIES DONE â plus aucun topic WP Ă traiter');
update_option('bbex_replies_done', 1, false);
return;
}
// BUILD MAP
$topic_map = [];
$xoops_topic_ids = [];
foreach($topic_rows as $t){
$topic_map[(int)$t->xoops_topic_id] = (int)$t->wp_topic_id;
$xoops_topic_ids[] = (int)$t->xoops_topic_id;
}
$ids_sql = implode(',', $xoops_topic_ids);
$this->log("đ REPLIES BATCH START");
$this->log("WP topics batch: " . count($topic_rows));
$this->log("XOOPS topics batch: " . count($xoops_topic_ids));
$this->log("XOOPS range: " . (min($xoops_topic_ids) ?? 0) . " â " . (max($xoops_topic_ids) ?? 0));
// STEP 2 : GET POSTS (LIVE XOOPSEOL)
$posts = $wpdb->get_results("
SELECT p.post_id, p.topic_id AS xoops_topic_id, p.uid, p.pid, p.post_time, pt.post_text
FROM {$this->getTable('posts')} p
JOIN {$this->getTable('posts_text')} pt ON pt.post_id = p.post_id
WHERE p.topic_id IN ($ids_sql)
ORDER BY p.post_id ASC
");
if(!$posts){
$max_wp_topic = max(array_column($topic_rows, 'wp_topic_id'));
$this->setLast_Topic($max_wp_topic);
$this->log("â ïž Aucun post trouvĂ©");
$this->log("âĄïž Skip batch â last_topic_wp=$max_wp_topic");
return;
}
$inserted = 0;
$skipped = 0;
$updated = 0;
$total = count($posts);
$i = 0;
foreach($posts as $p){
$i++;
if($i % 200 === 0 || $i === $total){
$pct = round(($i / $total) * 100, 2);
$this->log("âł Progress replies: $i/$total ($pct%) | inserted=$inserted skipped=$skipped updated=$updated");
}
// user check
if(empty($this->user_map[$p->uid])){
$skipped++;
continue;
}
$wp_tid = $topic_map[(int)$p->xoops_topic_id] ?? 0;
if(!$wp_tid){
$skipped++;
continue;
}
// MAIN TOPIC POST â CONTENT
if($p->pid == 0){
$wpdb->query($wpdb->prepare("
UPDATE {$wpdb->posts}
SET post_content = IF(post_content = '', %s, post_content)
WHERE ID = %d
", $p->post_text, $wp_tid));
$updated++;
continue;
}
// ANTI DOUBLON
$exists = $wpdb->get_var($wpdb->prepare("
SELECT 1 FROM bbex_post_lookup
WHERE xoops_post_id = %d AND type = 'reply'
LIMIT 1
", $p->post_id));
if($exists){
$skipped++;
continue;
}
// INSERT REPLY
$wpdb->insert($wpdb->posts, [
'post_author' => $this->user_map[$p->uid],
'post_date' => date('Y-m-d H:i:s', $p->post_time),
'post_content' => $p->post_text,
'post_status' => 'publish',
'post_type' => 'reply',
'post_parent' => $wp_tid
]);
$rid = (int) $wpdb->insert_id;
if(!$rid){
$skipped++;
continue;
}
$inserted++;
// meta topic
$wpdb->insert($wpdb->postmeta,[
'post_id' => $rid,
'meta_key' => '_bbp_topic_id',
'meta_value' => $wp_tid
]);
// forum
$forum_id = $wpdb->get_var($wpdb->prepare("
SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d
", $wp_tid));
if($forum_id){
$wpdb->insert($wpdb->postmeta,[
'post_id' => $rid,
'meta_key' => '_bbp_forum_id',
'meta_value' => $forum_id
]);
}
// lookup
$wpdb->query($wpdb->prepare("
INSERT INTO bbex_post_lookup (xoops_post_id, wp_post_id, type)
VALUES (%d, %d, 'reply')
ON DUPLICATE KEY UPDATE wp_post_id = wp_post_id
", $p->post_id, $rid));
}
$max_wp_topic = max(array_column($topic_rows, 'wp_topic_id'));
$this->setLast_Topic($max_wp_topic);
$this->log("====================================");
$this->log("đ REPLIES BATCH FINISHED");
$this->log("đ total=$total | inserted=$inserted | updated=$updated | skipped=$skipped");
$this->log("âĄïž last_topic_wp=$max_wp_topic");
$this->log("====================================");
}
if(isset($_GET['source'])){
$migration->setSource($_GET['source']);
}
RĂLE DE L'ADMINISTRATRICE D'OASIS - Oasis des Artistes. Le plus beau site de poĂ©sie
Aller au contenu
Ce sujet contient 4 réponses, 4 participants et a Ă©tĂ© mis Ă jour pour la derniĂšre fois par Sybilla , le 16-11-2025 16:14 .
joel
Sujet: 198 Réponses: 4013
Bonsoir,
Une question à été soulevée.
Quel est le rĂŽle de SYBILLA ?
*** Un administrateur sur un site de poésies est un «  » » »post clé. » » » »
Il a les mĂȘmes pouvoirs qu’un WEBMASTER.***
L’informaticien et moi-mĂȘme avons dĂ©cidĂ© il y a quelques mois d’accorder le poste d »administratrice Ă SYBILLA, car nous avons une entiĂšre confiance en elle.
EN QUOI CONSISTE SON POST ?
*** Elle possĂšde les mĂȘmes droits que l’informaticien et moi.
*** Elle a le rĂŽle d’une chef avec TOUS les pouvoirs dĂ©cisionnaires.
*** Elle est la chef d’Ă©quipe des modĂ©rateurs avec moi et doit superviser les membres et les modĂ©rateurs.
*** En cas de conflits entre des poĂštes, c’est moi et SYBILLA qui prenons les dĂ©cisions finales.
*** Elle gĂšre les membres d’OASIS et les modĂ©rateurs.
*** Elle crĂ©e les mises en pages, et nous les mettons sur la page d’accueil, la rubrique des nominĂ©s et sur les poĂ©sies. Et nous annonçons les nominations aux poĂštes.
*** Nous avons accĂšs tous deux au panneau d’administration comme l’informaticien.
SYBILLA et moi avont le droit d’inscription et de bannissement des membres du site.
Je demande Ă tous les membres de respecter SYBILLA, mon bras droit ainsi que son rĂŽle d’administratrice, et de nous laisser faire notre travail correctement.
Merci de votre compréhension.
Cordialement.
Joël.
Bonsoir Joël,
Merci pour ce post qui met en lumiĂšre les attributions du rĂŽle d’administratrice d’Oasis que gĂšre Sybilla avec brio, que je respecte et qui a toute mon amitiĂ©. Un rĂŽle pas facile et trĂšs prenant, elle a du mĂ©rite et chacun se doit de la respecter.
Amitié,
Roman
Sybilla
Sujet: 17798 Réponses: 198089
Bonsoir TrÚs Cher Ami poÚte Joël,
Je te remercie infiniment pour toutes ces précisions.
Mais plus encore pour ton entiĂšre confiance !
Douce soirée Cher Ami Joël !
Toutes mes amitiés
Bon courage et prends bien soin de toi
Gros bisous amicaux
Sybilla
Bonsoir Cher Ami poĂšte Roman,
Oups, je n’avais pas vu ta rĂ©ponse encore…
Je te remercie infiniment et suis trÚs touchée par tes mots !
Belle soirée Cher Ami poÚte Roman !
Toute mon amitié sincÚre
Gros bisous amicaux
Sybilla
Le r?ve est le poumon de ma vie (Citation de Sybilla)
poemic
Sujet: 3071 Réponses: 50398
Bonjour JOEL
Une mise au point qui met bien en valeur l’importance de l’Administratrice
d’Oasis et qui devrait inspirer respect et confiance..
Je tiens à remercier Sybilla pour sa présence , sa disponibilité
et sa compétence , en toute amitié et respect .
Merci Joel d’avoir prĂ©cisĂ© ce rĂŽle important .
Cordialement
poemic
Sybilla
Sujet: 17798 Réponses: 198089
Bonsoir Cher Ami poĂšte Michel,
Merci… infiniment…
Dans la vie, le respect ne devrait jamais aller qu’en sens unique..
Il me semble avoir toujours respecter chacun de mon cotĂ©…
Ne jamais oublier une chose nous tous :
«  »User, mais ne pas abuser » »
Moi-mĂȘme, en tant qu’administratrice, je soumets toujours mes propositions Ă JoĂ«l, le propriĂ©taire du site et mari d’Adeline.
Tout est question de respect.
TrÚs touchée par tes mots !
Belle soirée Cher Ami poÚte Michel !
Toutes mes amitiés
Gros bisous amicaux
Sybilla
Le r?ve est le poumon de ma vie (Citation de Sybilla)
Vous devez être connecté pour répondre à ce sujet.
Pour offrir les meilleures expériences, nous utilisons des technologies telles que les cookies pour stocker et/ou accéder aux informations des appareils. Le fait de consentir à ces technologies nous permettra de traiter des données telles que le comportement de navigation ou les ID uniques sur ce site. Le fait de ne pas consentir ou de retirer son consentement peut avoir un effet négatif sur certaines caractéristiques et fonctions.
LâaccĂšs ou le stockage technique est strictement nĂ©cessaire dans la finalitĂ© dâintĂ©rĂȘt lĂ©gitime de permettre lâutilisation dâun service spĂ©cifique explicitement demandĂ© par lâabonnĂ© ou lâutilisateur, ou dans le seul but dâeffectuer la transmission dâune communication sur un rĂ©seau de communications Ă©lectroniques.
LâaccĂšs ou le stockage technique est nĂ©cessaire dans la finalitĂ© dâintĂ©rĂȘt lĂ©gitime de stocker des prĂ©fĂ©rences qui ne sont pas demandĂ©es par lâabonnĂ© ou lâinternaute.
Le stockage ou lâaccĂšs technique qui est utilisĂ© exclusivement Ă des fins statistiques.
Le stockage ou lâaccĂšs technique qui est utilisĂ© exclusivement dans des finalitĂ©s statistiques anonymes. En lâabsence dâune assignation Ă comparaĂźtre, dâune conformitĂ© volontaire de la part de votre fournisseur dâaccĂšs Ă internet ou dâenregistrements supplĂ©mentaires provenant dâune tierce partie, les informations stockĂ©es ou extraites Ă cette seule fin ne peuvent gĂ©nĂ©ralement pas ĂȘtre utilisĂ©es pour vous identifier.
LâaccĂšs ou le stockage technique est nĂ©cessaire pour crĂ©er des profils dâinternautes afin dâenvoyer des publicitĂ©s, ou pour suivre lâutilisateur sur un site web ou sur plusieurs sites web ayant des finalitĂ©s marketing similaires.
Gérer le consentement