データのサニタイジング(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("/\&/", "/\%/", "/\</", "/\>/", "/\"/", "/\'/", "/\(/", "/\)/", "/\+/", "/\-/"); + $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以下には、ライブラリの拡張が置けそうな場所はないので、
強いてどちらか、といえばモデルかな、と思ったのでビヘイビアにしてみました。
でも、実際使ったのはコントローラから;