Enregistrement d’une image à partir du Front-End dans la médiathèque WordPress

Enregistrement d’une image à partir du Front-End dans la médiathèque WordPress

Nous allons présenter une méthode afin de mettre en ligne un fichier (dans notre cas une image) pour un post (contenu) donné.

Cet article va donner les sources pour le réaliser de manière dite « manuel », sinon vous pouriez très bien utiliser des outils comme :

  • CMB2 — Framework de formulaires
  • Pods — Framework plus orienté sur les objets WordPress (contenu personnalisé ou Custom Post Type, taxonomie, etc.) et la possibilité d’étendre un objet avec des tables spécifiques.
  • ou encore ACF (plus besoin de le citer).

 

Pour notre exemple, nous allons partir du principe :

  • Nous avons un espace personnel pour les membres connectés en front-office,
  • Que nous voulons éditer l’image à la une d’un post (lié bien sur à l’utilisateur),
  • L’image uploadée (téléchargée) remplacera l’image actuelle (s’il y en a une) et la supprimera,
  • L’image n’aura qu’une miniature (medium),
  • L’image sera stockée dans un répertoire spécifique,
  • L’image aura un nom imposée sur le serveur (id du post).

 

Le formulaire

Bien sur, ça commence par un formulaire. Donc là on ne va pas s’embêter, on vas se concentrer sur ce qui nous intéresse : l’image. Pas de champs superflus, par contre je laisse les champs de test comme :

  • les nonces bien sûr,
  • l’information du post a modifier ($post_id),
  • un champ action pour déclencher le processus de sauvegarde,
  • l’identifiant de l’utilisateur (post_author) et le type de post (post_type) pour des raison de sécurité.

Vous noterez que nous passons par admin-post.php pour le script de mise à jour.

Vous pouvez aussi mettre le formulaire dans un shortcode afin de le placer dans le contenu d’une page.

(Code à placer dans le thème)

[pastacode lang= »php » manual= »%3C%3Fphp%20%24post_id%20%3D%20%7Bon%20r%C3%A9cup%C3%A8re%20l’identifiant%20du%20post%7D%3B%20%3F%3E%0A%3C%3Fphp%20%24action%20%3D%20’edit-moncpt’%3B%20%3F%3E%0A%3C%3Fphp%20%24current_user%20%3D%20wp_get_current_user()%3B%20%3F%3E%0A%3Cform%20name%3D%22post%22%20action%3D%22%3C%3Fphp%20echo%20admin_url(%20’admin-post.php’%20)%3B%20%3F%3E%22%20method%3D%22post%22%20id%3D%22edit-cpt%22%20enctype%3D%22multipart%2Fform-data%22%3E%0A%0A%09%3C%3Fphp%20echo%20get_the_post_thumbnail(%20%24post_id%2C%20’medium’%20)%3B%20%3F%3E%0A%09%0A%09%3Cinput%20type%3D%22file%22%20name%3D%22image%22%20id%3D%22image%22%20accept%3D%22image%2Fpng%2C%20image%2Fjpeg%22%3E%0A%09%09%0A%09%3C%3Fphp%0A%09%2F**%0A%09*%20Autres%20champs%20de%20formulaire%20%C3%A0%20impl%C3%A9menter%20si%20besoin%0A%09*%2F%0A%09%3F%3E%0A%09%3Cinput%20name%3D%22post_id%22%20id%3D%22post_id%22%20type%3D%22hidden%22%20value%3D%22%3C%3Fphp%20echo%20%24post_id%3B%20%3F%3E%22%3E%0A%09%3Cinput%20name%3D%22action%22%20id%3D%22action%22%20type%3D%22hidden%22%20value%3D%22%3C%3Fphp%20echo%20%24action%3B%20%3F%3E%22%3E%0A%09%3Cinput%20name%3D%22post_author%22%20id%3D%22post_author%22%20type%3D%22hidden%22%20value%3D%22%3C%3Fphp%20echo%20%24current_user-%3EID%3B%3F%3E%22%3E%0A%09%3Cinput%20name%3D%22post_type%22%20id%3D%22post_type%22%20type%3D%22hidden%22%20value%3D%22cpt-slug%22%3E%0A%09%3C%3Fphp%0A%09wp_nonce_field(%20%24action%20)%3B%0A%09wp_original_referer_field(%20true%20)%3B%0A%09%3F%3E%0A%09%3Cinput%20type%3D%22submit%22%20accesskey%3D%22p%22%20value%3D%22Submit%22%20class%3D%22button%22%20id%3D%22publish%22%20name%3D%22publish%22%3E%0A%09%09%0A%3C%2Fform%3E » message= »Formulaire » highlight= » » provider= »manual »/]

 

Script de mise à jour du formulaire

(Le code PHP qui suit est à placer soit dans un plugin, soit dans le fichier function.php du thème, soit dans un mu-plugin)

admin_post

Tout d’abord il faut enregistrer le hook avec admin_post_{$action} pour le déclenchement du processus de mise à jour.

Il faut savoir que ce hook ne se déclenche que pour les utilisateurs connectés, sinon il faut utiliser admin_post_nopriv_{action}. Je vous renvois donc vers la documentation de admin_post_action et admin_post_nopriv_action pour plus d’infos.

[pastacode lang= »php » manual= »%3C%3Fphp%0Aadd_action(‘admin_post_edit_moncpt’%2C%20’ctw_front_edit_moncpt’)%3B%0A%3F%3E » message= »admin_post{$action} » highlight= » » provider= »manual »/]

 

ctw_front_edit_moncpt

C’est la fonction qui va enregistrer les informations de mise à jour du post.

On commence par les tests de sécurité puis par une mise à jour du post.

Si le la mise à jour fonctionne, on passe au téléchargement de notre image avec la fonction ctw_front_image_upload(). On récupère l’identifiant de l’image en tant que type attachement pour l’affecter au post.

Nous finissons avec la mise à jour du de la méta donnée _edit_last pour tracer qui a fait la modification.

[pastacode lang= »php » manual= »%3C%3Fphp%0A%2F**%0A%20*%20Permet%20la%20mise%20%C3%A0%20jour%20de%20moncpt%20%C3%A0%20partir%20du%20front%0A%20*%20%40return%20void%0A%20*%2F%0Afunction%20ctw_front_edit_moncpt()%7B%0A%0A%09if(%20(defined(%20’DOING_AUTOSAVE’%20)%0A%09%09%26%26%20DOING_AUTOSAVE%20)%0A%09%09%7C%7C%20empty(%24_POST)%20)%0A%09%09%09return%3B%0A%0A%09%24current_user%20%3D%20wp_get_current_user()%3B%0A%0A%09%24nonce_security%20%3D%20true%3B%0A%09%24result%20%3D%20false%3B%0A%09%0A%09global%20%24post%3B%0A%09%24post_id%20%3D%20%24_POST%5B’post_id’%5D%3B%0A%09%24post%20%3D%20get_post(%24post_id)%3B%0A%0A%09if%20(%20!wp_verify_nonce(%20%24_POST%5B’_wpnonce’%5D%2C%20’edit-moncpt’%20)%20)%0A%09%09%24nonce_security%20%3D%20false%3B%0A%0A%09%2F**%0A%09*%20ctw_current_user_can()%09Fonction%20de%20s%C3%A9curit%C3%A9%20maison%20pour%20v%C3%A9rifier%20les%20droits%20(ne%20sera%20pas%20d%C3%A9velopper%20dans%20cet%20article)%0A%09*%2F%20%0A%09if%20(‘POST’%20%3D%3D%20%24_SERVER%5B’REQUEST_METHOD’%5D%0A%09%09%09%26%26%20%24nonce_security%0A%09%09%09%26%26%20%24post-%3Epost_type%20%3D%3D%20%24_POST%5B’post_type’%5D%09%09%09%2F%2F%20Contr%C3%B4le%20post%0A%09%09%09%26%26%20%24current_user-%3EID%20%3D%3D%20%24_POST%5B’post_author’%5D%09%09%2F%2F%20Contr%C3%B4le%20s%C3%A9curit%C3%A9%20maison%20concernant%20le%20post%2C%20d%C3%A9pend%20des%20projets%0A%09%09%09%26%26%20ctw_current_user_can(%20’edit-moncpt’%2C%20%24post_id%20)%09%0A%09%09%09)%7B%0A%0A%09%09%09%24d%20%3D%20current_time(%20’mysql’%20)%3B%0A%0A%09%09%09%2F%2F%20Mise%20%C3%A0%20jour%20du%20CPT%0A%09%09%09%24result%20%3D%20wp_update_post(%20array(%0A%09%09%09%09’ID’%09%09%09%09%3D%3E%20%24_POST%5B’post_id’%5D%2C%0A%09%09%09%09’post_modified’%09%09%3D%3E%20%24d%2C%0A%09%09%09)%2C%20true)%3B%0A%0A%09%7D%0A%0A%09%24message_return%20%3D%20array()%3B%0A%0A%09if%20(%20is_wp_error(%24result)%20)%20%7B%0A%0A%09%09%24errors%20%3D%20%24result-%3Eget_error_messages()%3B%0A%09%09foreach%20(%24errors%20as%20%24error)%20%7B%0A%09%09%09echo%20%24error%3B%0A%09%09%7D%0A%09%09%24message_return%5B’save’%20%5D%20%3D%20’ko’%3B%0A%09%7D%0A%09else%7B%0A%0A%09%09%2F%2F%20Affecte%20comme%20nom%20d’image%2C%20le%20nom%20du%20post%0A%09%09%2F%2F%20Attention%3A%20ne%20pas%20d%C3%A9clarer%20%24post_data%20%3D%20null%20%0A%09%09%24post_data%20%3D%20array(‘post_title’%20%3D%3E%20%24post-%3Epost_title)%3B%0A%09%09%0A%09%09%2F%2F%20Traitement%20de%20l’Image%0A%09%09%24img_id%20%3D%20ctw_front_image_upload(%20’image’%2C%20%24post_id%2C%20%24post_data%20)%3B%0A%0A%09%09%2F%2F%20If%20our%20photo%20upload%20was%20successful%2C%20set%20the%20featured%20image%0A%09%09if%20(%20%24img_id%20%26%26%20!%20is_wp_error(%20%24img_id%20)%20)%20%7B%0A%09%09%09%24r%20%3D%20set_post_thumbnail(%20%24post_id%2C%20%24img_id%20)%3B%0A%09%09%7D%0A%0A%09%09%2F**%0A%09%09*%20Autre%20champ%20de%20formulaire%20%C3%A0%20traiter%20si%20besoin%0A%09%09*%2F%0A%09%09%0A%09%09%2F%2F%20Mise%20%C3%A0%20jour%20identifiant%20derni%C3%A8re%20modification%0A%09%09update_post_meta(%20%24post_id%2C%20’_edit_last’%2C%20%24current_user-%3EID%20)%3B%0A%09%09%24message_return%5B’save’%20%5D%20%3D%20’ok’%3B%0A%09%7D%0A%0A%09%24go_to_edit_cpt%20%3D%20add_query_arg(%20%24message_return%2C%20%24_POST%5B’_wp_http_referer’%5D%20)%3B%0A%09wp_redirect(%20%24go_to_edit_cpt%20)%3B%0A%7D%0A%0Afunction%20ctw_current_user_can(%20%24context%2C%20%24post_id%20)%09%7B%0A%09%2F**%0A%09*%20Contraintes%20sp%C3%A9cifique%20au%20projet%0A%09*%2F%0A%09return%20true%3B%0A%7D%0A%3F%3E » message= »Update moncpt » highlight= » » provider= »manual »/]

 

Upload de l’image et création du post attachement

La fonction va tout d’abord vérifier la variable $_FILES, puis nous allons une série de hook (détail au paragraphe suivant) non exhaustif que nous allons nous servir pour répondre à nos critères.

Et ensuite nous utilisons la fonction media_handle_upload() qui uploader l’image et nous retourner l’identifiant du contenu créé pour l’image.

[pastacode lang= »php » manual= »%3C%3Fphp%0A%2F**%0A%20*%20Handles%20uploading%20a%20file%20to%20a%20WordPress%20post%0A%20*%0A%20*%20%40param%09string%09%24field_id%09%09Nom%20du%20champ%20dans%20les%20donn%C3%A9es%20%24_POST%20%0A%20*%20%40param%09int%09%09%24post_id%09%09Post%20ID%0A%20*%20%40param%09array%09%24post_data%20%09%09Donn%C3%A9e%20du%20post%20a%20ajouter%20%C3%A0%20l’image%0A%20*%2F%0Afunction%20ctw_front_image_upload(%20%24field_id%2C%20%24post_id%2C%20%24post_data%20%3D%20array()%20)%20%7B%0A%0A%09%2F%2F%20Contr%C3%B4le%20sur%20la%20variable%20%24_FILES%0A%09if%20(%0A%09%09empty(%20%24_FILES%20)%0A%09%09%7C%7C%20!%20isset(%20%24_FILES%5B%24field_id%5D%20)%0A%09%09%7C%7C%20isset(%20%24_FILES%5B%24field_id%5D%5B’error’%5D%20)%20%26%26%200%20!%3D%3D%20%24_FILES%5B%24field_id%5D%5B’error’%5D%0A%09)%20%7B%0A%09%09return%3B%0A%09%7D%0A%09%24files%20%3D%20array_filter(%20%24_FILES%5B%24field_id%5D%20)%3B%0A%09if%20(%20empty(%20%24files%20)%20)%20%7B%0A%09%09return%3B%0A%09%7D%0A%09%0A%09%2F**%0A%09%20*%20Suppression%20du%20thumbsnail%20pr%C3%A9c%C3%A9dent%20(l’image%20sera%20supprim%C3%A9%20du%20serveur)%0A%09%20*%2F%0A%09if%20(%20isset(%20%24post_id%20)%20)%20%7B%0A%09%09wp_delete_attachment(%20get_post_thumbnail_id(%20%24post_id%20)%2C%20true%20)%3B%0A%09%7D%0A%0A%09%2F**%0A%09%20*%20Filtre%20execut%C3%A9%20en%20premier%20et%20comme%20param%C3%A8tre%20les%20infos%20du%20fichiers%0A%09%20*%2F%0A%09add_filter(%20’wp_handle_upload_prefilter’%2C%20’ctw_file_change_default_name’%2C%2010%2C1%20)%3B%0A%0A%09%2F**%0A%09%20*%20Filtre%20%C3%A0%20la%20cr%C3%A9ation%20du%20nom%20du%20fichier%20%0A%09%20*%2F%0A%09add_filter(%20’wp_unique_filename’%2C%20’ctw_file_unique_filename’%2C%2010%2C4%20)%3B%0A%09%0A%09%2F**%0A%09%20*%20Filtre%20sur%20le%20r%C3%A9pertoire%20de%20destination%0A%09%20*%2F%0A%09add_filter(%20’upload_dir’%2C%20’ctw_image_resize’%2C%2010%2C1%20)%3B%0A%09%0A%09%2F**%0A%09%20*%20Filtre%20%C3%A0%20la%20fin%20de%20la%20fonction%20de%20chargement%20de%20l’image%0A%09%20*%2F%0A%09add_filter(%20’wp_handle_upload’%2C%20’ctw_image_resize’%2C%2010%2C2%20)%3B%0A%0A%09%2F**%0A%09%20*%20Filtre%20le%20format%20des%20miniatures%20%C3%A0%20r%C3%A9aliser%20suite%20au%20chargement%0A%09%20*%2F%0A%09add_filter(%20’intermediate_image_sizes’%2C%20’ctw_change_image_size’%2C%2010%2C1%20)%3B%0A%0A%09%2F%2F%20Si%20jamais%20ce%20script%20n’est%20pas%20%C3%A9x%C3%A9cut%C3%A9%20dans%20admin-post.php%2C%20il%20faut%20s’assurer%20que%20nous%20avons%20les%20bonnes%20fonctions%0A%09if%20(%20!%20function_exists(%20’media_handle_upload’%20)%20)%20%7B%0A%09%09require_once(%20ABSPATH%20.%20’wp-admin%2Fincludes%2Fimage.php’%20)%3B%0A%09%09require_once(%20ABSPATH%20.%20’wp-admin%2Fincludes%2Ffile.php’%20)%3B%0A%09%09require_once(%20ABSPATH%20.%20’wp-admin%2Fincludes%2Fmedia.php’%20)%3B%0A%09%7D%0A%09%2F%2F%20Upload%20le%20fichier%20et%20renvoit%20l’identifiant%20d’attachement%0A%09return%20media_handle_upload(%20%24field_id%2C%20%24post_id%2C%20%24post_data%20)%3B%0A%7D%0A%3F%3E » message= »Upload de l’image  » highlight= » » provider= »manual »/]

 

Les fonctions appelées par les hook de configuration

Ces différents hook permettent de configurer le nom, la / les  taille(s) et le dossier de stockage des images.

Vous remarquerez que pour redimensionner une image, nous utilisons la fonction wp_get_image_editor() qui renvoit un objet WP_Image_Editor. Cette classe est très pratique pour la transformation d’image.

 

[pastacode lang= »php » manual= »%3C%3Fphp%0A%2F**%0A%20*%20Change%20le%20nom%20du%20fichier%20par%20le%20nom%20g%C3%A9n%C3%A9rique%20que%20nous%20voulons%20lui%20donner%0A%20*%2F%0Afunction%20ctw_file_change_default_name(%24file)%7B%0A%09global%20%24post%3B%0A%0A%09switch%20(%24file%5B’type’%5D)%20%7B%0A%09%09case%20’image%2Fgif’%3A%20%09%24ext%20%3D%20′.gif’%3B%20break%3B%0A%09%09case%20’image%2Fpng’%3A%20%09%24ext%20%3D%20′.png’%3B%20break%3B%0A%09%09default%3A%09%09%09%24ext%20%3D%20′.jpg’%3B%20break%3B%0A%09%7D%0A%0A%09%24file%5B’name’%5D%20%3D%20%24post-%3Ewp_post_id.%24ext%3B%0A%09return%20%24file%3B%0A%7D%0A%0A%2F**%0A%20*%20Renvois%20le%20nom%20du%20fichier%20et%20le%20renvois%20le%20nom%20sans%20chiffres%20si%20jamais%20il%20y%20a%20un%20doublon%20de%20nom%0A%20*%20Ce%20filtre%20n’a%20pas%20vraiment%20d’utilit%C3%A9%20car%20le%20nom%20nous%20l’avons%20d%C3%A9j%C3%A0%20chang%C3%A9%20dans%20le%20hook%20pr%C3%A9c%C3%A9dent%2C%0A%20*%20et%20nous%20n’aurons%20pas%20de%20doublons%20car%20nous%20avons%20supprim%C3%A9%20le%20fichier%20affect%C3%A9%20au%20post.%20%0A%20*%20Mais%20il%20est%20int%C3%A9ressant%20de%20le%20connaitre%20si%20jamais%20le%20compteur%20par%20d%C3%A9faut%20ne%20vous%20convient%20pas.%0A%20*%2F%0Afunction%20ctw_file_unique_filename(%24filename%2C%20%24ext%2C%20%24dir%2C%20%24callback)%7B%0A%09global%20%24post%3B%0A%09return%20%24post-%3EID%20.%20%24ext%3B%0A%7D%0A%0A%2F**%0A%20*%20Redimensione%20l’image%20l’original%20afin%20qu’elle%20ne%20soit%20pas%20trop%20lourde%0A%20*%2F%0Afunction%20ctw_image_resize(%24file%2C%20%24action)%7B%0A%09%24image%20%3D%20wp_get_image_editor(%20%24file%5B’file’%5D%20)%3B%0A%09if%20(%20!%20is_wp_error(%20%24image%20)%20)%7B%0A%09%09%2F%2F%20Nous%20d%C3%A9finissons%20i%C3%A7i%20une%20largeur%20et%20hauteur%20maximale%20de%20800%20pixels%0A%09%09%24res%20%3D%20%24image-%3Eresize(%20800%2C%20800%20)%3B%0A%09%7D%0A%09if(%20%24res%20)%7B%0A%09%09%24image-%3Esave(%20%24file%5B’file’%5D%20)%3B%0A%09%7D%0A%0A%09return%20%24file%3B%0A%7D%0A%0A%2F**%0A%20*%20Change%20le%20r%C3%A9pertoire%20par%20d%C3%A9faut%20de%20stockage%20des%20images%0A%20*%2F%0Afunction%20ctw_moncpt_image_directory(%24upload_dir)%7B%0A%09global%20%24post%3B%0A%09%0A%09%24upload_dir%5B’subdir’%5D%20%3D%20%22%2Frepertoire-moncpt%2F%22%3B%0A%09%24upload_dir%5B’path’%5D%20%3D%20%24upload_dir%5B’basedir’%5D.%24upload_dir%5B’subdir’%5D%3B%0A%09%24upload_dir%5B’url’%5D%20%3D%20%24upload_dir%5B’baseurl’%5D.%24upload_dir%5B’subdir’%5D%3B%0A%09%0A%09return%20%24upload_dir%3B%0A%7D%0A%0A%2F**%0A%20*%20Change%20intermediate_image_sizes%20pour%20ne%20lister%20que%20les%20types%20de%20formats%20d%C3%A9sir%C3%A9s%0A%20*%20function%20get_intermediate_image_sizes()%20in%20wp-includes%2Fmedia.php%0A%20*%2F%0Afunction%20ctw_change_image_size(%24image_sizes)%7B%0A%09%2F%2F%20On%20ne%20cr%C3%A9era%20que%20le%20format%20’medium’%20en%20plus%20de%20l’original%0A%09return%20array(‘medium’)%3B%0A%7D%0A%3F%3E » message= »Hook de personnalisation du upload » highlight= » » provider= »manual »/]

Conclusion

J’ai passé pas mal de temps avant de réussir a trouver les bon hook en épluchant la doc et le code WordPress. En définitif lorsque nous avons les bons exemples, le travail est plus aisé, d’ou le but de mon article sur ce sujet.


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *