エクスプレスエントリーデータダウンロードを外部フォームから実行したい
フォーラムの皆さま
いつも大変お世話になっております。
外部フォームブロックに、Expressエンティティを選択できる
リストボックスを作成し、選択したエンティティをCSVファイル
としてダウンロードしたいと考えております。
通常の、ダッシュボードからエクスプレスエンティティ詳細画面
にアクセスし、「CSVデータダウンロード」を実行することと同じ
機能を外部フォームで実現したいと思いますが、
可能でしょうか?
現在考えておりますのは、
・外部フォームのリストボックスのvalue にエンティティ名を設定
・submit 実行時、Express エンティティ名(value)を postして
コントローラ側へ渡す
・コントローラで受け取ったエンティティ名を引数にして、
Expressエンティティのデータを取得して配列に格納
・CSVファイルとしてサーバ上に出力➡ダウンロード
という手順です。
ぜひご教示賜ればと存じます。
どうぞよろしくお願い申し上げます。
# concrete5 Version
Core Version - 8.5.4
Version Installed - 8.5.4
Database Version - 20200609145307
# Database Information
Version: 5.1.73
SQL Mode:
# concrete5 Packages
CSV User Import & Export (0.1.1), Honest Websites Back To Top (1.1.0), Login/Logout Link (1.0), Login Page Background (0.9.1), Manual Nav (2.3.3), Migration Tool (0.9.1)
# concrete5 Overrides
blocks/external_form/form/controller/tkp_menu.php, blocks/external_form/form/controller/enq_a.php, blocks/external_form/form/controller/enq_b.php, blocks/external_form/form/controller/enq_c.php, blocks/external_form/form/controller/shukai.php, blocks/external_form/form/controller/enqopt.php, blocks/external_form/form/controller/emenu.php, blocks/external_form/form/controller/mailtmp.php, blocks/external_form/form/controller/csvdwn.php, blocks/external_form/form/controller, blocks/external_form/form/tkp_menu.php, blocks/external_form/form/enq_a.php, blocks/external_form/form/enq_b.php, blocks/external_form/form/enq_c.php, blocks/external_form/form/shukai.php, blocks/external_form/form/enqopt.php, blocks/external_form/form/emenu.php, blocks/external_form/form/mailtmp.php, blocks/external_form/form/csvdwn.php, blocks/external_form/form, blocks/external_form, mail/mail_send_hyoka_a.php, mail/mail_send_hyoka_b.php, mail/mail_2tmp.php, mail/mail_1tmp.php, mail/mail_3tmp.php, mail/mail_4tmp.php
# concrete5 Cache Settings
Block Cache - Off
Overrides Cache - On
Full Page Caching - Off
Full Page Cache Lifetime - Every 6 hours (default setting).
# Server Software
Apache
# Server API
apache2handler
# PHP Version
7.3.15
# PHP Extensions
apache2handler, bcmath, bz2, calendar, Core, ctype, curl, date, dba, dom, enchant, exif, fileinfo, filter, ftp, gd, gettext, gmp, hash, iconv, imap, intl, json, ldap, libxml, mbstring, mcrypt, mysqli, mysqlnd, odbc, openssl, pcre, PDO, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, recode, Reflection, session, shmop, SimpleXML, snmp, soap, sockets, SPL, sqlite3, standard, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, wddx, xml, xmlreader, xmlrpc, xmlwriter, xsl, Zend OPcache, zip, zlib
# PHP Settings
max_execution_time - 3600
log_errors_max_len - 4096
max_file_uploads - 100
max_input_nesting_level - 64
max_input_time - 60
max_input_vars - 1000
memory_limit - 256M
post_max_size - 384M
upload_max_filesize - 256M
ldap.max_links - Unlimited
mbstring.regex_stack_limit - 100000
mysqli.max_links - Unlimited
mysqli.max_persistent - Unlimited
odbc.max_links - Unlimited
odbc.max_persistent - Unlimited
pcre.backtrack_limit - 1000000
pcre.recursion_limit - 100000
pgsql.max_links - Unlimited
pgsql.max_persistent - Unlimited
session.cache_limiter - no value
session.gc_maxlifetime - 7200
soap.wsdl_cache_limit - 5
opcache.max_accelerated_files - 4000
opcache.max_file_size - 0
opcache.max_wasted_percentage - 5
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
おはようございます。
いつも大変お世話になり、ありがとうございます。
情報のご共有、まことにありがとうございます。
早速拝見させていただきます。
coreのCSV出力周りのコードを参照するという
観点に気づいておりませんでした。
aniyaさま、いつもありがとうございます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
いつもお世話になっております。
先日の週間concrete5 配信内容を参考に、取り急ぎ、Expressエンティティ
の属性名を取得して、リストからそれぞれの入力データをgetUserid();などの
メソッドで取得し、エントリーデータをループすることでcsvファイルとして
出力することはできました。
logs.php での csvファイル作成方法が大変役立ちました。
ありがとうございました。
引き続き、エンティティ名別にエントリーデータを動的に取得する方法
を試行中でございます。
完成いたしましたら、ご報告させていただきます
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
いつも大変お世話になっております。
先週の週刊concrete5を拝聴させていただき、大変勉強になりました。
ありがとうございます。
番組内でご説明いただいた、エンティティのIDを取得しようと試みて
おります。
hissyさんよりご説明いただいた、
public function csv_export($treeNodeParentID = null){
$me = $this;
$parent = $me->getParentNode($treeNodeParentID);
$entity = $me->getEntity($parent);
...
}
において、$treeNodeParentID が、MYSQLの「ExpressEntities」テーブル
における "id" に該当すると思うのですが、違いますでしょうか?
hissyさんがご説明下さっているのは、ダッシュボードのExpressエンティティ
詳細画面でエントリーデータ一覧を表示させているため、
$me->getParentNodeID() で表示しているExpressエンティティのエントリー
データの親ID(エンティティID)を取得していると思うのですが、これを
エントリーリストから取得するとしますと、
まず、$entity = Express::getObjectByHandle('●●●●');
●●●●はエンティティのハンドル名
でエンティティ情報を取得してきて、そのデータのIDを
$id = $entity->getID();
で取得すればよいように考えたのですが、この考えは間違っておりますで
しょうか?
ExpressEntitiesテーブルの「id」が取得できれば、あとは、
public function csv_export と同じ方法でcsvファイルの作成ができると
考えております。
どうぞよろしくお願い申し上げます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
$entity までは取れているようでしたので、そのあと必要な部分だけをハイライトでお送りしました。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
viewのリストボックスで取得したエンティティ名(ハンドル名)を
controller側へ渡して$entname に代入し、エントリーデータを取得しようと
いたしました。
ところが、下記コードを実行しましても、CSVダウンロードのための
ダイアログボックス自体も表示されません。
なんの反応もない状態でございます。
コードの解釈が間違えていると思います。
$input['csvent'] に、viewで選択したエンティティ名'enqa'を渡しているのですが、
これが原因でしょうか?
ご教示いただければ幸いです。
public function action_submit(){
//CSV作成対象エンティティの取得
$input['csvent'] = $this->post('csvent');
if (isset($input['csvent']) && $input['csvent'] != ''){
$entname = $input['csvent'];
}
$entity = Express::getObjectByHandle($entname);
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename=' . $entity->getHandle() . '.csv',
];
$config = $this->app->make('config');
$bom = $config->get('concrete.export.csv.include_bom') ? $config->get('concrete.charset_bom') : '';
$datetime_format = $config->get('concrete.export.csv.datetime_format');
return StreamedResponse::create(function () use ($entity, $me, $bom, $datetime_format) {
$entryList = new EntryList($entity);
$writer = $this->app->make(CsvWriter::class, [
$this->app->make(WriterFactory::class)->createFromPath('php://output', 'w'),
new Date()
]);
echo $bom;
$writer->insertHeaders($entity);
$writer->insertEntryList($entryList,$datetime_format);
}, 200, $headers);
}
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
return StreamedResponse::create(function () use ($entity, $me, $bom, $datetime_format) {
...
}
を
$response = StreamedResponse::create(function () use ($entity, $me, $bom, $datetime_format) {
...
}
$response->send();
と変更すれば動きそうです
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
おはようございます。ありがとうございます。
2/12の週刊concrete5において、katzさんより、
viewから渡したエンティティハンドル名がどのように
なっているかなど、var_dump で確認してみてくださいと
教えていただきましたので、それぞれの変数を確認して
見ました。
var_dump($entname);
exit();
としたところ、$entname は、予定通り、エンティティのハンドル
名が渡っておりました。
その後、return StreamedRespons::create~
の上の行までは、正常に値が取れておりました。
return StreamedRespons::create~で何も取得できていない状態
になっておりましたので、教えていただいた方法で検証させて
いただきます。ありがとうございます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
参照クラスを以下のように設定し、コードを変更いたしました。
そうしますと、「このサイトにアクセスできません。
ウェブページは一時的に停止しているか、新しいウェブアドレスに移動した可能性があります。」と表示されました(添付ファイル)。
参照クラス設定か、どこかで間違えている可能性もあるかと存じます。
どこが原因か、お教えいただけますと幸いでございます。どうぞよろしくお願い
申し上げます。
参照クラス・名前空間
namespace Application\Block\ExternalForm\Form\Controller;
use Concrete\Core\Controller\AbstractController;
use Concrete\Core\Csv\WriterFactory;
use Concrete\Core\Express\Export\EntryList\CsvWriter;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Concrete\Core\Entity\Express\Entity;
use Concrete\Core\Express\EntryList;
use Core;
use UserInfo;
use User;
use Express;
public function action_submit(){
//CSV作成対象エンティティの取得
$input['csvent'] = $this->post('csvent');
$me = $this;
if (isset($input['csvent']) && $input['csvent'] != ''){
$entname = $input['csvent'];
}
//$fileName = $entname.' download file';
$entity = Express::getObjectByHandle($entname);
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename=' . $entity->getHandle() . '.csv',
];
$config = $this->app->make('config');
$bom = $config->get('concrete.export.csv.include_bom') ? $config->get('concrete.charset_bom') : '';
$datetime_format = $config->get('concrete.export.csv.datetime_format');
//ここまでのすべての変数は、中身が正常に取れておりました
$response = StreamedResponse::create(function () use ($entity, $me, $bom, $datetime_format) {
$entryList = new EntryList($entity);
$writer = $this->app->make(CsvWriter::class, [
$this->app->make(WriterFactory::class)->createFromPath('php://output', 'w'),
new Date()
]);
echo $bom;
$writer->insertHeaders($entity);
$writer->insertEntryList($entryList,$datetime_format);
}, 200, $headers);
$response->send();
$this->set('message', 'csvダウンロードが終了しました。');
}
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
おはようございます。ありがとうございます!!できました!!
昨日投稿した「ページが表示できません」メッセージについては、
参照するクラスが抜けていたことが原因のようでございます。
ご迷惑をおかけいたしました(;^_^A
hissyさんのお教え通りに、$response = StreamRsponse::create(function () use...)
と致しまして、
$response->send(); を実行することで、ダイアログが表示され、無事ダッシュボード
と同じ機能が実現できました。
気になったところと致しましては、この方法でダウンロードしたcsvファイルを
ExcelからUTF-8で読み込んでみますと、
HTMLタグが一緒に吐き出されておりました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="/tkp_system/concrete/themes/elemental/css/bootstrap-modified.css">
<link href="/tkp_system/application/files/cache/css/elemental/main.css?ts=1599545416" rel="stylesheet" type="text/css" media="all">・・・
そこで、
$response->send();
の後にdie関数をかませることで、防止することができました。
$response->send();
die();
これで何とか解決できました。
hissyさん、katzさん、aniyaさん、フォーラムの皆さん、本当に
ありがとうございました。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
適切に処理を終了してくれます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
いつもご支援いただき、感謝申し上げます。
週間concrete5 での配信内容を参考に、まず
logs.phpの public function csv を確認いたしました。
ここでのcsvファイル作成方法については、ほぼ予想通り、
CSVファイルオープン後、データのヘッダ行を$rows[]に
挿入、その後、各データ行を1行ずつ $rows[] に追加していく
ものでした。
そこでお聞きしたいことが、いま、エンティティが3つある
としまして、外部フォームのセレクトボックス(A、B、C)
を選択し、エンティティ名Aが選択された場合、エンティティ
Aのヘッダ行およびデータ行を取得します。
このとき、エンティティAの属性(例えば5つあるとして)名の
取得と、
エンティティのlistを取得した場合、
$results = $list->getResults();
で取得したリストから、それぞれの属性で入力された値の取得
if (count($results)){
foreach ($results as $rowdata){
$zokusei1 = $rowdata->getUserid();
$zokusei2 = $rowdata->getUsername();
...
}
}
のgetUserid(); などを動的に定義したいと思いますが、この
方法が思い至っておりません。
Expressエントリーをそもそも、リストで取得していることが
間違えているような気がいたします。
お分かりの方がいらっしゃいましたら、ぜひお教えください。
どうぞよろしくお願い申し上げます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
concrete5 には CSV のインポート・エクスポートを行うライブラリ League/CSV ライブラリが同梱していて、こっちを使うとよりスマートに、CSV の出力を行うことができます。
全然、説明が無いのですが、
CSV でユーザーのインポート・エクスポートができるアドオンがあるので、
これを参考にエクスポートの部分を調整してもらえればと思います。
http://github.com/concrete5cojp/addon_csv_user_import_export
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
管理画面からのエクスポートと同じ機能ですよね?
このコードをコピペすればそのまま同じ機能です。
http://github.com/concrete5/concrete5/blob/8.5.4/concrete/src/Page/Controller/DashboardExpressEntriesPageController.php#L99-L117
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
http://www.youtube.com/watch?v=aDoR-AOtKAQ
29:25あたりを参照してみてください。
基本的にはhishikawaさんのアドバイスを参照してください、というまとめですが、
コードに関する具体的な補足説明を行っています。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
このクラスはconcrete5のコア機能で、エクスプレスエントリーをエクスポートするためにあらかじめ作られています。
逆に、私のアドオンが参考にならないのは、私のアドオンが使っているCsvWriterが外部ライブラリで、しかもconcrete5には同梱されていないものだからです。
以上、誤解を招いてはいけないと思い、補足しておきます。
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
いつもご支援を賜りまして、ありがとうございます。
今回の週間concrete5を拝聴し、hissyさんからご教示いただいた、Githubのコードを
確認させていただき、ExpressのCSVエクスポートの動きが理解できてまいりました。
external formのリストボックスで選択したExpressエンティティ(番号)を引数として
csvライブラリに渡して検証してみたいとおもいます。
concrete5には、フォームヘルパーやメールヘルパーと同様に、CsvWriterのような強力
なライブラリが最初から備わっているのは、本当に助かります。
1からphpコードを書くことに比べ、開発効率が格段に上がります。
ありがとうございます。頑張って解決いたします。
aniya
Re: エクスプレスエントリーデータダウンロードを外部フォームから実行したい
http://www.youtube.com/watch?v=svT42Rfvc3g
01:14:08あたりを参照してみてください。