web-dev-qa-db-fra.com

Supprimer automatiquement les champs personnalisés vides

Le code que vous voyez ci-dessous ne fonctionne que parfois. Je ne suis pas un pro sur PHP alors quelqu'un peut-il m'aider à améliorer ce code? Je l'utilise dans mon fichier functions-php dans ma configuration wordpress mu.

Le plus gros problème est qu'il ne supprimera pas les fichiers en double. c'est-à-dire si j'ai 2 champs personnalisés nommés Image et qu'un est vide, je veux que ce script supprime ce champ vide, mais cela ne fonctionne pas

add_action('save_post','my_cf_check');
function my_cf_check($post_id) {

    // verify this is not an auto save routine. 
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;

    //authentication checks
    if (!current_user_can('edit_post', $post_id)) return;

    //obtain custom field meta for this post
     $custom_fields = get_post_custom($post_id);

    if(!$custom_fields) return;

    foreach($custom_fields as $key=>$custom_field):
        //$custom_field is an array of values associated with $key - even if there is only one value. 
        //Filter to remove empty values.
        //Be warned this will remove anything that casts as false, e.g. 0 or false 
        //- if you don't want this, specify a callback.
        //See php documentation on array_filter
        $values = array_filter($custom_field);

        //After removing 'empty' fields, is array empty?
        if(empty($values)):
            delete_post_meta($post_id,$key); //Remove post's custom field
        endif;
    endforeach; 
    return;
} 
2
Demilio

Je crois que c'était ma solution à une question précédente que vous aviez.

J'ai mentionné dans cette réponse que le code ne traitait pas de l'éventualité d'une clé avec plusieurs valeurs et dont certaines sont vides. La raison en est que WordPress traite delete_post_meta ...

Lorsque vous utilisez delete_post_meta, les deux premiers arguments spécifient la publication et la clé du champ personnalisé. Vous avez un troisième argument facultatif, qui peut être utilisé pour spécifier une paire clé-valeur. Alors...

//Delete all post meta with key $key    
delete_post_meta($post_id,$key)
//Delete all post meta with key $key AND value $value
delete_post_meta($post_id,$key,$value)

Le problème est que si $value est vide, il le traite comme le premier cas et supprime toutes les méta de publication pour cette publication et cette clé.

Il existe une solution de contournement (et une solution non basée sur WordPress serait peut-être plus efficace ici), la logique est la suivante.

  • Identifier une clé avec une valeur vide
  • Récupérer toutes les valeurs non vides
  • Supprimer la clé
  • Réinsérez la clé en ajoutant uniquement des valeurs non vides

La boucle foreach modifiée;

foreach($custom_fields as $key=>$values):
    //$values is an array of values associated with $key - even if there is only one value. 
    //Filter to remove empty values.
    //Be warned this will remove anything that casts as false, e.g. 0 or false 
    //- if you don't want this, specify a callback.
    //See php documentation on array_filter
    $nonemptyvalues = array_filter($values);

    //If the $nonemptyvalues doesn't match $values then we removed an empty value(s).
    if($nonemptyvalues!=$values):
         //delete key
         delete_post_meta($post_id,$key);

         //re-add key and insert only non-empty values
         foreach($nonemptyvalues as $nonemptyvalue){
             add_post_meta($post_id,$key,$nonemptyvalue);
         }
    endif;  
endforeach;

Ce qui précède n'a pas été testé

1
Stephen Harris

Voyez ce que vous en pensez:

add_action('save_post','my_cf_check');
function my_cf_check($post_id) {

    // verify this is not an auto save routine. 
    if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;

    //authentication checks
    if (!current_user_can('edit_post', $post_id)) return;

    //obtain custom field meta for this post
    $custom_fields = get_post_custom($post_id);

    if( !$custom_fields ) return;

    foreach ( $custom_fields as $key => $val_arr ):

        if ( empty($val_arr) )
            delete_post_meta($post_id, $key); // if it's empty, delete the field.

        elseif ( is_array($val_arr) && 1 < count($val_arr) ) {

            foreach ($val_arr as $value) {
                // check each value, and delete the post meta if it's empty
                if ( empty( $value ) )
                    delete_post_meta($post_id, $key, $value);

            }

        } else {
            // it's an array with a single non-empty value, or it's a non-empty string
        }

    endforeach;

} 
0
Evan Mattson