質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WooCommerce

WooCommerceは、2011年にリリースされたWordPressのためのECプラグインです。ECサイトに必要な一連の機能を簡単に導入できる上、柔軟なカスタマイズをすることも可能です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

859閲覧

【WordPress】管理画面以外でもadmin-ajax.phpのメディアファイルパスを使えるようにしたい

bokupiroki

総合スコア54

WooCommerce

WooCommerceは、2011年にリリースされたWordPressのためのECプラグインです。ECサイトに必要な一連の機能を簡単に導入できる上、柔軟なカスタマイズをすることも可能です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/02/24 16:18

編集2020/02/25 00:44

###実現したいこと・前提条件

  • WordPressメディア上で「画像を編集」をクリックするとプレビューされる画像URL(ajax)を公開ページでも使えるようにしたい

↑具体的には「【サイトURL】/wp-admin/admin-ajax.php?action=imgedit-preview&_ajax_nonce=○○&postid=○○」のようなパス
イメージ説明

  • 現状ではWordPressにログインしてから公開ページ側を見ないと該当パスの画像が表示されない

カスタムフィールドの画像を表示したいのですが、訳があってそのままのURLで表示するのではなくajax版のパスで公開ページに表示したいと考えています。

具体的な理由は下記です。

  • WordPressのプラグイン「Woocommerce」で画像などのデータを販売している
  • Woocommerceの仕様上、データを実際に購入した人にしか該当データへのアクセス権が与えられない
  • ゆえに公開サイトでデータをプレビューできないので代わりにadmin-ajax.phpの画像URLを使って公開ページに画像を表示したい

###画面該当箇所のコード
管理画面上の任意の場所にajax版の画像をプレビューすることは、過去の質問で教わった下記のコードで実現できました。(https://teratail.com/questions/241743)

php

1<?php$args = [ 2 'numberposts' => -1, 3 'post_mime_type' => 'image', 4 'post_parent' => get_the_ID(), 5 'post_type' => 'attachment' 6]; 7$images = get_children( $args ); 8foreach ( $images as $image ) { 9 $nonce = wp_create_nonce( "image_editor-$image->ID" ); 10 ?> 11<img src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $downloadfile_id; ?>" onerror="this.style.display='none'">

↓投稿画面上でajax版URLを使って登録した画像を表示した結果
イメージ説明

公開ページ側で同じことをしようとしても、画像は表示されません。

###試したこと
WordPRessにログインした状態で「【サイトURL】/wp-admin/admin-ajax.php?action=imgedit-preview&_ajax_nonce=○○&postid=○○」をブラウザで叩くと画像が表示されます。

しかし、ログインしていない状態で同じことをするとブラウザに「0」と表示されるだけです。

例えば何かの設定をfunctions.phpに書き足せば、管理画面以外でも使えるようになるわけではないのでしょうか?

「そもそもの用途として間違っている」とか、「こういうことを調べたらいい」などがあればご教授いただきたいです。

###補足情報(FW/ツールのバージョンなど)
WordPress5.3.2
woocommerce3.8.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2020/02/24 16:36

「過去の質問を読め」ではなく、何のために何をしたいのかを具体的に追記されてはいかがでしょう。
bokupiroki

2020/02/24 17:00

更新いたしました。
guest

回答2

0

ベストアンサー

Woocommerceでダウンロード販売している画像をプレビューしたいということでしょうか?
たぶんこのような感じで出力できると思います。
get_post_metaの引数には商品の投稿IDを渡してください。ループの中であればそのままで大丈夫です。
post_metaにダウンロード可能なファイルの情報が入っているのでそこからURLを取得しています。
URLから画像に関する情報を取得しますが、オリジナル画像のURLが特定されないようにサムネイルを
base64でエンコードしてimgタグに設定しています。
ダウンロードファイルが画像かどうかの判断や有効期限のチェックはしていませんので、必要であれば
適宜実施してください。

PHP

1$files = get_post_meta(get_the_ID(), '_downloadable_files'); 2 if (!empty($files[0])) { 3 foreach ($files[0] as $file) { 4 $url = $file['file']; 5 $id = attachment_url_to_postid($url); 6 if ($id) { 7 $thumb = wp_get_attachment_image_url($id, 'thumbnail'); 8 $mimetype = get_post_mime_type($id); 9 if ($thumb && $mimetype) { 10 $data = file_get_contents($thumb); 11 if ($data) { 12 echo '<img src="data:'.$mimetype.';base64,'.base64_encode($data).'">'; 13 } 14 } 15 } 16 } 17}

投稿2020/03/02 01:28

tabuu

総合スコア2449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bokupiroki

2020/03/02 09:56

ありがとうございます。 出力結果に下記のようなエラーが出てしまいます。 --- Warning: file_get_contents(https://【サイトのドメイン】/wp-content/uploads/woocommerce_uploads/2020/03/ka-bili-150x150.png): failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden in --- 画像のパス自体は正しく認識できているようなので、販売する画像に対するアクセス権限がなく処理ができないのではないかと思っています。 経験上、Woocommerceは「_downloadable_files」にあてがわれているメディアのURL対して、ブラウザなどからアクセスさせない仕様のようです。 実際の販売データのURLをブラウザのアドレスバーに叩いてアクセスしても、 403のエラーが返ってくるのでそのように考えています。 (例)https://【サイトドメイン】wp-content/uploads/woocommerce_uploads/2020/03/ka-bili.png →ブラウザでアクセスすると403エラー
tabuu

2020/03/02 23:38

それではウェブサーバ経由ではなくローカルパスに変更すればいかかでしょうか? $thumb = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $thumb); $data = file_get_contents($thumb);
bokupiroki

2020/03/03 03:05

ありがとうございます。 今度はエラー含め何も表示されなくなりました。 コード全体 --- $files = get_post_meta(get_the_ID(), '_downloadable_files'); if (!empty($files[0])) { foreach ($files[0] as $file) { $url = $file['file']; $id = attachment_url_to_postid($url); if ($id) { $thumb = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $thumb); $mimetype = get_post_mime_type($id); if ($thumb && $mimetype) { $data = file_get_contents($thumb); if ($data) { echo '<img src="data:'.$mimetype.';base64,'.base64_encode($data).'">'; } } } } } echo '$thumbの中身→'.$thumb; --- 試しに「$thumb」に値が格納されているかチェックしてみたのですが、 何も出ないので空になっているように見受けられます。 「$id」や「$mimetype 」には値が格納されていました。
tabuu

2020/03/03 04:00

コメント欄にコードを書き難いので省略しましたが以下のようにifとstr_replaceの間に元々あった wp_get_attachment_image_urlを入れてください。 if ($id) { $thumb = wp_get_attachment_image_url($id, 'thumbnail'); $thumb = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $thumb); としてください。
bokupiroki

2020/03/03 04:46 編集

できました! 元々の「$thumb」の中身を再定義する必要があったということですね。 最終的なコード --- $files = get_post_meta(get_the_ID(), '_downloadable_files'); if (!empty($files[0])) { foreach ($files[0] as $file) { $url = $file['file']; $id = attachment_url_to_postid($url); if ($id) { $thumb = wp_get_attachment_image_url($id, 'thumbnail'); $thumb = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $thumb); $mimetype = get_post_mime_type($id); if ($thumb && $mimetype) { $data = file_get_contents($thumb); if ($data) { echo '<img src="data:'.$mimetype.';base64,'.base64_encode($data).'">'; } } } } } --- 本当にありがとうございました。
guest

0

wpのajax処理はログインしている場合としていない場合で別々に登録するようになっているので
当該のimedit-reviewっていうactionはwp_ajax_nopriv_{aciton}では登録されてないものと推測

php

1$GLOBALS['wp_filter']['wp_ajax_nopriv_imgedit-preview']=$GLOBALS['wp_filter']['wp_ajax_imgedit-preview'];

試したことはないけどソースコード見る限りはこれでいけるんじゃないかな

投稿2020/02/26 07:03

編集2020/02/27 09:08
KazuhiroHatano

総合スコア7804

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bokupiroki

2020/02/27 04:59 編集

ありがとうございます。 「ログイン時にしか使えないコードを書いているので、グローバル変数を新たに定義することでうまくいくのではないか?」 という認識であっていますでしょうか? 試しにもともとのにコードの<?php ~?>内にいただいたコードを追加してみましたが 同じ状態でした。 ↓追記後 ---- <?php $args = [ 'numberposts' => -1, 'post_mime_type' => 'image', 'post_parent' => get_the_ID(), 'post_type' => 'attachment' ]; $images = get_children( $args ); foreach ( $images as $image ) { $nonce = wp_create_nonce( "image_editor-$image->ID" ); //いただいたコード $GLOBALS['wp_filter']['wp_ajax_nopriv_imedit-review']=$GLOBALS['wp_filter']['wp_ajax_imedit-review']; ?> <img src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $downloadfile_id; ?>" onerror="this.style.display='none'"> --- funtcions.phpにも同様にコードを追記してみましたが同じでした。 imgタグの中も修正しないといけないなど、 根本的に何かを間違えていたら申し訳ありません。
KazuhiroHatano

2020/02/27 05:27

タイミングの問題ですかね 多分テーマのfunctions.phpが読まれたタイミグではまだ $GLOBALS['wp_filter']['wp_ajax_imedit-review'];はいないんじゃないでしょうか 件の処理はadd_action('admin_init',...)で、かなり遅いタイミングでやった方がいいですかね
bokupiroki

2020/02/27 09:00

ありがとうございます。 funtions.phpに記載してみましたが、同じ状況です。 ↓コード ---- function ajaxenable() { $GLOBALS['wp_filter']['wp_ajax_nopriv_imedit-review']=$GLOBALS['wp_filter']['wp_ajax_imedit-review']; } add_action('admin_init','ajaxenable',200); --- add_actionの第三引数(?)を「200」にしたのは 「かなり遅いタイミングでやった方がいい」とのアドバイスをいただいたことが理由です。 そもそもfunctions.php以外に「add_action」を書いた経験がないのですが、 試しにもともとのコードを記載している子テーマのファイルに同じように上記のコードを 書いても、状況としては同じでした。 申し訳ありません。 追加で必要な情報などあれば教えていただきたいです。
bokupiroki

2020/02/27 15:33

何度もありがとうございます。 修正後のコードをfunctions.phpに記載しましたが、状況は変わりませんでした。 コード --- function ajaxenable() { $GLOBALS['wp_filter']['wp_ajax_nopriv_imgedit-preview']=$GLOBALS['wp_filter']['wp_ajax_imgedit-preview']; } add_action('admin_init','ajaxenable',200); --- 申し訳ありません。
KazuhiroHatano

2020/02/28 01:14

一応ローカルで試したところ、このグローバル変数を直接いじる形でフィルタフックをコピーしても動くのは動くので、これで動かないならコールバックで権限チェックされてるとかですかね 自分もこれに類する処理書くなら権限チェックすると思います そうであるなら、このフィルタフックのコールバックのソースコードを見て 移植するなり対処方法を検討する感じですかね 権限チェックと画像出力の処理が分けられていて 画像出力の処理が関数やクラスとして切り分けられていれば移植は容易かもしれません 画像出力の関数やクラスに権限チェックの処理が組み込まれていたら 移植は諦めて、自前で画像出力のプログラムを書くとかですかね
bokupiroki

2020/02/29 15:14

ありがとうございます。 「コールバック」や「権限チェック」がなんのことなのかピンと来ていないので、 もう少し調べながらチャレンジさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問