queda solo en "otras semanas" * 2) la que estaba en "semana actual" -> pasa a "semana pasada" * 3) la carta NUEVA -> pasa a "semana actual" * * Robusto/autocorrige: la NUEVA es el parámetro CARTA; la "semana pasada" se * deriva como la carta publicada más reciente que NO es la nueva (por fecha), * no por quién estuviera en el término (que puede estar roto). Garantiza * count=1 en "actual" y count=1 en "pasada" por idioma. "Otras semanas" (21) * es el cajón base que conservan TODAS las cartas. * * Términos ES base (se derivan por Polylang a cada idioma): * actual = 6 (cartasemana) | pasada = 22 (carta-semana-pasada) | otras = 21 * * Uso: CARTA= php rotate_cartas.php (dry-run) * APPLY=1 CARTA= php rotate_cartas.php */ require getenv('FEA_WP_LOAD') ?: '/var/www/html/wp-load.php'; $APPLY = getenv('APPLY') === '1'; $CARTA = (int)(getenv('CARTA') ?: 0); if (!$CARTA) { fwrite(STDERR, "Falta CARTA=\n"); exit(1); } $actual_terms = pll_get_term_translations(6); $pasada_terms = pll_get_term_translations(22); $otras_terms = pll_get_term_translations(21); $carta_tr = pll_get_post_translations($CARTA); function cartas_en($terms) { // posts publish en cualquiera de esos términos (mismo idioma), por fecha desc return get_posts(['post_type'=>'post','post_status'=>'publish','numberposts'=>-1,'fields'=>'ids', 'orderby'=>'date','order'=>'DESC','suppress_filters'=>true, 'tax_query'=>[['taxonomy'=>'category','field'=>'term_id','terms'=>array_values(array_filter($terms))]]]); } foreach ($actual_terms as $lang => $t_actual) { $t_pasada = (int)($pasada_terms[$lang] ?? 0); $t_otras = (int)($otras_terms[$lang] ?? 0); $t_actual = (int)$t_actual; $new = (int)($carta_tr[$lang] ?? 0); // Conjunto de cartas de ESTE idioma (los términos ya son por idioma) por fecha desc. $all = cartas_en([$t_actual, $t_pasada, $t_otras]); // "semana pasada" = la más reciente que no es la nueva. $prev = 0; foreach ($all as $pid) { if ($pid != $new) { $prev = $pid; break; } } // Posts actualmente marcados como actual/pasada (conjunto pequeño a limpiar). $flagged = get_posts(['post_type'=>'post','post_status'=>'any','numberposts'=>-1,'fields'=>'ids', 'suppress_filters'=>true, 'tax_query'=>[['taxonomy'=>'category','field'=>'term_id','terms'=>array_values(array_filter([$t_actual,$t_pasada]))]]]); if ($APPLY) { // 1) limpiar: quitar actual+pasada de cualquiera salvo los dos destinos. foreach ($flagged as $pid) { if ($pid == $new || $pid == $prev) continue; wp_remove_object_terms($pid, array_values(array_filter([$t_actual,$t_pasada])), 'category'); } // 2) NUEVA -> semana actual (y fuera de pasada). Mantener otras. if ($new) { wp_set_object_terms($new, [$t_actual], 'category', true); if ($t_pasada) wp_remove_object_terms($new, [$t_pasada], 'category'); if ($t_otras) wp_set_object_terms($new, [$t_otras], 'category', true); } // 3) ANTERIOR -> semana pasada (y fuera de actual). Mantener otras. if ($prev && $t_pasada) { wp_set_object_terms($prev, [$t_pasada], 'category', true); wp_remove_object_terms($prev, [$t_actual], 'category'); if ($t_otras) wp_set_object_terms($prev, [$t_otras], 'category', true); } clean_term_cache(array_filter([$t_actual,$t_pasada,$t_otras]), 'category'); } $cleaned = count(array_diff($flagged, [$new, $prev])); $tn = $new ? get_post($new) : null; $tp = $prev ? get_post($prev) : null; printf("%s: actual=#%d «%s» | pasada=#%d «%s» | degradadas a 'otras' %d post(s)%s\n", strtoupper($lang), $new, $tn?mb_substr($tn->post_title,0,26):'-', $prev, $tp?mb_substr($tp->post_title,0,26):'-', $cleaned, $APPLY?'':' [DRY-RUN]'); } echo $APPLY ? "APLICADO\n" : "DRY-RUN (APPLY=1 para aplicar)\n";