getFormData(STATEFULID_INPUTNAME); if($stateFulID!=""){ $this->startStateFul($stateFulID,true); } $this->callMethod('onLoad',$this->eventDetailsID); # 全イベント共通起動処理 $this->callMethod($this->actionEvent,$this->eventDetailsID); # アクションイベント処理 $this->callMethod('onUnLoad',$this->eventDetailsID); # 全イベント共通終了処理 } # イベント名取得 function getEventName(&$data){ # GET/POSTデータからイベント名を抽出する foreach(array_keys($data) as $key){ if(preg_match("/^".EVENT_ON_CLICK."/",$key)>0){ # イベント名取得 $this->actionEvent = preg_replace('|^'.EVENT_ON_CLICK.'|','',$key); if(preg_match('/^[a-z0-9\\_]+\\_on[a-z]+$/i',$this->actionEvent)!=1){ # onclick補正 $this->actionEvent .= "_onClick"; } if(is_array($data[$key])){ # 明細番号取得 list($this->eventDetailsID) = array_keys($data[$key]); } # イベント取得成功 return true; } } # イベント取得失敗 return false; } # Value値を取得 function &getValue($name,$direct=false){ $detailName = $this->getDetailName($name); if($detailName!='' and $direct==false){ if(is_array($this->getValueDefine($name,'details'))){ $this->errorDie('Details Set Error ['.$name.']'); } # Details対応Value $value = &$this->value[$name][$this->getValue($detailName)]; } else{ $value = &$this->value[$name]; } if($this->getIsFile($name)==true) return $value['id']; return $value; } # Value値を格納 function setValue($name,$value,$valueMode=false,$directSet=false){ if($valueMode == VALUE_SESSION and !is_object($this->getSession())){ $this->startSession(); } $mode = $valueMode; if($mode===false) $mode = $this->defaultValueMode; $detailName = $this->getDetailName($name); if($detailName!='' and $directSet==false){ # Details対応Value $this->value[$name][$this->getValue($detailName)] = &$value; } else{ # 非DetailsValue / 直接Value格納 $this->value[$name] = &$value; } if(!is_null($mode)){ $this->valueSet[$mode][$name] = &$this->value[$name]; } } # getUrl(stateFul対応) function getUrl($url,$event="",$para=null,$stateFul=false){ $url = parent::getUrl($url,$event,$para); if($stateFul==true){ if(strpos($url,'?')===false) $url .= '?'.STATEFULID_INPUTNAME.'='.urlencode($this->stateFulID); else $url .= '&'.STATEFULID_INPUTNAME.'='.urlencode($this->stateFulID); } return $url; } # redirect(stateFul対応) function redirect($url,$event="",$para=null,$stateFul=false){ $url = $this->getUrl($url,$event,$para,$stateFul); parent::redirect($url); } # タグ取得 function &getTag($name,$tagName=null){ $tagText = parent::getTag($name,$tagName); # タグ名取得 $tagName = $this->getTagDefine($name); # 定義情報取得 $tagDefine = $this->valueDefine[$name]; if($tagName=='form' and c4_array_value($tagDefine,'stateFul')==true){ # ステートフル用Formタグ if($this->stateFulID==""){ $this->errorDie('StateFul対応Formタグ生成に失敗しました。StateFulが開始されていません。「'.$name.'」'); } $tagText .= ''; } return $tagText; } # フォームデータ単一取得 function getFormValue($name){ if($this->getIsFile($name)==true){ $this->setValue($name,$this->getFileData($name),false,true); return true; } $iName = $this->getInputName($name); $this->setValue($name,$this->getFormData($iName),false,true); } # Value名称に対応するInput Nameを取得(出力用) function getOutputName($name){ $id=''; $detailName = $this->getDetailName($name); if($detailName!=''){ # Details対応Value $id='['.$this->getValue($detailName).']'; } if($this->getValueDefine($name,'inputName') != ""){ return $this->getValueDefine($name,'inputName').$id; } elseif($this->inputNameEncodeFlag==true){ return $this->getNameEncode($name).$id; } else{ return $name.$id; } } # ************************************************** # StateFul機能 # ************************************************** # StateFul開始処理 function startStateFul($stateFulID=null,$loadOnly=false){ if(!is_object($this->getSession())){ $this->startSession(); } $session = &$this->getSession(); $this->stateFulSet = &$session->sessionLink(STATEFUL_KEY); if(!is_array($this->stateFulSet)){ # stateFulSetを初期化 $this->stateFulSet=array(); } # Load Onlyのエラー判定 if($loadOnly==true){ if(!isset($this->stateFulSet[$stateFulID])){ $this->errorDie('指定されたStateFul領域が見つかりません。StateFulID「'.$stateFulID.'」'); } elseif(is_numeric($this->stateFulSet[$stateFulID])){ $status = $this->stateFulSet[$stateFulID]; if($status==0){ $this->errorDie('指定されたStateFul領域は既に無効です。StateFulID「'.$stateFulID.'」'); } elseif($status==1){ $this->errorDie('指定されたStateFul領域は最大保持件数を超えた為破棄されました。StateFulID「'.$stateFulID.'」'); } else{ $this->errorDie('指定されたStateFul領域で致命的なエラーが発生しました。StateFulID「'.$stateFulID.'」'); } } } $st_id_count=0; $st_enabled_count=0; foreach(array_reverse(array_keys($this->stateFulSet)) as $st_id){ $st_id_count++; if($st_id_count>=MAX_STATEFUL_ID){ # 全ステートフルIDの最大保持件数超過分を削除 unset($this->stateFulSet[$st_id]); } if(is_array($this->stateFulSet[$st_id])){ $st_enabled_count++; if($st_enabled_count>=MAX_STATEFUL_ENABLED){ # 有効ステートフルの最大保持件数超過分を破棄 $this->stateFulSet[$st_id] = 1; } } } # StateFulIDが未指定の場合、StateFulIDを生成 if(is_null($stateFulID)) $stateFulID=md5(uniqid(rand(),1)); $this->stateFulID = $stateFulID; # StateFulIDでstateFulデータを取得 $stateFul = &$this->stateFulSet[$stateFulID]; if(!is_array($stateFul)) $stateFul = array(); # StateFulValue接続 $this->valueSet[VALUE_STATEFUL] = &$stateFul[VALUE_STATEFUL]; if(!is_array($this->valueSet[VALUE_STATEFUL])){ # 新規StateFulを初期化 $this->valueSet[VALUE_STATEFUL]=array(); } else{ # 再開StateFulをvalueに反映 foreach(array_keys($this->valueSet[VALUE_STATEFUL]) as $key){ $this->value[$key] = &$this->valueSet[VALUE_STATEFUL][$key]; } } # StateFulで維持するメンバ変数を接続 foreach(explode('/',STATEFUL_MEMBER) as $member){ $this->{$member} = &$stateFul[$member]; } $this->defaultValueMode = VALUE_STATEFUL; return $stateFulID; } # StateFul終了処理 function endStateFul($stateFulID=null){ if(is_null($stateFulID)) $stateFulID = $this->stateFulID; if(!is_object($this->getSession())){ $this->errorDie('セッション未確立時にendStateFulが実行されました'); } $session = &$this->getSession(); $this->stateFulSet = &$session->sessionLink(STATEFUL_KEY); if(!is_array($this->stateFulSet)){ $this->errorDie('endStateFulの実行時にStateFul領域が見つかりませんでした。'); } if(!isset($this->stateFulSet[$stateFulID])){ $this->errorDie('endStateFulで指定されたStateFul領域が見つかりません。StateFulID「'.$stateFulID.'」'); } elseif(is_numeric($this->stateFulSet[$stateFulID])){ $status = $this->stateFulSet[$stateFulID]; if($status==0){ $this->errorDie('endStateFulで指定されたStateFul領域は既に無効です。StateFulID「'.$stateFulID.'」'); } elseif($status==1){ $this->errorDie('endStateFulで指定されたStateFul領域は最大保持件数を超えた為破棄済みです。StateFulID「'.$stateFulID.'」'); } else{ $this->errorDie('endStateFulで指定されたStateFul領域で致命的なエラーが発生しました。StateFulID「'.$stateFulID.'」'); } } if(is_array($this->stateFulSet[$stateFulID])){ # 指定ステートフル領域を無効化 $this->stateFulSet[$stateFulID] = 0; } $this->stateFulID = null; unset($this->valueSet[VALUE_STATEFUL]); $this->defaultValueMode = DEFAULT_VALUEMODE; return $stateFulID; } # ************************************************** # Details機能 # ************************************************** # Detail定義格納 function setDetails($name,$details){ $this->setValueDefine($name,'details',$details); foreach($details as $dName){ # Detailカラムを初期化 if(!is_array($this->getValue($dName,true))) $this->setValue($dName,array(),false,true); $this->setDetailName($dName,$name); } } # Detail定義取得 function getDetails($name){ return $this->getValueDefine($name,'details'); } # Detail名格納 function setDetailName($name,$detailName){ $this->setValueDefine($name,'detailName',$detailName); } # Detail名取得 function getDetailName($name){ return $this->getValueDefine($name,'detailName'); } # Detail追加 function addDetails($name,$detailValues=array(),$id=null){ $details = $this->getDetails($name); $detailKey = array_shift($details); $detailKeyValue = &$this->getValue($detailKey,true); # DetailKeyを初期化 if(!is_null($id) and isset($detailKeyValue[$id])){ $this->errorDie('追加DetailIDが重複しています。DetailID「'.$id.'」'); } # 新規行作成 $value = array_shift($detailValues); if(is_null($id)){ # DetailID自動発行 $detailKeyValue[] = $value; $detailPointer = $detailKeyValue; end($detailPointer); $id = key($detailPointer); } else{ # 指定DetailID使用 $detailKeyValue[$id] = $value; } # 追加DetailIDにポインタセット $this->setValue($name,$id); # DetailValuesを各Valueに格納 foreach($details as $dName){ $value = array_shift($detailValues); $this->setValue($dName,$value); } return $id; } # Detail挿入 function insertDetails($name,$targetID,$detailValues=array(),$id=null){ # 指定Detail追加 $id = $this->addDetails($name,$detailValues,$id); # 指定位置へ順移動 $details = $this->getDetails($name); $detailKey = array_shift($details); $detailKeyValue = &$this->getValue($detailKey,true); $newDetailKeyValue = array(); $newValue = $detailKeyValue[$id]; unset($detailKeyValue[$id]); foreach(array_keys($detailKeyValue) as $key){ if($targetID===$key){ $newDetailKeyValue[$id] = $newValue; } $newDetailKeyValue[$key] = $detailKeyValue[$key]; } $detailKeyValue = $newDetailKeyValue; return $id; } # Detail追加 function deleteDetails($name,$id){ $details = $this->getDetails($name); # ポインタを二つ戻す list($detailKey) = $details; $detailKeyValue = &$this->getValue($detailKey,true); if(!is_array($detailKeyValue)) return false; prev($detailKeyValue); prev($detailKeyValue); # 指定要素の消去 foreach($details as $dName){ $detailValue = &$this->getValue($dName,true); if(is_array($detailValue)) unset($detailValue[$id]); } # 次のポインタを返す return $this->nextDetails($name); } # Detialポインタを次へ進める function nextDetails($name){ $details = $this->getDetails($name); $detailKey = array_shift($details); $detailKeyValue = &$this->getValue($detailKey,true); if(!is_array($detailKeyValue)) return false; $pointer = each($detailKeyValue); if($pointer===false){ $this->resetDetails($name); return false; } $id = $pointer['key']; $this->setValue($name,$id); return true; } # Detialポインタを先頭へ戻す function resetDetails($name){ $details = $this->getDetails($name); $detailKey = array_shift($details); $detailKeyValue = &$this->getValue($detailKey,true); if(!is_array($detailKeyValue)) return false; reset($detailKeyValue); return true; } # ************************************************** # File機能 # ************************************************** # Value名称に対応するIsFile属性を取得 function getIsFile($name){ return $this->getValueDefine($name,'isFile'); } # Value名称に対応するIsFile属性を格納 function setIsFile($name,$isFile){ $this->setValueDefine($name,'isFile',$isFile); } # Value名称に対応するFileDefine取得 function getFileDefine($name){ return $this->getValueDefine($name,'fileDefine'); } # Value名称に対応するFileDefine格納 function setFileDefine($name,$fileDefine){ $this->setValueDefine($name,'fileDefine',$fileDefine); } # 既存ファイルをFile値としてロード function loadFile($name,$file){ if(!file_exists($file)) return false; $fileID = $this->getValue($name); if($fileID=="") $fileID = md5(uniqid(rand(),1)); $info = array( 'id' => $fileID, 'name' => $file, 'type' => 'localfile', 'size' => filesize($file), 'error' => null); if(!copy($file,C4_FILE_INFO_PATH.'/'.$fileID)) return false; chmod(C4_FILE_INFO_PATH.'/'.$fileID,C4_FILE_MOD); $this->saveFileInfo($info); $this->setValue($name,$info); return true; } # File値のデータを保存 function saveFile($name,$file,$chmod=null,$reset=false){ $fileID = $this->getValue($name); if(!copy(C4_FILE_INFO_PATH.'/'.$fileID,$file)) return false; if(is_null($chmod)) $chmod = C4_FILE_MOD; chmod($file,$chmod); # File値をリセット if($reset) $this->resetFile($name); return true; } # File値を消去 function resetFile($name,$valueMode=false){ $value = $this->getValue($name); $this->setValue($name,array()); $fName=C4_FILE_INFO_PATH.'/'.$value; if(file_exists($fName) and $value!=""){ unlink($fName); } if(file_exists($fName.'.txt') and $value!=""){ unlink($fName.'.txt'); } } # FileInfo値を取得 function &getFileInfo($name){ $detailName = $this->getDetailName($name); if($detailName!=''){ # Details対応Value $value = &$this->value[$name][$this->getValue($detailName)]; } else{ $value = &$this->value[$name]; } return $value; } # ファイルデータ取得 function getFileData($name){ $inputName = $this->getInputName($name); $fileInfo = $this->getFormData($inputName.'__info'); $fileInfo = $this->arrayMethod('loadFileInfo',$fileInfo); if(!is_array($fileInfo)) $fileInfo = array(); if(isset($_FILES[$inputName])){ call_user_func_array(array(&$this,'makeFileInfo'),array($_FILES[$inputName],&$fileInfo)); } return $fileInfo; } # ファイル管理情報読込 function loadFileInfo($fileID){ list($fileID) = explode('/',$fileID); $infoName = C4_FILE_INFO_PATH.'/'.$fileID.'.txt'; $fileName = C4_FILE_INFO_PATH.'/'.$fileID; if($fileID!="" and file_exists($infoName) and file_exists($infoName)){ if($f = @fopen($infoName,'r')){ $info = ''; while (!feof ($f)) { $info .= fread($f, 4096); } $info = unserialize($info); fclose($f); # 最終更新日 touch($infoName); touch($fileName); return $info; } } return array(); } # ファイル管理情報保存 function saveFileInfo($fileInfo){ if($fileInfo['id']=="") return false; if($f = @fopen(C4_FILE_INFO_PATH.'/'.$fileInfo['id'].'.txt','w')){ fwrite($f,serialize($fileInfo)); fclose($f); chmod(C4_FILE_INFO_PATH.'/'.$fileInfo['id'].'.txt',C4_FILE_MOD); return true; } return false; } # ファイル管理情報作成 function makeFileInfo($fileData,&$fileInfo){ if(isset($fileData['tmp_name'])){ if(is_array($fileData['tmp_name'])){ foreach(array_keys($fileData['tmp_name']) as $key){ if(!isset($fileInfo[$key])) $fileInfo[$key] = array(); if(call_user_func_array(array(&$this,'moveUploadFile'),array($fileData['tmp_name'][$key],&$fileInfo[$key]['id']))){ $fileInfo[$key]['name'] = $fileData['name'][$key]; $fileInfo[$key]['type'] = $fileData['type'][$key]; $fileInfo[$key]['size'] = $fileData['size'][$key]; $fileInfo[$key]['error'] = $fileData['error'][$key]; $this->saveFileInfo($fileInfo[$key]); } } } else{ if(!is_array($fileInfo)) $fileInfo = array(); if($this->moveUploadFile($fileData['tmp_name'],$fileInfo['id'])){ $fileInfo['name'] = $fileData['name']; $fileInfo['type'] = $fileData['type']; $fileInfo['size'] = $fileData['size']; $fileInfo['error'] = $fileData['error']; $this->saveFileInfo($fileInfo); } } } } # テンポラリファイル取得 function moveUploadFile($tmpFile,&$fileID){ if($tmpFile != "" and file_exists($tmpFile)){ if($fileID=="") $fileID = md5(uniqid(rand(),1)); if(move_uploaded_file($tmpFile,C4_FILE_INFO_PATH.'/'.$fileID)){ chmod(C4_FILE_INFO_PATH.'/'.$fileID,C4_FILE_MOD); return true; } else{ return false; } } return false; } # ファイルプレビューイベント function filePreview_onClick(){ $this->setInputName('fileID','id'); $this->getFormValue('fileID'); $fileID = $this->getValue('fileID'); list($fileID) = explode('/',$fileID); if(preg_match('/^[0-9a-f]+$/',$fileID)!=1) return false; $fileInfo = $this->loadFileInfo($fileID); if(count($fileInfo)>0){ $fName = C4_FILE_INFO_PATH.'/'.$fileID; if(file_exists($fName)){ mb_http_output("pass"); if(preg_match('/\\.(jpe?g|gif|png)$/i',$fileInfo['name'],$matches)==1){ $ext = $matches[1]; $type = preg_replace('|jpg|i','jpeg',$matches[1]); header("Content-type: image/".$type); } else{ if(preg_match('/\\.([a-z0-9]+)$/i',$fileInfo['name'],$matches)==1) $ext = $matches[1]; else $ext = ''; header("Content-type: application/octet-stream"); } header("Content-Disposition: inline; filename=".$fileID.".".$ext); header("Content-length: " . filesize($fName)); readfile($fName); $this->standardOutFlag = true; } } } # ファイルアップロード(C4Spread用)イベント function fileUpload_onClick($idName){ list($id,$name) = c4_explode('.',$idName,2); list($time,$fileId) = c4_explode('_',$id,2); $fileInfoId = preg_replace('/\_c4Data$/','_c4FileId',$fileId); $this->setIsFile($name,true); $this->setInputName($name,$name); $this->getFormValue($name); $value = $this->getValue($name); if($value!='') $status='0'; else $status='1'; $js=<<<__JAVASCRIPT function complete(){ var d = window.parent.document; var iframe = d.getElementById('$id'); if('$status'=='0'){ var info = d.getElementById('$fileInfoId'); info.value='$value'; } iframe.setAttribute('c4status','$status'); } __JAVASCRIPT; $meta = ''; $body = ''; $html = ''.$meta.''.$body.''; $this->out($html); } # ************************************************** # Mail機能 # ************************************************** # メールオブジェクト生成 function &createSendMail($sendMailStr=null){ if(is_null($sendMailStr)) $sendMailStr=C4_SENDMAIL_DEFAULT_STR; list($className,$params) = c4_explode(':',$sendMailStr,2); $fileName = C4_BASE_PATH.'/tool/c4_mail.function.php'; $this->includeFunction($fileName,"c4_mailparse_rfc822_parse_addresses"); $mObj = &$this->createPlugin('sendmail',$className,$sendMailStr,$params); return $mObj; } # メール送信処理(実メールデータ指定) function sendMail(&$data,$rcptTo=null,$returnPath=null,$sendMailStr=null){ $mObj = &$this->createSendMail($sendMailStr); return $mObj->sendmail($data,$rcptTo,$returnPath); } # メールデータ作成 function &makeMessage($body,$to=null,$from=null,$subject=null,$header=null,$fileList=array()){ $fileName = C4_BASE_PATH.'/tool/c4_mail.function.php'; $this->includeFunction($fileName,"c4_make_message"); $mes = &c4_make_message($body,$to,$from,$subject,$header,$fileList); return $mes; } # 簡易メール送信 function sendMessage($body,$to=null,$from=null,$subject=null,$header=null,$fileList=array(),$returnPath=null,$bcc=null,$sendMailStr=null){ $mObj = &$this->createSendMail($sendMailStr); # メールデータ生成 $mes = &$this->makeMessage($body,$to,$from,$subject,$header,$fileList); if($mes[1]===false){ $this->lastError['C4EAction::sendMessage'] = $mes[2]; return false; } # RCPT TO 宛先リスト生成 $rcptTo = implode(',',$mes[0]); if(!is_null($bcc) and $bcc!="") $rcptTo .= ','.$bcc; $rcptTo=trim($rcptTo); if($rcptTo==""){ $this->lastError['C4EAction::sendMessage'] = '[RCPT TO] address not exists'; return false; } $mes[1] = preg_replace("/^\./","..",$mes[1]); if($mObj->sendmail($mes[1],$rcptTo,$returnPath)===false){ $this->lastError['C4EAction::sendMessage'] = $mObj->getMessage(); return false; } return true; } # テンプレートメール送信 # メール送信実行(Viewテンプレート指定) function sendViewMessage($view,$to=null,$from=null,$subject=null,$fileList=array(),$returnPath=null,$bcc=null,$sendMailStr=null){ $mail = $this->execViewVariableTxt($view); $tDie = &$this->getTemplateDie(); if(!$tDie){ $mail = str_replace("\r\n","\n",$mail); $header=null; $body = null; $splitMail = explode("\n\n",$mail,2); if(count($splitMail)==2){ $firstLine = strpos($splitMail[0]."\n","\n"); $firstHeader = strpos($splitMail[0],":"); if($firstHeader>0 and $firstHeader<$firstLine){ $header=$splitMail[0]; $body=$splitMail[1]; } } if(is_null($body)) $body = &$mail; if(!$this->sendMessage($body,$to,$from,$subject,$header,$fileList,$returnPath,$bcc,$sendMailStr)) $tDie=true; } return !$tDie; } # 入力データ退避 function getInputInfo(){ $port = ""; if((C4_PROTOCOL=='http' and C4_SERVER_PORT!=80) or (C4_PROTOCOL=='https' and C4_SERVER_PORT!=443)){ $port = ":".C4_SERVER_PORT; } $url = C4_PROTOCOL."://".C4_SERVER_NAME.$port.c4_server_path('REQUEST_URI'); $method = c4_server_path('REQUEST_METHOD'); $getData = ""; foreach(array_keys($_GET) as $key){ $getData .= urlencode($key).'='.urlencode(mb_convert_encoding($_GET[$key],$this->outputCharset,$this->innerCharset)); } if($getData!="") $url .= '?'.$getData; $postData = ""; if($method=='POST'){ foreach(array_keys($_POST) as $key){ $postData .= ''; } } return array($method,$url,$postData); } # ************************************************** # Spread機能 # ************************************************** function outSpreadData(){ $paraNames = func_get_args(); $this->spreadDataCount++; $this->out(implode("&",$this->encodePara($paraNames))."\n"); } function outSpreadStatus($status,$message=""){ $this->spreadDataCount++; $this->out('*&COUNT='.$this->spreadDataCount.'&STATUS='.urlencode($status).'&MESSAGE='.urlencode($message)."\n"); } } ?>