• ベストアンサー

WordPressの質問(q10245849)の続

回答が遅れてしまい申し訳ありません、こちらが最新の質問になります。 質問入力画面に画像をアップロードした場合と動画をアップロードした場合で大きさが変わってしまうのですが、統一することは可能でしょうか? こちらは以前 dell_ok さんにお聞きした覚えがあり難しいとアドバイスを頂いた記憶があるのですが… 質問入力画面にファイルをアップロードする場合クリックして選択する方法だけでなくドラッグ&ドロップも追加することは可能でしょうか? ※最新コード https://wandbox.org/permlink/IM6IiiwxaS6eXwXY

質問者が選んだベストアンサー

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.43

・全体の流れはクライアント(bbs_quest_input.php)入力フォームで送信 → サーバー(bbs_que_list.php)で受け取る → 表示という流れになりそうです。 そうではないと思います。 クライアントは bbs_que_list.php の JavaScript です。 サーバーは functions.php に追加するであろうアクションです。 いろいろと調べられているようですが、 すでにやったことのある方法を応用した方が簡単そうです。 例えば、サーバーの functions.php はこうです。 とりあえずは、非同期通信と無限スクロールの確認のためなので、 データベースは参照せずに、固定で2個のデータを返すものを作ってみます。 ---- function bbs_que_list_items() { $result = []; $result['items'][] = ['title' => 'タイトル1', 'img1' => '画像1']; $result['items'][] = ['title' => 'タイトル2', 'img1' => '画像2']; echo json_encode($result); exit; } add_action('wp_ajax_bbs_que_list_items', 'bbs_que_list_items'); add_action('wp_ajax_nopriv_bbs_que_list_items', 'bbs_que_list_items'); ---- WordPress の ajax の PHP 側の処理は以前やった方法です。 まず、実行する処理関数を作ります。 ここでは bbs_que_list_items という名前にしました。 WordPress ではアクションと呼ばれているようです。 フックの追加は以下の構文です。 add_action('wp_ajax_アクション名','関数名'); add_action('wp_ajax_nopriv_アクション名', '関数名'); クライアント側はこうです。 先日のサンプルではコンテンツの追加が固定文字だったものを、 非同期通信で取得したデータをもとに生成するように変更しました。 非同期通信については jQuery を使わず標準の JavaScript で記述しています。 ---- function ajax_add_content() { const formData = new FormData(); formData.append("action", "bbs_que_list_items"); const opt = { method: "post", body: formData } fetch("<?php echo home_url('wp-admin/admin-ajax.php'); ?>", opt) .then(response => { return response.json(); }) .then(json => { for (const item of json.items) { $content = "<div>" + item.img1 + "</div>" + "<div>" + item.title + "</div>"; $("#content").append($content); } }) .catch(error => { console.log(error); }); }; ----  formData.append("action", "bbs_que_list_items"); の、ここがサーバー側で記述したアクション名になります。  formData.append("action", "アクション名"); 手順としては以上のようになります。 私のサンプルに実装したので見てみてください。 残りの作業としては、 サーバー側  1.データベースから範囲を指定してデータを取得する  2.画像ファイルのパスを取得する クライアント側  3.表示件数の保持と送信  4.画像ファイルの形式にあったタグまたは要素にする になると思います。 無限スクロールの処理は参考サイトのもののままだと思うのですが、 スクロールを戻した際にもコンテンツが追加されているようなので、 なにかしら調整が必要な気がします。

php_learn
質問者

お礼

こちらが最新の質問になります。 質問の期限が切れており続きの質問を立てさせていただきました。アドバイスよろしくお願い致します。 https://okwave.jp/qa/q10263921.html

php_learn
質問者

補足

Q.いろいろと調べられているようですが、 すでにやったことのある方法を応用した方が簡単そうです。 クライアント側はこうです。 先日のサンプルではコンテンツの追加が固定文字だったものを、 非同期通信で取得したデータをもとに生成するように変更しました。 A.アドバイスありがとうございます。送信というのがボタンを押さないとコンテンツが取得できないのではないかと考えておりました… fetch()関数を使用してAPIからデータを取得可能なんですね勉強になりました。 Q.残りの作業としては、 サーバー側  1.データベースから範囲を指定してデータを取得する  2.画像ファイルのパスを取得する クライアント側  3.表示件数の(データベースから範囲を指定してデータ)保持と送信  4.画像ファイルの形式にあったタグまたは要素にする になると思います。 A.回答ありがとうございます。クライアント側の3番についてお聞きしたいのですが、1週間で質問をリセットする場合こちらは必要なくなるのでしょうか? データベースの容量から考えて定期的に質問を削除するように考えております。 4番の画像ファイルというのは画像、動画、PDF それぞれにあったタグに Javascript で変更するということでしょうか? サーバー側のコードは bbs_que_list.php を想定しております。 ※最新コード https://wandbox.org/permlink/a5reYrjPHQnrGXXi

その他の回答 (42)

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.42

・これを個数にすると $("#content").append("<div>画像</div><div>タイトル</div>"); 画像とタイトルで1括りにできないのではないかと思いました。 私のサンプルは質問者さま(参考サイト)のコードをもってきただけです。 個数にする必要はないと思います。 個数を気にされているようですが、参考サイトの、  <input type="hidden" id="count" value=0> や、  $("#content").append(add_content); は、現在何個表示しているかを保持しているだけのものです。 何個表示している、つまり、次のデータ取得でスキップする個数です。 参考サイトはコントロール(input)を使っていますが、 使わなくてもできそうな気がしています。 あと、私のサンプルではいただいたコードをそのままで試しましたが、 jQueryを使っているので、正直なところ、書き方がわかりません。 無限スクロールについてはこのままでもいいのですが、 非同期通信については以前のようなJavaScript標準の書き方にしたいところです。 そうすれば、doneとfailの問題もなくなるような気がします。

php_learn
質問者

補足

Q.参考サイトはコントロール(input)を使っていますが、 使わなくてもできそうな気がしています。 あと、私のサンプルではいただいたコードをそのままで試しましたが、 jQueryを使っているので、正直なところ、書き方がわかりません。 無限スクロールについてはこのままでもいいのですが、 非同期通信については以前のようなJavaScript標準の書き方にしたいところです。 そうすれば、doneとfailの問題もなくなるような気がします。 A.回答ありがとうございます、全体の流れはクライアント(bbs_quest_input.php)入力フォームで送信 → サーバー(bbs_que_list.php)で受け取る → 表示という流れになりそうです。 調べたところ方法が2つありフォームで送信するか個数をカウントする方法のどちらかのようです… フォームで送信する方法は恐らく不可能に近いと感じております… Ajax で質問者の情報を送信する必要がある為です。 アップロードファイルと画像の判定を区別させてファイルが安全か確かめるコードとスタンプ選択のコードも Javascript で実装する必要があり個数でスクロールを実装する方が簡単だと思いました。 上記とは別の方法になるのですが、Wordpress の記事として登録することで無限スクロールを実装する方法もあるようですが、現在の記事やその他のコンテンツにも影響が出る可能性があり難しいのではないかと考えております… ※Ajaxを使ってデータベースのデータを非同期で取得する https://rimane.net/ajax-mysql-1021/ ※Formの各入力要素からJSでデータを取得したうえで、AJAXを使って送信 https://docs-f.mix-soft.com/manual/input-form/formnokarajsdedtawoshitauedeajaxwotte ※WordPressで無限スクロールで記事を読み込む方法 https://haniwaman.com/infinite-scroll/ ※bbs_quest_input.php に実装して bbs_que_list.php に送信するコード <script> // 各要素への参照を取得。 const $form = $("#form"); const $attach = $(".attach"); const $question = $("#question"); const $title = $("#title"); const $stamp = $("#stamp"); const $attach = $(".attach"); const $name = $("#name"); // form要素の送信(submit)イベントにイベントリスナー(ハンドラー)を登録 $form.on("submit", (event) => { // 1. デフォルトのフォーム送信の動きを止める(prevent) event.preventDefault(); // 2. input要素(name="name"の要素)の現在の値(= 入力値)を取得。 const attach = $attach.val(); const question = $question.val(); const title = $title.val(); const stamp = $stamp.val(); const attach = $attach.val(); const name = $name.val(); // 3. AJAXを使ってデータ送信する。 $.ajax({ // 送信先のURL(HTMLのform要素のactionに相当する部分) url: "./bbs_que_list.php", // 送信するデータ。デフォルトでは "GET" リクエストなので、クエリ文字列(パラメータ)として付与される。 data: { "attach": "attach","question": "question","title": "title","stamp": "stamp","attach": "attach","name": "name" } }).then((response) => { // id="result"な要素のテキストを取得したAPIのレスポンスで置き換える。 $("#result").text(JSON.stringify(response)); }); }); </script> ※Wordpress の記事として登録することで無限スクロールを実装できると思われるコード <script> $ajax_query = $wpdb->prepare( array( 'post_type' => 'post', 'posts_per_page' => $posts_per_page, 'offset' => $offset, ) ); </script>

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.41
php_learn
質問者

補足

サンプルページありがとうございます。 実装したい機能と全く同じようです。サンプルページを見るとスクロールの高さで制御しているようですが、これを個数にすると $("#content").append("<div>画像</div><div>タイトル</div>"); 画像とタイトルで1括りにできないのではないかと思いました。 何か良い解決策はありますでしょうか?

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.40

非同期通信でデータを取得してどうのこうのはあとまわしにして。 無限スクロールの処理だけ質問一覧に実装してみてはどうでしょうか。

php_learn
質問者

補足

回答ありがとうございます。 無限スクロールのみコードを修正してみました。 ※test.phpに3パターンのコードを書きました。 https://wandbox.org/permlink/zQ2b7l3MA69TqAz8

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.39

・HTML 出力されたコンテンツ件数をカウントしてスクロール1段分の件数でイベントが発火する仕組みになっているように見えます。 画像とタイトルで1カウントとして計算することは可能なのでしょうか? 私が勝手に1段分と思っていましたが、関係ないようですね。 例えば1段に横に並んで3つコンテンツがあるとか、そう言うのを想像していました。 コードを見る限りそんなのは関係なく、単純に現在いくつコンテンツを追加したかでしか見ていないようです。 1コンテンツをどう見るかは自由です。 画像とタイトルで1カウントすればいいだけです。 と言うか、何も考えなくても自然とそうなってくるはずです。 ここですね。  count += data.length dataは取得したデータです。 lengthはそのデータの数です。 今回取得したデータの数をcountに加算しています。 1データが画像とタイトルのセットになっていれば、それで1カウントです。 生成するHTMLの要素とは直接関係ないので画像用のタグとタイトル用のタグでとか考えなくて大丈夫です。

php_learn
質問者

補足

Q.1コンテンツをどう見るかは自由です。 画像とタイトルで1カウントすればいいだけです。 と言うか、何も考えなくても自然とそうなってくるはずです。 A.回答ありがとうございます、合わせて1カウントにする場合 document.querySelectorAll()で指定する必要があるな気がしていたのですが、それを参考サイトのコードと組み合わせる方法が分かりませんでした… Q.ここですね。  count += data.length dataは取得したデータです。 lengthはそのデータの数です。 今回取得したデータの数をcountに加算しています。 1データが画像とタイトルのセットになっていれば、それで1カウントです。 生成するHTMLの要素とは直接関係ないので画像用のタグとタイトル用のタグでとか考えなくて大丈夫です。 A.説明ありがとうございます、画像とタイトルそれぞれの Div タグでカウントされるのではないかと勘違いしておりました。 セットで可能ということで覚えておきます。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.38

・セキュリティの面で非同期通信処理の.fail(function(e){ に不安がある為、修正を考えております。 Promise を使うように参考サイトでは推奨しているのですが、バインドパラムは使わないようにしたので、代用方法について質問してみる予定です。 参考サイトにはセキュリティについては書かれていないように思います。 セキュリティで言うと、プレースホルダーはそのためだったのなら実装してください。 以前やった通りです。どこかで以下のような書き方をしたと思います。 $sql = 'SELECT * FROM sortable ORDER BY ID LIMIT %d, 8'; $query = $wpdb->prepare($sql, $count); 非同期通信については質問入力画面と同じでいいと思います。 //非同期通信 fetch(url, opt) .then(response => { return response.json(); }) .then(json => { }) .catch(error => { console.log(error); });

php_learn
質問者

補足

回答ありがとうございます、参考サイトを見ると PHP のデータベースでプレースホルダーは必要なく、Javascript で必要だったようで申し訳ありません。 コードを考えてみたのですが間違っているところなどありますでしょうか? ※test.phpに考えたコードを書いてみました。 https://wandbox.org/permlink/zQ2b7l3MA69TqAz8 ※参考サイト https://www.agent-grow.com/self20percent/2021/08/03/php%E3%81%A8ajax%E3%81%A7%E7%84%A1%E9%99%90%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.37

SQL文に間違いがあったので訂正します。 $sql = "SELECT * FROM sortable ORDER BY ID DESC LIMIT {$count}, 8";

php_learn
質問者

補足

A.修正ありがとうございます。 参考サイトのコードから複数分からないところがあるのですが、dell_ok さんはどのようなコードだと思われますでしょうか? セキュリティの面で非同期通信処理の.fail(function(e){ に不安がある為、修正を考えております。 Promise を使うように参考サイトでは推奨しているのですが、バインドパラムは使わないようにしたので、代用方法について質問してみる予定です。 ※非同期処理のdone, failを卒業する https://qiita.com/wwwy/items/a7e9408c046f581b954d 上記とは別にコードを使用する際に不安視していることがあります。 HTML 出力されたコンテンツ件数をカウントしてスクロール1段分の件数でイベントが発火する仕組みになっているように見えます。 画像とタイトルで1カウントとして計算することは可能なのでしょうか?それぞれ別の要素として2カウントされてしまうのではないかと思い infinite scroll のライブラリを使用する方法しか選択肢がないのではないかと諦めておりました。 1.sample.php の38行目 // ドキュメント全体の高さ - 表示行きの高さ + スクロールした距離 / ドキュメント全体の高さ var scroll_pos = (document_h - window_h) / document_h ; 2.sample.php の59行目 data:{ count : count } 3.sample.php の64行目 add_content += "<div>"+val.content+"</div>"; //追加するコンテンツ ※最新コード https://wandbox.org/permlink/eGI3IvMNKUr9QwUG

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.36

・下記の方法だと Ajax で POST 送信されたコンテンツの数を計算するようで、データベースの質問数をカウントする方法だと難しいのではないかと感じております。 可能だと思われますでしょうか? 可能だと思います。 ・SQL の $count の値が変動する(条件が動的なSQL)ためプレースホルダーにする必要があるようで、バインドパラムするところでつまずいております… 無理にプレースホルダーにしなくても構いません。 SQL文はとりあえずこうしておいてください。  $sql = "SELECT * FROM sortable ORDER BY ID DESC LIMIT {$count}, {$count} + 8"; ただし、この 8 と言うのは、非同期通信で何件取得するかと言うことになりますので、スクロール1段分の件数になると思われます。 このような一連のデータの一部を取得する際には順序が重要になってきますので ORDER BY は必須です。 とりあえず、新しい順にしておきましょう。 これは不要です。  $content_arr = $stmt->fetchAll(PDO::FETCH_ASSOC); 同じことが、すでにこれでできているからです。  $rows = $wpdb->get_results($query);

php_learn
質問者

補足

Q.このような一連のデータの一部を取得する際には順序が重要になってきますので ORDER BY は必須です。 とりあえず、新しい順にしておきましょう。 これは不要です。  $content_arr = $stmt->fetchAll(PDO::FETCH_ASSOC); 同じことが、すでにこれでできているからです。  $rows = $wpdb->get_results($query); A.修正ありがとうございます。数を指定する際には ORDER BY は必須ということで覚えておきます。 get_results が同じ役割になるんですね勉強になりました。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.35

・ajaxを使う方法とIntersection Observer (IEでは動作しない)を使う方法の2つを見つけたのですが、どちらがよいと思われますでしょうか? どちらでもいいような気はしますが、 後者の参考サイトはPHPとのやりとりが書かれていないので、 参考にするのは難しいと思います。 私は詳しくないので、質問者さまが実装されてどうなるかです。 エラーになればコードをいただいて私の環境で試してなにかしらを判断することはできるとは思います。 どちらも非同期通信をするはずですが、 間にWordPressがあるので以前やった方法を参考にPHP側は実装してみてください。

php_learn
質問者

補足

回答ありがとうございます、色々と調べてみたのですが方法としては1つしかなさそうです。 下記の方法だと Ajax で POST 送信されたコンテンツの数を計算するようで、データベースの質問数をカウントする方法だと難しいのではないかと感じております。 dell_ok さんは可能だと思われますでしょうか? コードを応用できないか考えていたのですが、SQL の $count の値が変動する(条件が動的なSQL)ためプレースホルダーにする必要があるようで、バインドパラムするところでつまずいております… // 配列取得 $content_arr = $stmt->fetchAll(PDO::FETCH_ASSOC); ※queryとprepareの違いについて https://qiita.com/yamatetsu0418/items/511c6202731a4a9aab0b ※PHPとajaxで無限スクロール https://www.agent-grow.com/self20percent/2021/08/03/php%E3%81%A8ajax%E3%81%A7%E7%84%A1%E9%99%90%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/ ※修正中のコード getContent.php <?php header("Content-type: application/json; charset=UTF-8"); // コンテンツ件数 $count = $_POST["count"]; // DB接続 $sql = " SELECT count(*) AS q FROM sortable LIMIT $count, $count + 8 "; // 実行結果取得 $query = $wpdb->prepare($sql); $rows = $wpdb->get_results($query); //現在のアップロードディレクトリ(パス名)を取得 $upload_dir = wp_upload_dir(); // 配列取得 $content_arr = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($content_arr); //SQLインジェクションの対策 exit; ?> ______________________________ 上記とは別に Javascript と PHP で無限スクロールを作る方法を探してみたのですが、ajax で RSS から記事データを抽出して使う方法だった為、データベースから取得したコンテンツには使えそうにないようです… Ajax と Mysql を両方使う方法が何故難しいのか調べたところ、画面を表示してからバックエンドの言語であるPHPで操作しているからだと書かれておりました。 質問一覧表示画面のコンテンツを表示する場合 Javascript で行うのが適切なようです。 ※Javascript&PHP 無限スクロール https://comment-out.net/2023/02/11/1550.html ※Jacascript と PHP を併用するのはなぜ難しいのか https://qiita.com/yamakawacho/questions/a4de16f4bbb82bf076e8 _______________________________ Ajax を使わずに Wordpress で無限スクロールを実装する方法で1つだけ可能だと思われる方法を見つけたのですが、infinite scroll というライブラリを使用するようです。 ※参考サイト https://www.webdesignleaves.com/pr/wp/wp-using-chatgpt-01.html

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.34

・全体に1つ div を設定するために foreach ($rows as $row) {} のループの外に echo '<div>'; echo '</div>'; を追加しております。 HTMLは下記のようにすることに致しました。 実行して期待通りになったのならそれでいいと思います。 私は実行していませんが、こうなると予想しています。 <div> <div>がぞう</div> <div>たいとる</div> <div>がぞう</div> <div>たいとる</div> <div>がぞう</div> <div>たいとる</div> <div>がぞう</div> <div>たいとる</div> <div>がぞう</div> <div>たいとる</div> </div> 無限スクロールを実装される予定のようなので、PHPのここの処理はまったく不要になりますが、 JavaScriptで実装するにしても、手書きのHTMLは重要ですので、 上記のイメージが正しいのかどうか考えてみてください。

php_learn
質問者

補足

回答ありがとうございます、上記のイメージ通りになります。

  • dell_OK
  • ベストアンサー率13% (766/5720)
回答No.33

・以前記事の方に設定した際とは異なり記事のIDがないため実行できるのか不安です。 以前のコードがどうなっていたかわからないのですが ID は関係ないような気がしています。 関係あるとしても sortable にも ID はあるので使えるのではないでしょうか。

php_learn
質問者

補足

回答ありがとうございます。 ページネーションについて調べたところ、最近では無限スクロール型を採用しているサイトが多いようで、PC 以外でサイトを閲覧している方が見やすいようになっているようです。 デメリットとして Javascript で作成するため SEO に認知されないようですが、メイン記事でしっかり集客すれば問題ないとの理由で流行しているとのことでした。 上記の理由から無限スクロールで作成しようと考えております。 ajaxを使う方法とIntersection Observer (IEでは動作しない)を使う方法の2つを見つけたのですが、どちらがよいと思われますでしょうか? 初めは ajax を使う方法で作成したいと考えていたのですが、<input type="hidden" id="count" value=0>が使われており// コンテンツ件数 $count = $_POST["count"]; を取得する方法が送信?となっているようで、どのような流れで作られているのか分からず、Intersection Observer の方が良いのではないかと考えております。 ※PHPとajaxで無限スクロール https://www.agent-grow.com/self20percent/2021/08/03/php%E3%81%A8ajax%E3%81%A7%E7%84%A1%E9%99%90%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/ ※Intersection Observerで無限スクロール https://weblasts.com/javascript/intersection-observer

関連するQ&A