データのサニタイジング(2-1) 編集画面で逆Sanitize

の記載の通り、beforeSaveで、サニタイズ(含むhtmlエンティティ化)してDBに登録できましたが・・・・。

予想通り、編集画面で表示するとフォームにはエンティティ化済みの文字列が入力されています。


escape()とhtml()の逆戻しをすればよいので探してみましたが・・・・該当するメソッドが見当たりません。
自分で作ってみました。

修正前のフォーム入力値
<i>i</i>(+-'1')
↓
修正後のフォーム入力値
<i>i</i>(+-'1')

(追記:html()逆戻しの際、タグ削除処理追加しました)


例によって差分貼り。

--- models/behaviors/sanitize_plus.php  (revision 0)
+++ models/behaviors/sanitize_plus.php  (revision 0)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * 独自のSanitize、逆Sanitizeの追加Behavoir
+ * The behavoir of the additional Sanitize rules, reverse-Sanitize rules.
+ */
+
+app::import('Sanitize');
+
+class SanitizePlusBehavior extends ModelBehavior {
+
+       var $settings = array();
+
+       function setup(&$model, $config = array()) {
+               $this->settings = $config;
+       }
+
+       /* reverse-Sanitize */
+       /* return HTML tags from HTML entities.
+        * base on ver1.2.5
+        * @param string $string Sanitized Data
+        * @param boolean $strip_all If true, Sanitized by Sanitize::stripAll(), and NO NEEW to set below 3 $args.
+        * @param boolean $strip_scripts If true, Sanitized by Sanitize::stripScripts()
+        * @param boolean $strip_images If true, Sanitized by Sanitize::stripImages()
+        * @param boolean $strip_whitespace If true, Sanitized by Sanitize::stripWhitespace()
+        * return Data reverted HTML tags
+        */
+       function restore_html(&$model, $string, $strip_all = true, $strip_scripts = true, $strip_images = true, $strip_whitespace = true) {
+               $patterns = array("/\&amp;/", "/\&#37;/", "/\&lt;/", "/\&gt;/", "/\&quot;/", "/\&#39;/", "/\&#40;/", "/\&#41;/", "/\&#43;/", "/\&#45;/");
+               $replacements = array("&", "%", "<", ">", '"', "'", "(", ")", "+", "-");
+
+               $string = preg_replace($patterns, $replacements, $string);
+
+               if ($strip_all) {
+                       $string = Sanitize::stripAll($string);
+               } else {
+                       if ($strip_scripts) {
+                               $string = Sanitize::stripScripts($string);
+                       }
+                       if ($strip_images) {
+                               $string = Sanitize::stripImages($string);
+                       }
+                       if ($strip_whitespace) {
+                               $string = Sanitize::stripImages($string);
+                       }
+               }
+
+               return $string;
+       }
+}

--- models/user.php     (revision 191)
+++ models/user.php     (working copy)
@@ -6,6 +6,7 @@
        var $actsAs = array(
                'Acl' => 'requester',
                'Cakeplus.AddValidationRule',
+               'SanitizePlus',
        );

Index: controllers/users_controller.php
===================================================================
--- controllers/users_controller.php    (revision 191)
+++ controllers/users_controller.php    
(working copy)
	function _edit($id) {
(中略)
                if (empty($this->data)) {
                        $this->data = $this->User->read(null, $id);
+
+                       $this->data['User']['name'] = $this->User->restore_html($this->data['User']['name'], true);
                }
        }

((controllers/users_controller.phpであえて$this->User->restore_html($this->data['User']['name'], true)のtrueを明示しているは、タグ処理してますよという印(自分用・・・)))


以上、追加ビヘイビアにしましたが、小一時間迷いました。


これは、コンポーネントにすべきなのかビヘイビアにすべきなのか。

  • 複数のコントローラで共有できるロジック=コンポーネント
  • 複数のモデルで共有できるロジック=ビヘイビア
  • Sanitize 「サニタイズはコアのライブラリであるため、どこからでも利用することができます。ただし、おそらくはコントローラかモデルで使うことが望ましいでしょう。」

http://book.cakephp.org/ja/view/153/Data-Sanitization


app以下には、ライブラリの拡張が置けそうな場所はないので、
強いてどちらか、といえばモデルかな、と思ったのでビヘイビアにしてみました。

でも、実際使ったのはコントローラから;