5
votes

Est-il possible d'imiter ou de passer une URL de fichier à $ _Files?

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.

php

5 commentaires

wp_handle_upload appelle _wp_handle_upload , et ce dernier utilise move_uploaded_file interne 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_file vous permet d'interférer à ce stade - vous devez gérer le déplacement du vous-même dans votre fonction de gestionnaire personnalisé, puis renvoyer null pour 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 truc wp_insert_attachment devrait suffire?


@ 04FS Vous devez en fait renvoyer quelque chose de différent de null pour que WP ignore la tentative de déplacement du fichier. Voir ligne 848


Essayez de lire sur wp_handle_sideload .


3 Réponses :


2
votes

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é.


0 commentaires

2
votes

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 .


0 commentaires

0
votes

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;
}

wp_handle_sideload

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.


0 commentaires