Cum să încarci o imagine folosind un formular simplu?
Scriu un plugin pentru pagina mea de profil și vreau să creez o funcție de încărcare prin intermediul unui buton 'Browse' și un câmp 'Dir' care va încărca și va returna URL-ul imaginii. Nu doresc să folosesc media-upload.
Am citit Setarea Imaginii Reprezentative din Formular Frontend dar nu înțeleg codul. Mă puteți ajuta să rezolv această problemă?
Sunt mai multe părți.
Trebuie să adăugați un enctype
la formularul de profil.
function edit_form_type_wpse_98375() {
echo ' enctype="multipart/form-data"';
}
add_action('user_edit_form_tag','edit_form_type_wpse_98375');
Apoi adăugați un câmp în formular.
function user_fields_wpse_98375($profileuser) {
$_profile_photo = get_user_meta($profileuser->data->ID,'_profile_photo',true);
echo '<h3>'.__('Date Utilizator Adiționale',THEME_TEXTDOMAIN).'</h3>';
echo '<tr class="show-admin-bar">';
echo '<th scope="row">'.__('Fotografie Profil', THEME_TEXTDOMAIN).'</th>';
echo '<td'.$tspan.'>';
echo '<fieldset>';
echo '<legend class="screen-reader-text"><span>'.__('Fotografie Profil', THEME_TEXTDOMAIN).'</span></legend>';
echo '<label for="profile_photo">';
echo '<input name="profile_photo" type="file" id="profile_photo" value="" />';
echo '</label><br />';
echo '</fieldset>';
echo '</td>';
echo '</tr>';
echo '</table>';
}
add_action('show_user_profile', 'user_fields_wpse_98375');
add_action('edit_user_profile', 'user_fields_wpse_98375');
Și apoi salvați datele.
function save_user_custom($id=false) {
global $_FILES,$_POST;
if (false === $id) return false;
// salvează imaginea
if (isset($_FILES)) {
if (isset($_FILES['profile_photo'])){
if (0 === $_FILES['profile_photo']['error']) {
// Aici salvezi fișierul
// Poți folosi wp_handle_upload
// Sau Filesystem API
// nu sunt sigur ce vrei să faci
}
}
unset($up);
}
}
add_action('personal_options_update','save_user_custom');
add_action('edit_user_profile_update','save_user_custom');
wp_handle_upload
este probabil cea mai simplă soluție. Conform Codex:
if ( ! function_exists( 'wp_handle_upload' ) )
require_once( ABSPATH . 'wp-admin/includes/file.php' );
$uploadedfile = $_FILES['file'];
$upload_overrides = array( 'test_form' => false );
$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
if ( $movefile ) {
echo "Fișierul este valid și a fost încărcat cu succes.\n";
var_dump( $movefile);
} else {
echo "Posibil atac la încărcarea fișierului!\n";
}
Tipul de input file
funcționează (în mare parte) ca orice alt input de formular. Dacă îi dai un nume precum my_uploads['profile_photo']
în loc de profile_photo
, vei primi un array. Acesta va fi reflectat în variabila $_FILES
când procesezi trimiterea formularului. Poți adăuga câte input-uri file
dorești construind acel array sau pur și simplu dându-le nume diferite. Cât despre adăugarea dinamică a input-urilor file
, aceasta este destul de simplu de realizat cu Javascript.
Referințe
http://codex.wordpress.org/Function_Reference/wp_handle_upload
http://codex.wordpress.org/Filesystem_API

Mulțumesc s_ha_dum ^_^ și acesta este exemplul pe care îl doresc cu adevărat http://i165.photobucket.com/albums/u56/zectdropper/Capture_zpsea5fdfc7.png Explicație->câmpul de încărcare poate adăuga sau șterge mai mult de unul. Cred că ar trebui să le salveze sub formă de array. Cum le pot scrie și salva în WordPress

Și dacă trebuie să testezi erori, poți folosi acest hook: user_profile_update_errors

Cred că nu ești foarte experimentat cu PHP și încărcarea fișierelor. Așa că voi începe cu câteva noțiuni de bază și voi termina cu o clasă simplă.
Dacă nu ai citit deja noțiunile de bază despre încărcarea fișierelor cu PHP, fă-o acum. Nimeni nu ți le va explica aici, este în afara subiectului.
Să începem cu formularul HTML de bază
if( empty( $_FILES ) ) {
global $pagenow;
$url = admin_url( $pagenow );
?>
<!-- Tipul de codare a datelor, enctype, TREBUIE să fie specificat ca mai jos -->
<form enctype="multipart/form-data" action="<?php echo $url; ?>" method="POST">
<!-- MAX_FILE_SIZE trebuie să preceadă câmpul de încărcare a fișierului -->
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<!-- Numele elementului de input determină numele din array-ul $_FILES -->
Trimite acest fișier: <input name="userfile" type="file" />
<input type="submit" value="Trimite Fișierul" />
</form>
<?php
} else {
$imageupload = new File_Upload();
$attachment_id = $imageupload->create_attachment();
var_dump( $attachment_id );
}
Asta este destul de simplu. Dacă array-ul superglobal $_FILES
este gol, înseamnă că nu a fost încărcat niciun fișier, afișează formularul de încărcare. Dacă nu este gol, procesează încărcarea. Folosesc admin_url()
și variabila $pagenow
pentru a crea URL-ul acțiunii. Dacă folosești formularul de încărcare în frontend, trebuie să folosești home_url()
sau ceva similar.
După trimiterea fișierului cu HTML, trebuie să procesezi fișierele încărcate. Acest lucru se va face în clasa File_Upload
.
class File_Upload
{
/**
* Cheia index din formularul de încărcare
* @var string
*/
public $index_key = '';
/**
* Copie a array-ului superglobal $_FILES
* @var array
*/
public $files = array();
/**
* Constructor
* Inițializează array-ul de fișiere și ghicește cheia index
*/
public function __construct(){
if ( isset( $_FILES ) && ! empty( $_FILES ) ) {
$this->files = $_FILES;
$this->guess_index_key();
}
}
/**
* Setează/rescrie cheia index
* Converțește $name cu type casting (string)
*
* @param string $name Numele cheii index
* @return string ::name Numele cheii index stocate
*/
public function set_field_name_for_file( $name = '' ) {
$this->index_key = ( ! empty( $name ) ) ? (string) $name : '';
return $this->index_key;
}
/**
* Converțește fișierul încărcat într-un atașament WordPress
*
* @return boolean Dacă atașamentul a fost creat (true) sau nu (false)
*/
public function create_attachment(){
// mută fișierul încărcat din folderul temporar și creează datele de bază
$imagedata = $this->handle_uploaded_file();
// dacă mutarea eșuează, oprește aici
/*
* Pentru Producție
* Setează și returnează un obiect de eroare cu WP_Error()
*/
if ( empty( $imagedata ) )
return false;
/*
* Pentru Producție
* Verifică dacă $imagedata conține valorile așteptate (și necesare)
* Orice metodă poate eșua și poate returna date malitioase!!
*/
$filename = $imagedata['filename'];
// creează array-ul de date pentru atașament
$attachment = array(
'guid' => $imagedata['url'] . '/' . $filename,
'post_mime_type' => $imagedata['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', $filename ),
'post_content' => '',
'post_status' => 'inherit'
);
// inserează atașamentul (posttype attachment)
$attach_id = wp_insert_attachment( $attachment, $filename );
// trebuie mai întâi să incluzi fișierul image.php
// pentru ca funcția wp_generate_attachment_metadata() să funcționeze
require_once( ABSPATH . 'wp-admin/includes/image.php' );
/*
* Pentru Producție
* Verifică $attach_data, wp_generate_attachment_metadata() poate eșua
* Verifică dacă wp_update_attachment_metadata() eșuează (returnează false),
* returnează un obiect de eroare cu WP_Error()
*/
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
return $attach_id;
}
/**
* Gestionează încărcarea
*
* @return array $return_data Array cu informații despre fișierul încărcat
*/
protected function handle_uploaded_file() {
// obține datele de bază
$return_data = wp_upload_dir();
// obține calea temporară și numele fișierului din $_FILES ($this->files)
$tmp_file = ( isset( $this->files[$this->index_key] ) && ! empty( $this->files[$this->index_key] ) ) ?
(string) $this->files[$this->index_key]['tmp_name'] : '';
$tmp_name = ( isset( $this->files[$this->index_key] ) && ! empty( $this->files[$this->index_key] ) ) ?
(string) $this->files[$this->index_key]['name'] : '';
// oprește dacă ceva nu a funcționat
if ( empty( $tmp_file ) )
return false;
// setează calea fișierului
$filepath = $return_data['filepath'] = $return_data['path'] . '/' . basename( $tmp_name );
// mută fișierul încărcat din directorul temporar în directorul de încărcare
move_uploaded_file( $tmp_file , $filepath );
// setează numele fișierului
$filename = $return_data['filename'] = basename( $filepath );
// setează tipul fișierului
/*
* Pentru Producție
* Ar trebui să verifici EXTENSIA și TIPUL fișierului la
* FIECARE încărcare. Dacă nu faci asta, este posibil să încarci
* ORICE fel de fișier, inclusiv cod malitios.
*/
$type = wp_check_filetype( $filename, null );
$return_data['file_ext'] = ( isset( $type['ext'] ) && ! empty( $type['ext'] ) ) ?
$type['ext'] : '';
$return_data['type'] = ( isset( $type['type'] ) && ! empty( $type['type'] ) ) ?
$type['type'] : '';
// returnează rezultatele
return $return_data;
}
/**
* Încearcă să obțină primul index din $_FILES
*
* @return boolean Dacă a fost găsită o cheie sau nu
*/
protected function guess_index_key() {
$keys = array_keys( $_FILES );
if ( ! empty( $keys ) ) {
$this->index_key = $keys[0];
return true;
}
return false;
}
}
Aceasta este o clasă de bază și nu este pentru producție! Încărcarea fișierelor este un subiect foarte sensibil, trebuie să validezi și să sancționezi toate datele singur. Altfel, este posibil ca cineva să încarce cod malitios și să hack-uiască serverul/blogul/site-ul tău!
Acum, pas cu pas, ce se întâmplă unde și când.
Prin crearea unei instanțe a clasei, clasa încearcă să creeze o copie a array-ului superglobal $_FILES
. Dacă lucrezi cu array-uri superglobale, nu le atinge! Este posibil ca alte părți ale codului (plugin-uri sau teme) să aibă nevoie și ele de datele din ele. Următorul lucru care se întâmplă în constructor este că încercăm să ghicim cheia index. După cum știi, putem trimite mai mult de un fișier și $_FILES
poate conține date pentru toate fișierele încărcate. Dacă trebuie să procesezi mai mult de un fișier, parcurge $_FILES
și setează cheia index cu set_field_name_for_file()
// obține indexii din $_FILES
$keys = array_keys( $_FILES );
$upload_processor = new File_Upload();
foreach ( $keys as $key ) {
$upload_processor->set_field_name_for_file( $key );
$upload_processor->create_attachment();
}
set_field_name_for_file()
este necesar și dacă vrei să alegi un câmp specific din formularul tău HTML, altfel clasa va folosi primul index pe care îl poate găsi.
Următorul pas este să gestionezi fișierul încărcat. Metoda create_attachment()
apelează metoda protejată handle_uploaded_file()
, nu trebuie să o faci manual. Metoda handle_uploaded_file()
pur și simplu colectează și setează unele căi și nume de fișiere necesare.
Ultimul pas este să creezi un atașament. create_atatchment()
va seta toate datele necesare și va crea un atașament pentru tine. Metoda returnează ID-ul atașamentului, astfel încât poți accesa toate datele atașamentului cu get_post( [id] )
$imageupload = new File_Upload();
$attachment_id = $imageupload->create_attachment();
[alt cod]
$attachment = get_post( $attachment_id );
$image_url = $attachment->guid;
printf( '<p><img src="%s"></p>', $image_url );
Câteva cuvinte despre gestionarea erorilor
Am scris câteva indicii în codul clasei pentru mediu de producție. După cum am menționat mai sus, încărcarea fișierelor este un subiect foarte sensibil. Trebuie să verifici, să validezi și să sancționezi absolut totul. WordPress are un sistem integrat de gestionare a erorilor cu WP_Error()
. Folosește-l! Și verifică dacă încărcarea a avut succes cu is_wp_error()
.
PHP poate seta câteva mesaje de eroare care explică de ce a eșuat încărcarea, dacă a eșuat. Dar PHP nu returnează mesaje în text clar, returnează coduri de eroare. O metodă de a converti aceste coduri în text clar ar putea arăta astfel:
protected function guess_upload_error( $err = 0 ) {
$errcodes = array(
'Eroare necunoscută',
'Fișierul încărcat depășește directiva upload_max_filesize din php.ini.',
'Fișierul încărcat depășește directiva MAX_FILE_SIZE specificată în formularul HTML.',
'Fișierul încărcat a fost doar parțial încărcat.',
'Niciun fișier nu a fost încărcat.',
'Lipsește un folder temporar.',
'Nu s-a putut scrie fișierul pe disc.',
'O extensie PHP a oprit încărcarea fișierului. PHP nu oferă o modalitate de a determina care extensie a cauzat oprirea încărcării; examinarea listei de extensii încărcate cu phpinfo() poate ajuta.'
);
return ( isset( $errcodes[$err] ) ) ?
$errcodes[$err] : 'Eroare necunoscută';
}
Trebuie să verifici dacă încărcarea a avut succes, acest lucru ar putea arăta astfel (în metoda handle_upload_file()
)
// oprește dacă ceva nu a funcționat
if ( empty( $tmp_file ) ) {
$code = ( isset( $this->files[$this->index_key]['error'] ) ) ?
$this->files[$this->index_key]['error'] : 0;
$msg = $this->guess_upload_error( $code );
return new WP_Error( 'uploaderror', 'Încărcarea a eșuat cu mesajul: ' . $msg );
}
Și apoi trebuie să gestionezi eroarea când apelezi clasa
if ( empty( $_FILES ) ) {
global $pagenow;
$url = admin_url( $pagenow );
?>
<!-- Formular HTML-->
<?php
} else {
$imageupload = new File_Upload();
$attachment_id = $imageupload->create_attachment();
if ( is_wp_error( $attachment_id ) ) {
echo '<ol>';
foreach ( $attachment_id->get_error_messages() as $err )
printf( '<li>%s</li>', $err );
echo '</ol>';
} else {
// fă ceva cu atașamentul creat
$attachment = get_post( $attachment_id );
$image_url = $attachment->guid;
printf( '<p><img src="%s"></p>', $image_url );
}
}
Ține minte întotdeauna: Niciodată nu lăsa o încărcare eșuată netratată!

Adăugați cod în fișierul functions.php
add_action('wp_ajax_custom_action', 'custom_action');
add_action('wp_ajax_nopriv_custom_action', 'custom_action');
function custom_action() {
$post_id =12;
//print_r($_FILES); exit;
global $wpdb;
//$response = array();
if( $_FILES['uploadedfiles']) {
$file = $_FILES['uploadedfiles'];
require_once( ABSPATH . 'wp-admin/includes/admin.php' );
$file_return = wp_handle_upload( $file, array('test_form' => false ) );
if( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
return false;
} else {
$filename = $file_return['file'];
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $file_return['url']
);
$attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
update_post_meta($post_id, '_thumbnail_id', $attachment_id);
if( 0 < intval( $attachment_id ) ) {
return $attachment_id;
}
}
return false;
}
//$response['message'] = 'Imagine încărcată!!!';
//echo json_encode($response);
wp_die();
}
