J'ai besoin de modifier une application qui a été conçue pour nous par quelqu'un d'autre. L'application accepte un fichier (de type .ydk) d'un formulaire et le télécharge ensuite sur WordPress (tout en lisant également son contenu). Je souhaite modifier cela afin qu'il puisse également lire un fichier .ydk à partir du serveur.
Je l'ai réduit à ce qui suit:
Array
(
[name] => 58535.ydk
[type] => application/octet-stream
[tmp_name] => YGOPRO_Decks/user_decks/58535.ydk
[error] => 0
[size] => 576
)
Et la fonction qu'elle utilise alors:
$urls = 'YGOPRO_Decks/user_decks/58535.ydk';
$size = filesize($urls);
$info = pathinfo($urls);
$info_basename = $info['basename'];
$info_mime = 'application/octet-stream';
$UrlArray = array(
'name' => $info_basename,
'type' => $info_mime,
'tmp_name' => 'YGOPRO_Decks/user_decks/58535.ydk',
'error' => 0,
'size' => $size
);
if($_FILES['deckFile']){
$attachment_ydk_id = upload_ydk_file($UrlArray);
}
Donc la façon dont je regarde les choses. $_Files est nécessaire car il utilise wp_handle_upload qui, je crois, nécessite le tableau $_Files .
J'ai essayé fopen et file() tant que tels mais pas de chance:
$attachment_ydk_id = upload_ydk_file(fopen("location_of_file.ydk", "r"));
EDIT: 1ère tentative
J'ai maintenant essayé ce qui suit (pour tenter de recréer $ _Files):
//Upload ydk file
function upload_ydk_file( $file = array() ) {
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 );
if( 0 < intval( $attachment_id ) ) {
return $attachment_id;
}
}
return false;
}
Le fichier existe à l'emplacement donné. Un print_r sur le tableau donne:
if($_FILES['deckFile']){
$attachment_ydk_id = upload_ydk_file($_FILES['deckFile']);
}
Toujours pas de chance malheureusement. Cela semblait être une très bonne méthode et je pensais que j'étais sur quelque chose, mais cela continue à échouer.
3 Réponses :
Vous étiez sur la bonne voie en créant votre propre tableau pour $_FILES . Pour continuer, essayez d'ajouter le `` faux fichier '' au global comme ceci:
$urls = 'YGOPRO_Decks/user_decks/58535.ydk';
$size = filesize($urls);
$info = pathinfo($urls);
$info_basename = $info['basename'];
$info_mime = 'application/octet-stream';
$UrlArray = array(
'name' => $info_basename,
'type' => $info_mime,
'tmp_name' => 'YGOPRO_Decks/user_decks/58535.ydk',
'error' => 0,
'size' => $size
);
$_FILES[$info_basename] = $UrlArray;
if(!empty($_FILES)) {
$attachment_ydk_id = upload_ydk_file($UrlArray);
}
Cela devrait faire croire à WP qu'un fichier réel a été téléchargé.
Selon la documentation de wp_insert_attachement , le fichier doit être situé dans le répertoire uploads. En supposant que vous ayez accès à la bibliothèque WordPress complète (puisque vous y appelez déjà), vous pouvez obtenir le chemin en utilisant wp_upload_dir .
$urls = 'YGOPRO_Decks/user_decks/58535.ydk';
$tmp_file = wp_upload_dir() . '/' . basename($urls);
if (!copy($url, $tmp_file))
exit();
$size = filesize($tmp_file);
$info = pathinfo($tmp_file);
$info_basename = $info['basename'];
$info_mime = 'application/octet-stream';
$UrlArray = array(
'name' => $info_basename,
'type' => $info_mime,
'tmp_name' => $tmp_file,
'error' => 0,
'size' => $size
);
$attachment_ydk_id = upload_ydk_file($UrlArray);
Remarque: Si vous n'avez pas chargé WordPress (par exemple, si vous essayez d'exécuter cela en tant que script à partir de la ligne de commande), alors upload_ydk_file ne fonctionnera pas car il repose sur plusieurs fonctions WordPress.
Vous n'êtes pas non plus fait jamais appel upload_ydk_file parce que vous en train de vérifier si le deckFile nœud du $_FILES tableau est mis en avant de l' appeler.
if($_FILES['deckFile']){
$attachment_ydk_id = upload_ydk_file($UrlArray);
}
Si vous supprimez cela et appelez toujours upload_ydk_file puisque vous savez que $ UrlArray sera toujours défini, vous devriez être prêt à partir.
$tmp_file = wp_upload_dir() . '/' . basename($urls);
if (!copy($url, $tmp_file))
exit();
EDIT: L' utilisation de wp_handle_sideload est un moyen plus sûr de déplacer le fichier dans le répertoire de téléchargement. Cependant, il va déplacer le fichier, pas copier le fichier, donc si vous souhaitez l'utiliser à la place, vous devez toujours copier le fichier d'origine avant de le transmettre à wp_handle_sideload .
Je suis arrivé à mettre enfin en œuvre une solution pour cela. Comme un utilisateur l'a gentiment mentionné, wp_handle_sideload au lieu de wp_handle_upload était la solution. Cela m'a permis de charger un fichier URL parallèlement à l'imitation du tableau $_FILES .
//Upload ydk file
function upload_ydk_file( $file = array() ) {
require_once( ABSPATH . 'wp-admin/includes/admin.php' );
$file_return = wp_handle_sideload( $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 );
if( 0 < intval( $attachment_id ) ) {
return $attachment_id;
}
}
return false;
}
Gérez les charges latérales, qui est le processus de récupération d'un élément multimédia à partir d'un autre serveur au lieu d'un téléchargement multimédia traditionnel. Ce processus implique de nettoyer le nom de fichier, de vérifier les extensions pour le type mime et de déplacer le fichier vers le répertoire approprié dans le répertoire de téléchargement.
wp_handle_uploadappelle_wp_handle_upload, et ce dernier utilisemove_uploaded_fileinterne pour déplacer le fichier vers son emplacement cible; mais cette fonction PHP a une vérification intégrée pour vérifier que le fichier provient d'un téléchargement de fichier réel, pour des raisons de sécurité - si vous essayez de déplacer un autre fichier qui ne remplit pas cette exigence, cela échouera.Mais le filtre
pre_move_uploaded_filevous permet d'interférer à ce stade - vous devez gérer le déplacement du vous-même dans votre fonction de gestionnaire personnalisé, puis renvoyernullpour que WordPress ignore la partie où il tente de déplacer le fichier lui-même par la suite.Pourquoi avez-vous besoin d'injecter des données dans
$_FILES? Si le fichier est déjà sur le serveur, le simple fait de faire le trucwp_insert_attachmentdevrait suffire?@ 04FS Vous devez en fait renvoyer quelque chose de différent de
nullpour que WP ignore la tentative de déplacement du fichier. Voir ligne 848Essayez de lire sur
wp_handle_sideload.