Posted on

PDF出力で時間がかかる場合に「処理中...」表示する

CAKEPHP2で、PDF作成時にその作成している間だけ、処理中...を表示するサンプルを記入します。
まずDBを追加します。

  1. CREATE TABLE IF NOT EXISTS `sessions` (  
  2.   `session_id` text  
  3. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;  

custom.css

  1. ・  
  2. ・  
  3. ・  
  4. div#loading {  
  5.     position : absolute;  
  6.     top : 20%;  
  7.     left : 50%;  
  8. }  
  9. ・  
  10. ・  
  11. ・  

bootstrap.php

  1. ・  
  2. ・  
  3. ・  
  4. define('ROOT_URL', preg_replace('/index\.php/''', env('SCRIPT_NAME')));  
  5. ・  
  6. ・  
  7. ・  

default.ctp

  1. ・  
  2. ・  
  3. ・  
  4.     <link type="text/css" rel="stylesheet" href="<?php echo ROOT_URL ?>css/custom.css">  
  5. ・  
  6. ・  
  7. ・  
  8. <script type="text/javascript">  
  9.     var rootUrl = "<?php echo $this->Html->url('/') ?>";  
  10. </script>  
  11. <div id="loading" style="display:none;"><img decoding="async" src="<?php echo ROOT_URL ?>img/wait.gif">  
  12. 処理中・・・・</div>  
  13. ・  
  14. ・  
  15. ・  
  16. <script>  
  17.     // PDF出力時に処理中の表示処理 下記xxxxは作成されているコントローラ名を記載ください。  
  18.     function LoadingMsg() {  
  19.         if(confirm('PDF作成に1から5分程度の時間を要します。本当に実行しますか?')) {  
  20.             $("#loading").css("display""block");  
  21.             $.get(rootUrl + "xxxx/ajax_session_save"function (data) {  
  22.                 var json = $.parseJSON(data);  
  23.                 if (json.RES == 0) {  
  24.                     loop();  
  25.                 } else {  
  26.                     $("#loading").css("display""none");  
  27.                 }  
  28.             });  
  29.         } else {  
  30.             return false;  
  31.         }  
  32.     }  
  33.     // 処理中表示を続けるかを判定する。 下記xxxxは作成されているコントローラ名を記載ください。  
  34.     var timerID  
  35.     function loop() {  
  36.         timerID = setTimeout(loop,1000);  
  37.   
  38.         $.get(rootUrl + "xxxx/ajax_session_get"function (data) {  
  39.             var json = $.parseJSON(data);  
  40.             if (json.RES == -1) {  
  41.                 $("#loading").css("display","none");  
  42.                 clearTimeout(timerID);  
  43.             }  
  44.         });  
  45.     }  
  46.   
  47. </script>  

xxxxController.php

  1. function detail($id$step){  
  2. (isset($this->request->data['out'])) {  
  3.         $info = PDF出力する情報を取得処理を記述する。  
  4.         if (!emptyempty($info)) {  
  5.             $this->autoRender = false;  
  6.             $this->layout = false;  
  7.             $this->set('info'$info);  
  8.             $this->render('pdf_out');  
  9.         } else {  
  10.             $this->モデル名->invalidate('error'"データがありません。");  
  11.             $this->autoRender = true;  
  12.             $this->layout = 'default';  
  13.         }  
  14.     }     
  15. }  
  16.   
  17. /** 
  18.  * セッション保存 
  19.  * 
  20.  * @note 
  21.  */  
  22. function ajax_session_save() {  
  23.     Configure::write('debug', 0);  
  24.     $this->autoRender = false;  
  25.   
  26.     $id = $this->Session->id();  
  27.     $sql = "INSERT INTO sessions (`session_id`) VALUE (:id);";  
  28.     $sqlArr['id'] = $id;  
  29.     $jsonResult = array();  
  30.     if (false === $this->モデル名->query($sql,$sqlArr)) {  
  31.         $jsonResult['RES'] = -1;  
  32.     } else {  
  33.         $jsonResult['RES'] = 0;  
  34.     }  
  35.     echo json_encode($jsonResult);  
  36.     exit;  
  37. }  
  38.   
  39. /** 
  40.  * セッション確認 
  41.  * 
  42.  * @note 
  43.  */  
  44. function ajax_session_get() {  
  45.     Configure::write('debug', 0);  
  46.     $this->autoRender = false;  
  47.   
  48.     $id = $this->Session->id();  
  49.     $sql = "select * from sessions WHERE session_id = :id;";  
  50.     $sqlArr['id'] = $id;  
  51.   
  52.     $jsonResult = array();  
  53.     $res = $this->モデル名->query($sql,$sqlArr);  
  54.     if (!emptyempty($res)) {  
  55.         $jsonResult['RES'] = 0;  
  56.     } else {  
  57.         $jsonResult['RES'] = -1;  
  58.     }  
  59.     echo json_encode($jsonResult);  
  60.     exit;  
  61. }  
  62.   
  63. /** 
  64.  * render直後の処理 
  65.  * 
  66.  * @note 
  67.  */  
  68. public function afterFilter() {  
  69.     $id = $this->Session->id();  
  70.     $sql = "delete from sessions WHERE session_id = :id;";  
  71.     $sqlArr['id'] = $id;  
  72.     $res = $this->モデル名->query($sql,$sqlArr);  
  73. }  

detail.ctp

  1. ・  
  2. ・  
  3. ・  
  4.     <input type="submit" name="out" id="out" value="出力" onclick="LoadingMsg();">  
  5. ・  
  6. ・  
  7. ・  

PDF作成処理はこのブログでは触れませんが、
結論から言うとsession_idがDBに保存されている間は、PDF出力処理中になるようにします。
出力ボタンが押下された時点で、本当に実行してよいかを問い、実行してよい場合は、当該のsession_idをDBに追加します。
renderで呼ばれた処理が終了すると、PDF出力が終わったことになり、CAKEPHP2では、
afterFilter()が呼ばれます。そこで、DBから該当のsession_idを消します。
表示VIEWでは、session_idが存在する間、処理中...を表示としておき、
DBからsession_idが削除されれば、処理中...を消すことで完成となります。