PageRenderTime 219ms CodeModel.GetById 33ms app.highlight 84ms RepoModel.GetById 46ms app.codeStats 1ms

/baser/plugins/mail/models/message.php

https://github.com/hashing/basercms
PHP | 740 lines | 390 code | 103 blank | 247 comment | 56 complexity | bb46819cd1373d50200d6b62bbe480f1 MD5 | raw file
  1<?php
  2/* SVN FILE: $Id$ */
  3/**
  4 * メッセージモデル
  5 *
  6 * PHP versions 5
  7 *
  8 * baserCMS :  Based Website Development Project <http://basercms.net>
  9 * Copyright 2008 - 2012, baserCMS Users Community <http://sites.google.com/site/baserusers/>
 10 *
 11 * @copyright		Copyright 2008 - 2012, baserCMS Users Community
 12 * @link			http://basercms.net baserCMS Project
 13 * @package			baser.plugins.mail.models
 14 * @since			baserCMS v 0.1.0
 15 * @version			$Revision$
 16 * @modifiedby		$LastChangedBy$
 17 * @lastmodified	$Date$
 18 * @license			http://basercms.net/license/index.html
 19 */
 20/**
 21 * Include files
 22 */
 23App::import('Model', 'MailField');
 24/**
 25 * メッセージモデル
 26 *
 27 * @package baser.plugins.mail.models
 28 *
 29 */
 30class Message extends MailAppModel {
 31/**
 32 * クラス名
 33 *
 34 * @var string
 35 * @access public
 36 */
 37	var $name = 'Message';
 38/**
 39 * ビヘイビア
 40 * 
 41 * @var array
 42 * @access public
 43 */
 44	var $actsAs = array('BcCache');
 45/**
 46 * メールフォーム情報
 47 *
 48 * @var array
 49 * @access public
 50 */
 51	var $mailFields = null;
 52/**
 53 * Constructor.
 54 *
 55 * @return void
 56 * @access private
 57 */
 58	function __construct($id = false, $table = null, $ds = null, $tablePrefix = null) {
 59
 60		if($tablePrefix) {
 61			$cm =& ConnectionManager::getInstance();
 62			if(!empty($cm->config->plugin['prefix'])) {
 63				$dbPrefix = $cm->config->plugin['prefix'];
 64			}else {
 65				$dbPrefix = '';
 66			}
 67			$this->tablePrefix = $dbPrefix.$tablePrefix;
 68		}
 69		parent::__construct();
 70
 71	}
 72/**
 73 * beforeSave
 74 *
 75 * @return boolean
 76 * @access public
 77 */
 78	function beforeSave() {
 79
 80		$this->data = $this->convertToDb($this->data);
 81		return true;
 82
 83	}
 84/**
 85 * バリデート処理
 86 *
 87 * @param	array	$options
 88 * @return 	array
 89 * @access	public
 90 * TODO beforeValidateに移行できないか検討
 91 */
 92	function invalidFields($options = array()) {
 93
 94		$data = $this->data;
 95
 96		$this->_setValidate();
 97		parent::invalidFields($options);
 98
 99		// Eメール確認チェック
100		$this->_validEmailCofirm($data);
101		// 不完全データチェック
102		$this->_validGroupComplate($data);
103		// 拡張バリデートチェック
104		$this->_validExtends($data);
105		// バリデートグループエラーチェック
106		$this->_validGroupErrorCheck();
107		// エラー内容変換
108		$this->_validSingeErrorCheck();
109
110		return $this->validationErrors;
111
112	}
113/**
114 * validate(入力チェック)を個別に設定する
115 * VALID_NOT_EMPTY	空不可
116 * VALID_EMAIL		メール形式チェック
117 *
118 * @return void
119 * @access protected
120 * TODO Cake1.2に対応させる
121 */
122	function _setValidate() {
123
124		foreach($this->mailFields as $mailField) {
125
126			if($mailField['MailField']['valid']&&!empty($mailField['MailField']['use_field'])) {
127				if(defined($mailField['MailField']['valid'])) {
128					$this->validate[$mailField['MailField']['field_name']] = constant($mailField['MailField']['valid']);
129				}else {
130					$this->validate[$mailField['MailField']['field_name']]=$mailField['MailField']['valid'];
131				}
132			}
133
134		}
135
136	}
137/**
138 * 拡張バリデートチェック
139 *
140 * @param array $data
141 * @return void
142 * @access protected
143 */
144	function _validExtends($data) {
145
146		$dists = array();
147
148		// 対象フィールドを取得
149		foreach($this->mailFields as $mailField) {
150
151			if(!empty($mailField['MailField']['use_field'])) {
152				// マルチチェックボックスのチェックなしチェック
153				if($mailField['MailField']['valid_ex']=='VALID_NOT_UNCHECKED') {
154					if(empty($data['Message'][$mailField['MailField']['field_name']])) {
155						$this->invalidate($mailField['MailField']['field_name']);
156					}
157					$dists[$mailField['MailField']['field_name']][] = @$data['Message'][$mailField['MailField']['field_name']];
158
159					// datetimeの空チェック
160				}elseif($mailField['MailField']['valid_ex']=='VALID_DATETIME') {
161					if(empty($data['Message'][$mailField['MailField']['field_name']]['year']) ||
162							empty($data['Message'][$mailField['MailField']['field_name']]['month']) ||
163							empty($data['Message'][$mailField['MailField']['field_name']]['day'])) {
164						$this->invalidate($mailField['MailField']['field_name']);
165					}
166				}
167			}
168		}
169
170	}
171/**
172 * エラー内容変換
173 *
174 * @return void
175 * @access protected
176 */
177	function _validSingeErrorCheck() {
178
179		foreach($this->validate as $key => $data) {
180
181			// VALID_NOT_EMPTY以外は形式エラーとする
182			if($data != '/.+/') {
183				if(isset($this->validationErrors[$key])) {
184					$this->invalidate($key.'_format');
185				}
186			}
187
188		}
189
190	}
191/**
192 * バリデートグループエラーチェック
193 *
194 * @return void
195 * @access protected
196 */
197	function _validGroupErrorCheck() {
198
199		$dists = array();
200
201		// 対象フィールドを取得
202		foreach($this->mailFields as $mailField) {
203
204			// 対象フィールドがあれば、バリデートグループごとに配列にフィールド名を格納する
205			if($mailField['MailField']['group_valid']) {
206				$dists[$mailField['MailField']['group_valid']][] = $mailField['MailField']['field_name'];
207			}
208
209		}
210
211		// エラーが発生しているかチェック
212		foreach($dists as $key =>$dist) {
213
214			foreach($dist as $data) {
215				if(isset($this->validationErrors[$data])) {
216
217					// VALID_NOT_EMPTY以外は形式エラーとする
218					if($this->validate[$data]!='/.+/') {
219						$this->invalidate($key);
220						$this->invalidate($key.'_format');
221					}else {
222						$this->invalidate($key);
223					}
224
225				}
226			}
227
228		}
229
230	}
231/**
232 * 不完全データチェック
233 *
234 * @param array $data
235 * @return void
236 * @access protected
237 */
238	function _validGroupComplate($data) {
239
240		$dists = array();
241
242		// 対象フィールドを取得
243		foreach($this->mailFields as $mailField) {
244
245			// 対象フィールドがあれば、バリデートグループごとに配列に格納する
246			if($mailField['MailField']['valid_ex']=='VALID_GROUP_COMPLATE') {
247				$dists[$mailField['MailField']['group_valid']][] = $data['Message'][$mailField['MailField']['field_name']];
248			}
249
250		}
251		// チェック
252		// バリデートグループにおけるデータの埋まり具合をチェックし、全て埋まっていない場合、全て埋まっている場合以外は
253		// 不完全データとみなしエラーとする
254		foreach($dists as $key =>$dist) {
255			$i=0;
256			foreach($dist as $data) {
257				if($data) {
258					$i++;
259				}
260			}
261			if($i>0 && $i < count($dist)) {
262				$this->invalidate($key.'_not_complate');
263				for($j=1;$j<=count($dist);$j++) {
264					$this->invalidate($key.'_'.$j);
265				}
266			}
267		}
268
269	}
270/**
271 * Eメール確認チェック
272 *
273 * @param array $data
274 * @return void
275 * @access protected
276 */
277	function _validEmailCofirm($data) {
278
279		$dists = array();
280
281		// 対象フィールドを取得
282		foreach($this->mailFields as $mailField) {
283
284			// 対象フィールドがあれば、バリデートグループごとに配列に格納する
285			if($mailField['MailField']['valid_ex']=='VALID_EMAIL_CONFIRM') {
286				$dists[$mailField['MailField']['group_valid']][] = $data['Message'][$mailField['MailField']['field_name']];
287			}
288
289		}
290		// チェック
291		// バリデートグループにおけるデータ2つを比較し、違えばエラーとする
292		foreach($dists as $key =>$dist) {
293			list($a,$b)=$dist;
294			if($a != $b) {
295				$this->invalidate($key.'_not_same');
296				$this->invalidate($key.'_1');
297				$this->invalidate($key.'_2');
298			}
299		}
300
301	}
302/**
303 * 自動変換
304 * 確認画面で利用される事も踏まえてバリデートを通す為の
305 * 可能な変換処理を行う。
306 *
307 * @param array $data
308 * @return array $data
309 * @access public
310 */
311	function autoConvert($data) {
312
313		foreach($this->mailFields as $mailField) {
314			
315			$value = $data['Message'][$mailField['MailField']['field_name']];
316			
317			if(!empty($value)) {
318				
319				// 半角処理
320				if($mailField['MailField']['auto_convert']=='CONVERT_HANKAKU') {
321					$value = mb_convert_kana($value,'a');
322				}
323				// 全角処理
324				if($mailField['MailField']['auto_convert']=='CONVERT_ZENKAKU') {
325					$value = mb_convert_kana($value,'AK');
326				}
327				// サニタイズ
328				if(!is_array($value)) {
329					$value = str_replace('<!--','&lt;!--', $value);
330				}
331				// TRIM
332				if(!is_array($value)) {
333					$value = trim($value);
334				}
335				
336			}
337			
338			$data['Message'][$mailField['MailField']['field_name']] = $value;
339			
340		}
341
342		return $data;
343
344	}
345/**
346 * 初期値の設定をする
347 *
348 * @return array $data
349 * @access public
350 */
351	function getDefaultValue() {
352		
353		$data = array();
354
355		// 対象フィールドを取得
356		if($this->mailFields) {
357			foreach($this->mailFields as $mailField) {
358
359				// 対象フィールドがあれば、バリデートグループごとに配列に格納する
360				if(!is_null($mailField['MailField']['default_value']) && $mailField['MailField']['default_value'] !== "") {
361
362					if($mailField['MailField']['type']=='multi_check') {
363						$data['Message'][$mailField['MailField']['field_name']][0] = $mailField['MailField']['default_value'];
364					}else {
365						$data['Message'][$mailField['MailField']['field_name']] = $mailField['MailField']['default_value'];
366					}
367
368				}
369
370			}
371		}
372		return $data;
373
374	}
375/**
376 * データベース用のデータに変換する
377 *
378 * @param array $dbDatas
379 * @return array $dbDatas
380 * @access public
381 */
382	function convertToDb($dbData) {
383		
384		// マルチチェックのデータを|区切りに変換
385		foreach($this->mailFields as $mailField) {
386			if($mailField['MailField']['type']=='multi_check' && $mailField['MailField']['use_field']) {
387				if(!empty($dbData['Message'][$mailField['MailField']['field_name']])) {
388					if(is_array($dbData['Message'][$mailField['MailField']['field_name']])){
389						$dbData['Message'][$mailField['MailField']['field_name']]= implode("|",$dbData['Message'][$mailField['MailField']['field_name']]);
390					}else{
391						$dbData['Message'][$mailField['MailField']['field_name']]= $dbData['Message'][$mailField['MailField']['field_name']];
392					}
393				}
394			}
395		}
396
397		// 機種依存文字を変換
398		$dbData['Message'] = $this->replaceText($dbData['Message']);
399
400		return  $dbData;
401
402	}
403/**
404 * 機種依存文字の変換処理
405 * 内部文字コードがUTF-8である必要がある。
406 * 多次元配列には対応していない。
407 *
408 * @param string $str 変換対象文字列
409 * @return string $str 変換後文字列
410 * @access public
411 * TODO AppExModeに移行すべきかも
412 */
413	function replaceText($str) {
414
415		$ret = $str;
416		$arr = array(
417				"\xE2\x85\xA0" => "I",
418				"\xE2\x85\xA1" => "II",
419				"\xE2\x85\xA2" => "III",
420				"\xE2\x85\xA3" => "IV",
421				"\xE2\x85\xA4" => "V",
422				"\xE2\x85\xA5" => "VI",
423				"\xE2\x85\xA6" => "VII",
424				"\xE2\x85\xA7" => "VIII",
425				"\xE2\x85\xA8" => "IX",
426				"\xE2\x85\xA9" => "X",
427				"\xE2\x85\xB0" => "i",
428				"\xE2\x85\xB1" => "ii",
429				"\xE2\x85\xB2" => "iii",
430				"\xE2\x85\xB3" => "iv",
431				"\xE2\x85\xB4" => "v",
432				"\xE2\x85\xB5" => "vi",
433				"\xE2\x85\xB6" => "vii",
434				"\xE2\x85\xB7" => "viii",
435				"\xE2\x85\xB8" => "ix",
436				"\xE2\x85\xB9" => "x",
437				"\xE2\x91\xA0" => "(1)",
438				"\xE2\x91\xA1" => "(2)",
439				"\xE2\x91\xA2" => "(3)",
440				"\xE2\x91\xA3" => "(4)",
441				"\xE2\x91\xA4" => "(5)",
442				"\xE2\x91\xA5" => "(6)",
443				"\xE2\x91\xA6" => "(7)",
444				"\xE2\x91\xA7" => "(8)",
445				"\xE2\x91\xA8" => "(9)",
446				"\xE2\x91\xA9" => "(10)",
447				"\xE2\x91\xAA" => "(11)",
448				"\xE2\x91\xAB" => "(12)",
449				"\xE2\x91\xAC" => "(13)",
450				"\xE2\x91\xAD" => "(14)",
451				"\xE2\x91\xAE" => "(15)",
452				"\xE2\x91\xAF" => "(16)",
453				"\xE2\x91\xB0" => "(17)",
454				"\xE2\x91\xB1" => "(18)",
455				"\xE2\x91\xB2" => "(19)",
456				"\xE2\x91\xB3" => "(20)",
457				"\xE3\x8A\xA4" => "(上)",
458				"\xE3\x8A\xA5" => "(中)",
459				"\xE3\x8A\xA6" => "(下)",
460				"\xE3\x8A\xA7" => "(左)",
461				"\xE3\x8A\xA8" => "(右)",
462				"\xE3\x8D\x89" => "ミリ",
463				"\xE3\x8D\x8D" => "メートル",
464				"\xE3\x8C\x94" => "キロ",
465				"\xE3\x8C\x98" => "グラム",
466				"\xE3\x8C\xA7" => "トン",
467				"\xE3\x8C\xA6" => "ドル",
468				"\xE3\x8D\x91" => "リットル",
469				"\xE3\x8C\xAB" => "パーセント",
470				"\xE3\x8C\xA2" => "センチ",
471				"\xE3\x8E\x9D" => "cm",
472				"\xE3\x8E\x8F" => "kg",
473				"\xE3\x8E\xA1" => "m2",
474				"\xE3\x8F\x8D" => "K.K.",
475				"\xE2\x84\xA1" => "TEL",
476				"\xE2\x84\x96" => "No.",
477				"\xE3\x8D\xBB" => "平成",
478				"\xE3\x8D\xBC" => "昭和",
479				"\xE3\x8D\xBD" => "大正",
480				"\xE3\x8D\xBE" => "明治",
481				"\xE3\x88\xB1" => "(株)",
482				"\xE3\x88\xB2" => "(有)",
483				"\xE3\x88\xB9" => "(代)",
484		);
485
486		return str_replace( array_keys( $arr), array_values( $arr), $str);
487
488	}
489/**
490 * メール用に変換する
491 *
492 * @param array $dbDatas
493 * @return array $dbDatas
494 * @access public
495 * TODO ヘルパー化すべきかも
496 */
497	function convertDatasToMail($dbData) {
498
499		foreach($dbData['mailFields'] as $key => $value) {
500			$dbData['mailFields'][$key]['MailField']['before_attachment'] = strip_tags($value['MailField']['before_attachment']);
501			$dbData['mailFields'][$key]['MailField']['after_attachment'] = strip_tags($value['MailField']['after_attachment'],"<br>");
502			$dbData['mailFields'][$key]['MailField']['head'] = strip_tags($value['MailField']['head'],"<br>");
503			$dbData['mailFields'][$key]['MailField']['after_attachment'] = str_replace("<br />","\n",$dbData['mailFields'][$key]['MailField']['after_attachment']);
504			$dbData['mailFields'][$key]['MailField']['head'] = str_replace('<br />',"",$dbData['mailFields'][$key]['MailField']['head']);
505		}
506		foreach($this->mailFields as $mailField) {
507			if(!empty($dbData['message'][$mailField['MailField']['field_name']])) {
508				//var_dump(mb_convert_encoding($dbData['message'][$mailField['MailField']['field_name']],'SJIS','UTF-8'));
509				$dbData['message'][$mailField['MailField']['field_name']] = str_replace('<br />',"\n",$dbData['message'][$mailField['MailField']['field_name']]);
510				//$dbData['message'][$mailField['MailField']['field_name']] = mb_convert_kana($dbData['message'][$mailField['MailField']['field_name']], "K", "UTF-8");
511
512			}
513			if($mailField['MailField']['type']=='multi_check') {
514				if(!empty($dbData['message'][$mailField['MailField']['field_name']])) {
515					$dbData['message'][$mailField['MailField']['field_name']]= split("\|",$dbData['message'][$mailField['MailField']['field_name']]);
516				}
517			}
518
519		}
520
521		return $dbData;
522
523	}
524/**
525 * メッセージテーブルを作成する
526 *
527 * @param string $contentName コンテンツ名
528 * @return boolean
529 * @access public
530 */
531	function createTable($contentName) {
532
533		$db = $this->getDataSource();
534		$this->tablePrefix = $this->getTablePrefixByContentName($contentName);
535		$fullTable = $this->tablePrefix.'messages';
536		$table = str_replace($db->config['prefix'], '', $fullTable);
537		$schema = array(
538			'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'length' => 8, 'key' => 'primary'),
539			'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
540			'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL),
541			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
542		);
543		$ret = true;
544		if($contentName == 'messages') {
545			if($this->tableExists($fullTable)){
546				$ret = $db->dropTable(array('table'=>$table));
547			}
548		}
549		if(!$ret){
550			return false;
551		}
552		$ret = $db->createTable(array('schema'=>$schema, 'table'=>$table));
553		$this->deleteModelCache();
554		return $ret;
555
556	}
557/**
558 * メッセージテーブルの名前を変更する
559 *
560 * @param string $source 元コンテンツ名
561 * @param string $target 変更後コンテンツ名
562 * @return boolean
563 * @access public
564 */
565	function renameTable($source,$target) {
566
567		$db = $this->getDataSource();
568
569		$sourceName = $this->getTablePrefixByContentName($source).'messages';
570		$targetName = $this->getTablePrefixByContentName($target).'messages';
571		$sourceTable = str_replace($db->config['prefix'], '', $sourceName);
572		$targetTable = str_replace($db->config['prefix'], '', $targetName);
573
574		$ret = true;
575		if($target== 'messages') {
576			$ret = $db->dropTable(array('table'=>$targetTable));
577		}
578		if(!$ret){
579			return false;
580		}
581		$ret = $db->renameTable(array('old'=>$sourceTable, 'new'=>$targetTable));
582		
583		if($ret && $source == 'messages') {
584			$ret = $this->createTable($source);
585		}
586
587		$this->deleteModelCache();
588		return $ret;
589
590	}
591/**
592 * メッセージテーブルを削除する
593 *
594 * @param string $contentName コンテンツ名
595 * @return boolean
596 * @access private
597 */
598	function dropTable($contentName) {
599
600		$db = $this->getDataSource();
601		$this->tablePrefix = $this->getTablePrefixByContentName($contentName);
602		$fullTable = $this->tablePrefix.'messages';
603		$table = str_replace($db->config['prefix'], '', $fullTable);
604
605		if(!$this->tableExists($fullTable)){
606			return true;
607		}
608		
609		$ret = $db->dropTable(array('table'=>$table));
610		
611		if($ret && $contentName == 'messages') {
612			$ret = $this->createTable($contentName);
613		}
614		
615		$this->deleteModelCache();
616		return $ret;
617
618	}
619/**
620 * メッセージファイルにフィールドを追加する
621 *
622 * @param string $contentName
623 * @param string $field
624 * @return array
625 * @access public
626 */
627	function addField($contentName, $field) {
628
629		$fullTable = $this->getTablePrefixByContentName($contentName).$this->useTable;
630		$db = $this->getDataSource();
631		$table = str_replace($db->config['prefix'],'',$fullTable);
632		$options = array('field' => $field, 'column' => array('type'=>'text'), 'table' => $table);
633		$ret = parent::addField($options);
634		return $ret;
635
636	}
637/**
638 * メッセージファイルのフィールドを削除する
639 *
640 * @param string $contentName
641 * @param string $field
642 * @return array
643 * @access public
644 */
645	function delField($contentName, $field) {
646
647		$fullTable = $this->getTablePrefixByContentName($contentName).$this->useTable;
648		$db = $this->getDataSource();
649		$table = str_replace($db->config['prefix'],'',$fullTable);
650		$ret = parent::delField(array('field'=>$field, 'table'=>$table));
651		return $ret;
652
653	}
654/**
655 * メッセージファイルのフィールドを編集する
656 *
657 * @param string $fieldName
658 * @param string $oldFieldName
659 * @param string $newfieldName
660 * @return array
661 * @access private
662 */
663	function renameField($contentName, $oldFieldName,$newfieldName) {
664
665		$fullTable = $this->getTablePrefixByContentName($contentName).$this->useTable;
666		$db = $this->getDataSource();
667		$table = str_replace($db->config['prefix'],'',$fullTable);
668		$ret = parent::renameField(array('old'=>$oldFieldName, 'new'=>$newfieldName, 'table'=>$table));
669		return $ret;
670
671	}
672/**
673 * コンテンツ名つきのテーブルプレフィックスを取得する
674 * 
675 * @param string $contentName
676 * @return string
677 * @access public
678 */
679	function getTablePrefixByContentName($contentName) {
680
681		$db = $this->getDataSource();
682		$prefix = '';
683		if($contentName != 'messages') {
684			$prefix = $db->config['prefix'].$contentName."_";
685		} else {
686			$prefix = $db->config['prefix'];
687		}
688		return $prefix;
689
690	}
691/**
692 * メッセージ保存用テーブルのフィールドを最適化する
693 * 初回の場合、id/created/modifiedを追加する
694 * 2回目以降の場合は、最後のカラムに追加する
695 * 
696 * @param array $dbConfig
697 * @param int $mailContentId
698 * @return boolean
699 * @access public
700 */
701	function construction($mailContentId) {
702
703		App::import('Model','Mail.MailField');
704		App::import('Model','Mail.MailContent');
705		$mailFieldClass = new MailField();
706		$mailContentClass = new MailContent();
707
708
709		// フィールドリストを取得
710		$mailFields = $mailFieldClass->find('all', array('conditions' => array('MailField.mail_content_id' => $mailContentId)));
711		// コンテンツ名を取得
712		$contentName = $mailContentClass->field('name', array('MailContent.id'=>$mailContentId));
713
714		if(!$this->tableExists($this->getTablePrefixByContentName($contentName).'messages')) {
715
716			/* 初回の場合 */
717			$this->createTable($contentName);
718
719		}else {
720
721			/* 2回目以降の場合 */
722			$this->tablePrefix = $this->getTablePrefixByContentName($contentName);
723			$this->_schema = null;
724			$this->cacheSources = false;
725			$schema = $this->schema();
726			$messageFields = array_keys($schema);
727			foreach($mailFields as $mailField) {
728				if(!in_array($mailField['MailField']['field_name'], $messageFields)) {
729					$this->addField($contentName, $mailField['MailField']['field_name']);
730				}
731			}
732
733		}
734
735		return true;
736
737	}
738	
739}
740?>