[WordPress] 將附件關聯於文章中程式化的做法

需求

不論是自己上傳檔案或是程式自動捕捉檔案,想附加於媒體庫與指定內容中做關聯。

表單實作

WordPress 提供許多不錯的方法可以呼叫,如果是前端為表單的做法可以參考:media_handle_upload 方法。

如文件中表單:

<form id="featured_upload" method="post" action="#" enctype="multipart/form-data">
    <input type="file" name="my_image_upload" id="my_image_upload"  multiple="false" />
    <input type="hidden" name="post_id" id="post_id" value="55" />
    <?php wp_nonce_field( 'my_image_upload', 'my_image_upload_nonce' ); ?>
    <input id="submit_my_image_upload" name="submit_my_image_upload" type="submit" value="Upload" />
</form>

要記住 my_image_upload 這個 name 參數,與記得加上 wp_nonce_field 欄位驗證請求源,避免你網站太簡單就被機器人灌爆。程式中使用 wp_verify_nonce( $_POST['my_image_upload_nonce'], 'my_image_upload' ) 作為判斷來源請求是否一樣。

下方為主要處理附加檔案的主要方式:

require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );

// Let WordPress handle the upload.
// Remember, 'my_image_upload' is the name of our file input in our form above.
$attachment_id = media_handle_upload( 'my_image_upload', $_POST['post_id'] );

要使用 media_handle_upload 與下列方法需要引用上面三個檔案(image.php, file.php, media.php),然後把要這方法「處理」的資料欄位 my_image_upload 帶入,與要附加的文章編號(post_id),結果就是會回傳附加好的「檔案文章編號」,用來後續操作。

進階實作

總有更多細節掌控需求,這時候可以使用 media_handle_sideload 方法。不論是透過程式自己抓檔案來存還是表單作法,這方法範例中就是模擬將資料放遠端存取的方式。使用 download_url 抓取檔案,建立一個類似 $_FILES 資料結構的陣列參數來附加檔案到內容中。

$tempName = tempnam(sys_get_temp_dir(), 'mxp-tw');
$tempName = realpath($tempName);
file_put_contents($tempName, base64_decode($data));
$tid = media_handle_sideload(array('name' => $output_file_with_extension, 'type' => 'image/jpeg', 'tmp_name' => $tempName, 'error' => 0, 'size' => strlen($data)), $pid, $name . " / " . $posttitle);

如上面範例,只要自己包過檔案結果,帶入正確結構 array('name'=>'檔案名稱','type'=>'MIME檔案類型','tmp_name'=>'暫存檔案完整路徑與名稱','error'=>0,'size'=>'檔案大小數字') 與關聯文章編號和描述。

MIME Type 網際網路媒體型式

進-進階實作

如果不只是抓檔案來放,要是連檔案都是自己「做」出來,那~麽~進階的作法也是有解!檔案前處理後使用 wp_upload_bits 方式寫入

$upload = wp_upload_bits($_FILES["field1"]["name"], null, file_get_contents($_FILES["field1"]["tmp_name"]));

照文件格式呼叫後會取得一組檔案資訊的陣列,然後使用 wp_insert_attachment 建立「附件的文章內容」。

$attachment = array(
    'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ), 
    'post_mime_type' => $filetype['type'],
    'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
    'post_content'   => '',
    'post_status'    => 'inherit'
);

// Insert the attachment.
$attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );

建立了一篇紀錄附件的文章資料後還要更新這紀錄中檔案的資料:wp_generate_attachment_metadata

$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id,  $attach_data );

到此才算是把一個關聯附件資料建立完成。步驟雖多了些,但可以有不少細節可以操作,就看需求是怎樣了!

附加圖片於文章精選特色圖片

上傳檔案大多為圖片的情況也常有一個需求是設定該圖片為文章的封面圖片,方法簡單很多: set_post_thumbnail($pid, $attachment_id); 把文章編號與附件文章編號套入這方法就設定好囉~

結語

其實不要這麼做也是能把檔案上傳到網站上,但後續的管理問題就跟 WordPress 脫節了,想透過後台來管理就必須照架構來開發,而直接寫資料庫的做法完全不推薦,盡是把可能有安全疑慮的漏洞由自己給打開,何必呢。

Facebook 外掛整合


Share: