Come cambiare in modo sicuro il nome di un custom post type?
Ho creato un custom post type chiamato 'portfolio' ma voglio cambiarlo in 'projects'. Quali sono i passaggi esatti da seguire per cambiare il nome in modo sicuro ed evitare che i post del custom post type scompaiano dalla dashboard?
Nota: Ci sono già dei post in portfolio
quindi non posso semplicemente sostituire portfolio
con projects
.
/* Registra il Post Type Portfolio */
add_action('init', 'create_portfolio');
function create_portfolio() {
$labels = array(
'name' => __('Portfolio', 'nome generale del post type'),
'singular_name' => __('Progetto', 'nome singolare del post type'),
'add_new' => __('Aggiungi Nuovo', 'elemento portfolio'),
'add_new_item' => __('Aggiungi Nuovo Progetto'),
'edit_item' => __('Modifica Progetto'),
'new_item' => __('Nuovo Progetto'),
'view_item' => __('Visualizza Progetto'),
'search_items' => __('Cerca Progetti'),
'not_found' => __('Nessun elemento trovato'),
'not_found_in_trash' => __('Nessun elemento trovato nel Cestino'),
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','thumbnail')
);
register_post_type( 'portfolio' , $args );
}
/* Registra la Tassonomia Competenze */
register_taxonomy("Skills", array("portfolio"), array("hierarchical" => true, "label" => "Competenze", "singular_label" => "Competenza", "rewrite" => true));
/* Aggiungi Campi */
add_action("admin_init", "add_portfolio_fields");
function add_portfolio_fields(){
add_meta_box("website_url", "URL del Sito", "website_url", "portfolio", "side", "low");
add_meta_box("view_more", "Vedi Altro", "view_more", "portfolio", "side", "low");
add_meta_box("screenshot_name", "Nome Screenshot", "screenshot_name", "portfolio", "side", "low");
add_meta_box("thumbnail_name", "Nome Miniatura", "thumbnail_name", "portfolio", "side", "low");
add_meta_box("thumbnail_alt", "Alt Miniatura", "thumbnail_alt", "portfolio", "side", "low");
}
function website_url(){
global $post;
$custom = get_post_custom($post->ID);
$website_url = $custom["website_url"][0];
?>
<label>URL del Sito:</label>
<input size="50" name="website_url" value="<?php echo $website_url; ?>" />
<?php
}
function view_more() {
global $post;
$custom = get_post_custom($post->ID);
$view_more = $custom["view_more"][0];
?>
<label>Vedi Altro:</label>
<input size="50" name="view_more" value="<?php echo $view_more; ?>" />
<?php
}
function screenshot_name() {
global $post;
$custom = get_post_custom($post->ID);
$screenshot_name = $custom["screenshot_name"][0];
?>
<label>Nome Screenshot:</label>
<input name="screenshot_name" value="<?php echo $screenshot_name; ?>" />
<?php
}
function thumbnail_name() {
global $post;
$custom = get_post_custom($post->ID);
$thumbnail_name = $custom["thumbnail_name"][0];
?>
<label>Nome Miniatura:</label>
<input name="thumbnail_name" value="<?php echo $thumbnail_name; ?>" />
<?php
}
function thumbnail_alt() {
global $post;
$custom = get_post_custom($post->ID);
$thumbnail_alt = $custom["thumbnail_alt"][0];
?>
<label>Alt Miniatura:</label>
<input name="thumbnail_alt" value="<?php echo $thumbnail_alt; ?>" />
<?php
}
add_action('save_post', 'save_portfolio_details');
function save_portfolio_details(){
global $post;
update_post_meta($post->ID, "website_url", $_POST["website_url"]);
update_post_meta($post->ID, "view_more", $_POST["view_more"]);
update_post_meta($post->ID, "screenshot_name", $_POST["screenshot_name"]);
update_post_meta($post->ID, "thumbnail_name", $_POST["thumbnail_name"]);
update_post_meta($post->ID, "thumbnail_alt", $_POST["thumbnail_alt"]);
}
/* Colonne Personalizzate */
add_action("manage_posts_custom_column", "portfolio_custom_columns");
add_filter("manage_edit-portfolio_columns", "portfolio_edit_columns");
function portfolio_edit_columns($columns){
$columns = array(
"cb" => "<input type=\"checkbox\" />",
"title" => "Titolo Progetto",
"description" => "Descrizione",
);
return $columns;
}
function portfolio_custom_columns($column){
global $post;
switch ($column) {
case "description":
the_excerpt();
break;
}
}

Puoi farlo anche direttamente con MySQL.
UPDATE `wp_posts`
SET
# Aggiorna la colonna post_type
`post_type` = REPLACE(`post_type`,'nome_del_vecchio_post_type','nome_del_nuovo_post_type'),
# Aggiorna gli URL
`guid` = REPLACE(`guid`,'nome_del_vecchio_post_type','nome_del_nuovo_post_type')
WHERE `post_type` = 'nome_del_vecchio_post_type'
Due cose da notare:
- Dovrai aggiornare tutti i riferimenti a questo post type nel tuo codice (ad esempio, template, definizioni CMB2 o definizioni di tassonomia).
- Se hai memorizzato riferimenti a questo post type all'interno di
wp_postmeta
in array serializzati, non vuoi fare un semplice UPDATE/REPLACE perché li distruggeresti! A meno che le stringhe del nuovo e vecchio post type non abbiano esattamente la stessa lunghezza.

Estendendo ulteriormente la risposta di Will..., e specialmente se lo stai facendo dal tuo plugin:
global $wpdb;
$old_post_types = array('old_type' => 'new_type');
foreach ($old_post_types as $old_type=>$type) {
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_type = REPLACE(post_type, %s, %s)
WHERE post_type LIKE %s", $old_type, $type, $old_type ) );
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET guid = REPLACE(guid, %s, %s)
WHERE guid LIKE %s", "post_type={$old_type}", "post_type={$type}", "%post_type={$old_type}%" ) );
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET guid = REPLACE(guid, %s, %s)
WHERE guid LIKE %s", "/{$old_type}/", "/{$type}/", "%/{$old_type}/%" ) );
}
La modifica qui è di non sostituire direttamente il vecchio tipo nel guid, ma di sostituirlo solo se è presente "post_type=old_type" o "/old_type/". Questo evita di sostituire per errore degli slug validi. (ad esempio il tuo custom post type è portfolio, e anche lo slug di una pagina contiene portfolio)
Un'alternativa è fare qualcosa del genere:
global $wpdb, $wp_rewrite;
foreach ($old_post_types as $old_type=>$type) {
$q = 'numberposts=-1&post_status=any&post_type='.$old_type;
$items = get_posts($q);
foreach ($items as $item) {
$update['ID'] = $item->ID;
$update['post_type'] = $type;
wp_update_post( $update );
}
}
$wp_rewrite->flush_rules();

Grazie. Funziona. Un piccolo dettaglio: l'ultima parte della seconda query nel loop dovrebbe essere "%post_type={$old_type}%", non "%post_type={$type}%".

Ho semplicemente convertito le query wpdb in semplici query SQL per semplificare.
UPDATE wp_posts SET post_type = REPLACE(post_type, old_type, type) WHERE post_type LIKE '%old_type%';
UPDATE wp_posts SET guid = REPLACE(guid, 'post_type=old_type', 'post_type=type') WHERE guid LIKE '%post_type=old_type%';
UPDATE wp_posts SET guid = REPLACE(guid, '/old_type/', '/type/') WHERE guid LIKE '%/old_type/%';

Ecco un modo davvero semplice:
- Esegui l'Esportatore di WordPress (Strumenti > Esporta) - esporta solo il tipo di articolo di cui vuoi cambiare il nome
- Apri il file .xml generato e sostituisci tutte le menzioni del vecchio nome del tipo di articolo con il nuovo nome (sia nel meta "custom_post_type" che nel campo del permalink)
- Crea il tuo nuovo tipo di articolo con lo stesso nome presente nel file .xml modificato (ma mantieni comunque il vecchio nel caso qualcosa vada storto)
- Importa il file .xml modificato tramite l'Importatore di WordPress (plugin disponibile direttamente da Strumenti > Importa)
- Verifica che il contenuto sia presente nel nuovo tipo di articolo e poi elimina quello vecchio

Grazie per questo... ho anche seguito la conversazione qui per inizializzare un nuovo custom post type: https://wordpress.stackexchange.com/a/252078/142039 -- sono riuscito a importare tutti i miei dati, fantastico!

Utilizza una Query sul Database di WordPress ma Non Dimenticare i Dati Serializzati delle Opzioni
Il metodo che ha funzionato per me è stato eseguire una ricerca e sostituzione all'interno del database di WordPress, assicurandomi di non danneggiare i dati serializzati delle opzioni nel processo. Il modo migliore che ho trovato è utilizzare lo strumento di ricerca e sostituzione sicuro nel database di interconnect/it. Non eseguire mai una query del tipo SET
post_type= REPLACE(
post_type,'vecchio_tipo_post','nuovo_tipo_post')
senza sapere cosa stai facendo, altrimenti i dati serializzati si romperanno poiché mantengono un checksum e non potranno essere deserializzati correttamente.
Leggi la sezione "Problemi Potenziali" prima di seguire ciecamente queste istruzioni
Passo 1 - Aggiorna in Modo Sicuro il Database con il Nuovo Nome
- fai un backup del tuo database perché le seguenti modifiche potrebbero potenzialmente corromperlo.
- scarica e decomprimi lo strumento di ricerca e sostituzione sicuro nel database di interconnect/it
- aggiungi la directory estratta alla root del tuo sito web (funziona anche nelle sottodirectory)
- accedi alla directory, es: /miosito.com/path/to/utility/directory/
- segui le istruzioni. clicca 'dry-run' se sei paranoico per vedere le modifiche (ce ne saranno centinaia se hai anche solo pochi post del tipo modificato)
- clicca 'live run' per finalizzare le modifiche.
- rimuovi la directory dello strumento sicuro dalla tua directory WordPress poiché rappresenta un problema di sicurezza
Passo 2 - Reimposta i Tuoi Permalink
Se stai utilizzando i permalink, gli aggiornamenti al tuo database comprometteranno i reindirizzamenti ai tuoi tipi di post personalizzati. Esiste però una soluzione semplice: vai nelle impostazioni di WordPress/permalink e prendi nota dell'impostazione corrente (la mia era 'nome del post'). Quindi torna alle impostazioni predefinite, clicca 'salva', poi torna all'impostazione precedente e salva di nuovo. Hai appena risolto i problemi di reindirizzamento.
Passo 3 - Rinomina i Template dei Tipi di Post Personalizzati nel Tuo Tema
Se sei come me e hai creato template personalizzati per i tipi di post, dovrai rinominarli altrimenti i tuoi post personalizzati appariranno scomposti. Accedi al tuo tema e trova tutti i file che contengono il vecchio nome del tipo di post nel loro nome file e rinominali utilizzando il nuovo nome. Ad esempio, ho dovuto cambiare single-project-portfolio.php
in single-before-after.php
quando ho modificato il mio tipo di post da project-portfolio
a before-after
.
Passo 5 - Aggiorna Qualsiasi Codice
Esegui una ricerca e sostituzione file per il vecchio nome del tipo di post personalizzato nella cartella del tema e dei plugin. Nel mio caso, avevo diversi shortcode personalizzati che dipendevano dalla decisione se stavo utilizzando uno dei miei tipi di post personalizzati.
Testa Tutto
Problemi Potenziali (leggi prima di iniziare questa procedura)
Problemi di SincronizzazioneSe i tuoi tipi di post personalizzati erano sincronizzati, tieni presente che la tua ricerca e sostituzione iniziale modificherà anche i GUID dei tuoi post, il che costringerà tutti gli abbonati a vedere i vecchi post come nuovi. Non ho dovuto affrontare questo problema, ma se ne hai bisogno, considera di scegliere manualmente le tabelle che lo strumento safesearch elabora, quindi aggiorna manualmente qualsiasi dato non serializzato utilizzando la seguente query:
SET `post_type` = REPLACE(`post_type`,'vecchio_tipo_post','nuovo_tipo_post')
WHERE `post_type` LIKE '%vecchio_tipo_post%';

molto utile elencare tutto questo. tranne che la query SQL alla fine non è completa, poiché hai dimenticato il guid, ma sono elencati nella risposta di Will. inoltre non utilizzerei WHERE 'post_type' LIKE '%old_post_type%'
, userei WHERE 'post_type' = 'old_post_type'
, poiché il tuo metodo potrebbe anche causare la modifica di altri tipi di post..

Se non hai ancora articoli nel tuo portfolio.
Sarebbe molto semplice. Rinomina tutto ciò che è "Portfolio" in "Progetti". Non perderai nulla e cambierai solo il nome.
Modifica:
Prova a utilizzare questo plugin http://wordpress.org/extend/plugins/ptypeconverter/ per esportare i post attuali in modo sicuro e importarli nel tuo nuovo custom post type.
Quindi i passaggi sono:
1 Scarica e usa il plugin: http://wordpress.org/extend/plugins/ptypeconverter/
2 Copia il tuo file del custom post type "portfolio" in un posto sicuro. Chiamalo ad esempio portfolio_post_typeBACKUP.php
3 Ora sei sicuro che, se questo metodo fallisce, potrai recuperarlo.
4 Cambia "portfolio" in "projects"
5 Importa i post con il plugin e voilà!
Spero che funzioni.

Ah, scusa, avrei dovuto specificare. Ci sono già molti post nella categoria portfolio
.

questo plugin non funziona più correttamente. L'ho provato e non ha modificato tutti i tipi di post 'vecchi'. Ma la soluzione MySQL (risposta di Will) funziona bene.

Non ho abbastanza reputazione per commentare quindi scriverò qui. Estendendo l'esempio di Will, ho cambiato i LIKE con "=" e ho fatto puntare entrambi alla clausola WHERE post_type
UPDATE `wp_posts`
SET `guid` = REPLACE(`guid`,'old_post_type','new_post_type')
WHERE `post_type` = 'old_post_type'
UPDATE `wp_posts`
SET `post_type` = REPLACE(`post_type`,'old_post_type','new_post_type')
WHERE `post_type` = 'old_post_type'
Ricordatevi inoltre di andare in Admin > Impostazioni > Permalinks e cliccare su "Salva modifiche". Altrimenti i vostri collegamenti potrebbero non funzionare.
Dovrete anche modificare i nomi dei template 'single-post-type'.
Questo dovrebbe essere tutto ciò che dovete fare.
