Tillat brukere å sende inn bilder til WordPress-siden din

I denne opplæringen lærer du hvordan du lager et plugin som lar brukerne sende inn bilder og laste dem opp til WordPress-mediebiblioteket. Du lærer også hvordan du sletter bilder på WordPress-mediebiblioteket, og gjør noen grunnleggende validering på opplastede bilder.


Tidligere…

Denne opplæringen er på forespørsel fra noen brukere som fant mine citater plugin tutorial interessant, men var spesielt opptatt av å finne ut hvordan samme teknikk kan brukes til å laste opp bilder fra frontend. Så her er en gjentagelse av den opplæringen som bare gjør det. For detaljerte opplysninger om plugin-oppsett, kortkoder og nonces, se den forrige opplæringen.

Pluggen vil:

  • vis et bildeopplastingsskjema ved hjelp av en kortkode
  • godta kun bilder av en bestemt type og maksimal størrelse
  • Legg til en egendefinert innleggstype for brukerbilder
  • legg til bilder i WordPress mediebiblioteket med en skikkelig vedleggstekst
  • Vis upubliserte bilder
  • la brukerne slette sine upubliserte bilder

Vi vil bruke det innebygde WordPress-innlegget miniatyrbildet (aka Featured Image) -meta-feltet for å holde bildet for hvert innlegg. Dette gjør det også lettere å vise og jobbe med bildet vårt, da vi kan bruke post_thumbnail-funksjonene.

Her er det vi satser på:

All kode er tilgjengelig i plugin-kilden øverst i denne opplæringen.


Trinn 1 Sett opp pluggen

Opprett en pluginfil med navnet submit_user_images.php i wp-content / plugins / sender-user-bilder katalog.

Se plugin-kilden for plugin header info.


Trinn 2 Plugin Initialization Funksjon

Vi skal lage en egendefinert posttype som heter user_images for å holde våre brukerbilder og en tilpasset taksonomi navngitt user_image_category. Dette vil muliggjøre renere administrasjon av bildene enn bare å tildele dem til vanlige innlegg og kategorier.

Den innledende kroken og funksjonen

Vi bruker følgende initialiseringskode for å lage vår egendefinerte innleggstype og egendefinert taksonomi:

 add_action ('init', 'sui_plugin_init'); funksjonen sui_plugin_init () $ image_type_labels = array ('name' => _x ('Brukerbilder', 'posttype generalt navn'), 'singular_name' => _x ('Brukerbilde', 'posttype entallnavn'), 'add_new' => _x ('Legg til nytt brukerbilde', 'bilde'), 'add_new_item' => __ ('Legg til nytt brukerbilde'), 'edit_item' => __ ('Rediger brukerbilde'), 'new_item '=> __ (' Legg til nytt brukerbilde '),' all_items '=> __ (' Vis brukerbilder '),' view_item '=> __ (' Vis brukerbilde '),' search_items '=> __ Brukernavn '=' 'Not_found' => __ ('Ingen brukerbilder funnet'), 'not_found_in_trash' => __ ('Ingen brukerbilder funnet i Papirkurv'), 'parent_item_colon' => ", 'menu_name' => ' Brukerbilder '); $ image_type_args = array (' labels '=> $ image_type_labels,' public '=> true,' query_var '=> true,' rewrite '=> true,' capability_type '=>' innlegg ',' has_archive '=' true 'hierarchical' => false, 'map_meta_cap' => true, 'menu_position' => null, 'støtter' => array ('tittel', 'editor', 'author', 'miniatyrbilde')) ; register_post_type ('user_images', $ image_type_args); $ image_catego ry_labels = array ('name' => _x ('User Image Categories', 'Taxonomy General Name'), 'singular_name' => _x ('Brukerbilde', 'Taxonomy Singular Name'), 'search_items' => __ 'Search User Image Categories'), 'all_items' => __ ('Alle brukerbildekategorier'), 'parent_item' => __ ('Parent User Image Category'), 'parent_item_colon' => __ ('Parent User Image Category : '' Edit_item '=> __ (' Rediger brukerbildekategori '),' update_item '=> __ (' Oppdater brukerbildekategori '),' add_new_item '=> __ (' Legg til ny brukerbildekategori ') 'new_item_name' => __ ('Ny bruker bilde navn'), 'menu_name' => __ ('User Image Categories'),); $ image_category_args = array ('hierarchical' => true, 'labels' => $ image_category_labels, 'show_ui' => sant, 'query_var' => true, 'rewrite' => array ('slug' => 'user_image_category') ,); register_taxonomy ('sui_image_category', array ('user_images'), $ image_category_args); $ default_image_cats = array ('humor', 'landskaper', 'sport', 'folk'); foreach ($ default_image_cats as $ cat) hvis (! term_exists ($ cat, 'sui_image_category')) wp_insert_term ($ cat, 'sui_image_category'); 

Hva denne koden gjør:

  • bruker WordPress init action hook for å ringe en plugin initialiseringsfunksjon
  • registrerer en egendefinert innleggstype kalt user_images
  • registrerer en egendefinert taksonomi navngitt user_image_category og tildeler den til posten type user_images
  • legger til noen standardkategorier i user_image_category taksonomi hvis de ikke allerede eksisterer

Vi vil nå ha en User Images-meny i admin-dashbordet og en måte å administrere brukerbilder og deres kategorier på.


Trinn 3 Konfigurer noen standardinnstillinger

Vi må gjøre noen grunnleggende validering, så la oss definere to konstanter for senere bruk:

 definer ('MAX_UPLOAD_SIZE', 200000); define ('TYPE_WHITELIST', serialize (array ('image / jpeg', 'image / png', 'image / gif')));

Trinn 4 Definer en kortkode

Vi definerer en kortkode som gjør det mulig for oss å vise (og behandle) brukerens innleveringsskjema i et innlegg eller en side:

 add_shortcode ('sui_form', 'sui_form_shortcode');

Sikkerhet

Fordi pluginet aksepterer data fra brukeren, implementerer vi følgende sikkerhetsmekanismer:

  • Kun innloggede brukere har tilgang til skjemaet for innlevering av bilde
  • Vi bruker nonces for å verifisere at skjemaene ble generert av vårt plugin
  • bilder blir sendt inn ved hjelp av wp_insert_post som sanitiserer dataene før de lagres i databasen
  • Brukerne kan bare se sine egne bilder, og ikke hindre dem fra å slette andre brukeres bildeinnlegg

Trinn 5 Hovedfunksjonen

Dette er funksjonen kalt av vår kortkode. Den viser og behandler skjemaet for innlevering av bilde og bildeliste / slettingsskjema. Vi tar den i bitbitbiter og i trinn 6 ser vi på hjelperfunksjonene.

 funksjon sui_form_shortcode () if (! is_user_logged_in ()) return '

Du må være logget inn for å sende inn et bilde.

'; global $ current_user;
  • sjekk for å se om brukeren er logget inn
  • Ta tak i WordPress $ current_user-variabelen som vi trenger for å få vår bruker-ID
 $ resultat = sui_parse_file_errors ($ _ FILES ['sui_image_file'], $ _POST ['sui_image_caption']) ($ _POST ['sui_upload_image_form_submitted']) && wp_verify_nonce ($ _ POST ; hvis ($ resultat ['error']) echo '

FEIL: '. $ resultat ['feil']. '

'; andre $ user_image_data = array ('post_title' => $ resultat ['caption'], 'post_status' => 'venter', 'post_author' => $ current_user-> ID, 'post_type' => 'user_images') ; hvis ($ post_id = wp_insert_post ($ user_image_data)) sui_process_image ('sui_image_file', $ post_id, $ result ['caption']); wp_set_object_terms ($ post_id, (int) $ _ POST ['sui_image_category'], 'sui_image_category');
  • Hvis bildet skjemaet er sendt, vil det være et sui_upload_image_form_submitted felt som ble generert av vår wp_nonce_field-funksjon. Vi kan da verifisere nonce og fortsette å behandle det innsendte bildet
  • gjør noen validering ved å sende filinngangen (hvor de opplastede bildedataene er lagret) og bildetekstdata til en valideringsfunksjon, sui_parse_file_errors, og vise eventuelle returnerte feil
  • konstruere en matrise som stiller inn poststatusen (administrasjonen må nå godkjenne den til publisering), angi posttypen til user_images (vår egendefinerte innleggstype) og sette forfatteren av bildeposten til den innloggede brukeren som er innlogget.
  • Hvis bildeinnlegget ble lagt inn, lagrer du bildet i WordPress mediebiblioteket (sui_process_image) og endelig angir kategorien for bildeinnlegget og viser en suksessmelding
 hvis (isset ($ _POST ['sui_form_delete_submitted']) && wp_verify_nonce ($ _ POST ['sui_form_delete_submitted'], 'sui_form_delete')) hvis (isset ($ _ POST ['sui_image_delete_id'])) if ($ user_images_deleted = sui_delete_user_images $ _POST ['sui_image_delete_id'])) echo '

'. $ user_images_deleted. 'bilder (e) slettet!

';
  • Hvis bildet slett skjemaet er sendt, vil det være et sui_form_delete_submitted felt som ble generert av vår wp_nonce_field-funksjon. Vi kan da verifisere nonce og fortsette å behandle rekke bilder som er sjekket for sletting
  • Vi kontrollerer at vi faktisk har noen bilder sjekket for sletting ved å teste $ _POST ['sui_image_delete_id']. I så fall overfører vi dem til sui_delete_user_images-funksjonen (se trinn 6)
  • Hvis bilder ble slettet, viser vi en suksessmelding
 echo sui_get_upload_image_form ($ sui_image_caption = $ _POST ['sui_image_caption'], $ sui_image_category = $ _POST ['sui_image_category']); hvis ($ user_images_table = sui_get_user_images_table ($ current_user-> ID)) echo $ user_images_table; 
  • Vi utfører bildeopplastingsskjemaet
  • Til slutt sender vi bildeliste / slettingsskjema ved å sende bruker-ID til sui_get_user_images_table-funksjonen (se trinn 6)

Trinn 6 Hjelperfunksjoner

Her ser vi på funksjonene som genererer skjemaene, legger bildene til mediebiblioteket og funksjonen som sletter de valgte bildene.

 funksjon sui_get_upload_image_form ($ sui_image_caption = ", $ sui_image_category = 0) $ out ="; $ ut. = '
'; $ ut. = wp_nonce_field ('sui_upload_image_form', 'sui_upload_image_form_submitted'); $ ut. = '
'; $ ut. = '
'; $ ut. = '
'; $ ut. = sui_get_image_categories_dropdown ('sui_image_category', $ sui_image_category). '
'; $ ut. = '
'; $ ut. = '
'; $ ut. = ''; $ ut. = '
'; returner $ ut;
  • funksjonen aksepterer 2 valgfrie argumenter for omformering av skjemafeltene. Dette er en bekvemmelighet for brukeren.
  • Et nonce-felt er utdata som vi sjekker når skjemaet er sendt inn
  • vi lager en rullegardin for bildekategoriene ved å ringe sui_get_image_categories_dropdown (se neste funksjon)
 funksjonen sui_get_image_categories_dropdown ($ taksonomi, $ valgt) return wp_dropdown_categories (array ('taxonomy' => $ taksonomi, 'navn' => 'sui_image_category', 'selected' => $ valgt, 'hide_empty' => 0, 'echo' => 0)); 
  • funksjonen aksepterer 2 argumenter, inkludert element-ID for den valgte kategorien
  • vi bruker WordPress wp_dropdown_categories funksjonen til å lage en dropdown som viser bruker bildekategorier fra user_image_category taksonomi (vår tilpassede taksonomi)
 funksjon sui_get_user_images_table ($ user_id) $ args = array ('author' => $ user_id, 'post_type' => 'user_images', 'post_status' => 'venter'); $ user_images = ny WP_Query ($ args); Hvis (! $ user_images-> post_count) returnerer 0; $ out = "; $ out. = '

Dine upubliserte bilder - Klikk for å se full størrelse

'; $ ut. = '
'; $ ut. = wp_nonce_field ('sui_form_delete', 'sui_form_delete_submitted'); $ ut. = ''; $ ut. = ''; foreach ($ user_images-> innlegg som $ user_image) $ user_image_cats = get_the_terms ($ user_image-> ID, 'sui_image_category'); foreach ($ user_image_cats as $ cat) $ user_image_cat = $ cat-> navn; $ post_thumbnail_id = get_post_thumbnail_id ($ user_image-> ID); $ ut. = wp_nonce_field ('sui_image_delete_'. $ user_image-> ID, 'sui_image_delete_id_'. $ user_image-> ID, false); $ ut. = ''; $ ut. = ''; $ ut. = ''; $ ut. = ''; $ ut. = ''; $ ut. = ''; $ ut. = '
BildebildetekstKategoriSlett
'. wp_get_attachment_link ($ post_thumbnail_id, 'miniatyrbilde'). ''. $ user_image-> post_title. ''. $ user_image_cat. '
'; $ ut. = ''; $ ut. = '
'; returner $ ut;
  • godta bruker-ID fordi vi trenger å få en liste over brukerbilder bare for den nåværende brukeren
  • opprett $ args for å spesifisere brukeren, posttype user_images og brukerbilder som er ventende (ennå ikke publisert av admin)
  • Kjør et tilpasset søk ved hjelp av WP_Query
  • returner falsk hvis forespørselen returnerer ingen brukerbilder
  • start et skjema og generer en nonce for skjemaet
  • loop gjennom bildene innleggene sørger for at vi også ta tak i kategorien av bildeinnlegget
  • generere en nonce for bilde slette avmerkingsboksen, tildele et unikt navn for nonce ved å sammenkoble brukerens bilde post ID
  • skriv ut en tabellrad som inneholder bildeopplysningene samt et slettingsfelt

Hvorfor legge til en nonce for hvert bilde innlegg?

Skjemaer kan manipuleres i nettleseren for å sende tilbake uventede data. I vårt tilfelle er hver slette avmerkingsboksen tilordnet verdien av et innlegg. Men hva om en skadelig bruker endret den verdien og forårsaket vår slettingsfunksjon for å fjerne et innlegg som ikke var faktisk oppført?

En måte å unngå dette på er å bruke nonces for hver rad postdata, slik at nonces er unikt navngitt med postverdien som skal slettes. Vi bekrefter derfor ikke at du har skjemaet for å sikre at det er en ekte returverdi.

 funksjonen sui_delete_user_images ($ images_to_delete) $ images_deleted = 0; foreach ($ images_to_delete as $ user_image) hvis (isset ($ _ POST ['sui_image_delete_id_'. $ user_image]) &&wp_verify_nonce ($ _ POST ['sui_image_delete_id_'. $ user_image], 'sui_image_delete_'. $ user_image)) if post_thumbnail_id = get_post_thumbnail_id ($ user_image)) wp_delete_attachment ($ post_thumbnail_id);  wp_trash_post ($ user_image); $ images_deleted ++;  returnere $ images_deleted; 
  • funksjonen aksepterer en rekke bilde post-IDer for å slette
  • hver bildepost-ID er merket for å se om en nonce ble generert for den
  • Hvis nonce verifiserer, sletter vi bildevedlegget som eksisterer i mediebiblioteket ved å sende iden til bildet etter miniatyrbildet til WordPress-funksjonen wp_delete_attachment
  • Vi ødelegger også bildepostet ved hjelp av WordPress-funksjonen wp_trash_post

Men blir ikke miniatyrbildevedlegget slettet når innlegget blir søppel?

Nei, og det er fordi WordPress lagrer vedlegg som vanlige innlegg i postdatabase-tabellen. Ta en titt selv: alle vedleggene lagres i innleggstabellen med en posttype av vedlegg. Hvis du bare sletter et innlegg av typen user_images, slettes ikke miniatyrbilaget. Det forblir i mediebiblioteket for fremtidig bruk, med mindre vi spesifikt sletter det med wp_delete_attachment. For vårt formål trodde jeg det var best å fjerne vedlegget når brukerens innlegg ble slettet.


Trinn 7 Bildehåndteringsfunksjonene

La oss minne oss om hva resultatet av en HTML-filinngang ser ut når den legger inn et bilde på skriptet ditt:

 Array ([name] => ref_blind.jpg [type] => bilde / jpeg [tmp_name] => / tmp / php79xI4e [feil] => 0 [størrelse] => 106290)

Vi overfører den rekkefølgen til sui_process_image-funksjonen sammen med ID-en for den lagrede brukerbildepost og den santiserte bildeteksten.

 funksjonen sui_process_image ($ file, $ post_id, $ caption) require_once (ABSPATH. "wp-admin". '/includes/image.php'); require_once (ABSPATH. "wp-admin". '/includes/file.php'); require_once (ABSPATH. "wp-admin". '/includes/media.php'); $ attachment_id = media_handle_upload ($ file, $ post_id); update_post_meta ($ post_id, '_thumbnail_id', $ attachment_id); $ attachment_data = array ('ID' => $ attachment_id, 'post_excerpt' => $ bildetekst); wp_update_post ($ attachment_data); returnere $ attachment_id; 
  • Vi må inkludere WordPress-administrasjonsskriptene som håndterer bildeopplastinger bak kulissene
  • vi kaller media_handle_upload-funksjonen (som er en del av media.php), sender den opplastede filarrayen og post-ID
  • Nå har vi et vedleggs-ID som vi kan bruke med update_post_meta for å tilordne vedlegget til innlegget som dets miniatyrbilde. Merk: "_thumbnail_id" refererer til det interne miniatyrbildet (Featured Image) meta-feltet. Interne Wordpress-felt begynner med en understreking.
  • Vi bruker vedleggs-ID-en for å oppdatere bildeteksten av vedlegget ved hjelp av funksjonen wp_update_post

Fordi vedlegg er bare vanlige innlegg, hvis vi oppdaterer feltet post_excerpt for vedlegget, oppdaterer vi faktisk vedleggets tekstfelt som vist i redigeringsskjermen for mediebiblioteket.

Valideringsfunksjonen

Vi validerer også filarrayen og den brukerdefinerte bildteksten med sui_parse_file_errors-funksjonen.

 ($ result = '$ error'] = "Nei" fil opplastet eller det oppsto en opplastingsfeil! "; return $ result; $ image_caption = trim (preg_replace ('/ [^ a-zA-Z0-9 \ s] + /',", $ image_caption)); hvis ($ image_caption == ") $ result ['error'] =" Tekstet ditt kan bare inneholde bokstaver, tall og mellomrom! "; returnere $ resultat; $ resultat ['caption'] = $ image_caption; $ image_data = $ result ['error'] = 'Bildet ditt må være en jpeg, png eller gif ($ result [' tmp_name ' ! '; elseif (($ file [' size ']> MAX_UPLOAD_SIZE)) $ resultat [' error '] =' Ditt bilde var '. $ file [' size '].' bytes! Det må ikke overstige '. MAX_UPLOAD_SIZE. 'Bytes.'; Returnerer $ resultat;
  • sjekk feilelementet i filararrayen for en html-opplastingsfeil, hvis funnet returnerer en resultatmatrise med feil
  • Kjør litt regex på bildeteksten for å fjerne alt, men alfanumeriske data og mellomrom, erstatte med mellomrom for lesbarhet
  • hvis vi ender med en tom bildetekst etter å ha gjort det, returnerer vi en feil
  • sjekk den interne bildetypen (ikke stole på filtypen) ved hjelp av PHP getimagesize-funksjonen mot TYPE_WHITELIST-konstanten
  • Sjekk bildestørrelsen mot MAX_UPLOAD_SIZE-konstanten

Trinn 8 Enkel styling

Bare slipp denne stilinfoen i stilen.css-filen i temamappen din:

 #sui_upload_image_form #sui_image_caption width: 500px;  #user_images font-size: 12px;  #user_images th text-align: left;  #user_images td vertikaljustering: midt;  #user_images td input margin: 0px; 

Trinn 9 Prøv det

Aktiver plugin, trykk kortnummeret på en side, logg inn på nettstedet ditt, og test det ut. Når du laster opp et bilde, vil du se et nytt innlegg vises under administrasjonsmenyen Brukerbilder. Det blir ventet på publisering. Du vil også se et nytt bilde som er oppført i mediebiblioteket ditt, vedlagt det nye innlegget ditt og med bildeteksten som angitt.

Den komplette pluginkodekilden og en demo-nettstedslink er oppført øverst i denne opplæringen.

Kildemappen inneholder også en Wordpress-sidemal med en tilpasset sløyfe som viser publiserte bilder for alle brukere.


Siste tanker

Du kan ønske å legge strengere validering på bildeopplastingene dine. Husk at du aksepterer data fra brukere som ved et uhell eller skadelig opplasting av upassende filer. Å sjekke filtype og størrelse er en god start.

Også, vi opprettet vedleggsvedlegget ved å oppdatere vedleggets post_excerpt-felt. Du kan også angi en vedleggsbeskrivelse ved å bruke vedleggets post_content-felt.