--- /dev/null
+<Files ~ "\.(phpl|phpc|hide)$">
+ Order allow,deny
+ Deny from all
+ Satisfy All
+</Files>
+<Files ~ "^ailases(|\.db)$">
+ Order allow,deny
+ Deny from all
+ Satisfy All
+</Files>
+<Files ~ "^\.ht">
+ Order allow,deny
+ Deny from all
+ Satisfy All
+</Files>
--- /dev/null
+#zubora mail address
+/^zbr\.[0-9a-zA-Z]+\.[0-9a-zA-Z]+(@.*)?$/ "|php -q -f /home/shohei/zubora/receiver.phpc"
--- /dev/null
+<?php\r
+define("PREFIX" ,"zbr");\r
+define("DB" ,"pgsql");\r
+// or define("DB","mysql");\r
+define("DB_HOST" ,"localhost");\r
+define("DB_NAME" ,"zubora");\r
+define("DB_USER" ,"zubora");\r
+define("DB_PASSWORD","password");\r
+?>\r
--- /dev/null
+<?php
+phpinfo();
+?>
--- /dev/null
+<?php
+require_once(dirname(__FILE__)."/zubora.phpl");
+
+$READY = array();
+$READY["PREFIX"] = true;
+$READY["DB"] = true;
+$READY["SCHEMA"] = true;
+$READY["MAIL"] = false;
+$READY["BOOK"] = true;
+
+$zdb = new ZuboraDB();
+
+try{
+ $zdb->connect();
+} catch (Exception $e) {
+ $READY["DB"] = false;
+}
+
+if(!$READY["DB"]){
+ //DBセッティング
+ echo "DBをセッティングしてください。";
+ exit(0);
+}
+
+try{
+ if(!$zdb->isExist(TBL_BOOKS)){
+ echo "Tableを作ります。";
+ }
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+/*
+if(!$zdb->addBalance("yokoyama","food",5000,'yokoyama@inf.shizuoka.ac.jp',"テスト")){
+ echo $zdb->ERROR;
+}*/
+if(false ===$zdb->getHimoku("yokoyama","fooxd")){
+ echo "該当費目なし";
+}else{
+ print_r($zdb->getHimoku("yokoyama","fooxd"));
+}
+/* foreach($zdb->query('SELECT * from books') as $row) {
+ print_r($row);
+}*/
+
+?>
\ No newline at end of file
--- /dev/null
+error
+
+金額欄が数字ではありません。(\e$B$J\e(B)
--- /dev/null
+<?php\r
+require_once('Mail/mimeDecode.php');\r
+require_once('Mail/RFC822.php');\r
+require_once('Mail.php');\r
+require_once(dirname(__FILE__)."/zubora.phpl");\r
+\r
+/* 基本関数 */\r
+class DBWriter{\r
+ var $prefix = PREFIX;\r
+ var $session = array();\r
+ var $writeReady = false;\r
+ var $ERROR = "";\r
+ var $zdb = null;\r
+ function DBWriter(){\r
+ $this->zdb = new ZuboraDB();\r
+ }\r
+ function decodeMail($mail){\r
+ $params = array();\r
+ $params['include_bodies'] = true;\r
+ $params['decode_bodies'] = true;\r
+ $params['decode_headers'] = true;\r
+ $decoder = new Mail_mimeDecode($mail);\r
+ try {\r
+ $mail = $decoder->decode($params);\r
+ }catch(Exception $e) {\r
+ $this->ERROR .= "メール解析時にエラーが発生しました。(".$e->getMessage().")\n";\r
+ return false;\r
+ }\r
+ if(!isSet($mail->headers['from']) or !isSet($mail->headers['to']) or !isSet($mail->headers["subject"])){\r
+ $this->ERROR .= "必要な情報がメールから取得できませんでした。\n";\r
+ return false;\r
+ }\r
+ $from = Mail_RFC822::parseAddressList($mail->headers['from']);\r
+ $from = $from[0]->mailbox.'@'.$from[0]->host;\r
+ $to = Mail_RFC822::parseAddressList($mail->headers['to']);\r
+ $to = $to[0]->mailbox.'@'.$to[0]->host;\r
+ list($mbox,$domain) = explode("@",$to);\r
+ list($prefix,$book,$himoku) = explode(PREFIX_SEP_MAIL,$mbox);\r
+ $price = $mail->headers["subject"];\r
+ $this->checkPrefix($prefix);\r
+ $this->checkBook($book,$domain);\r
+ $this->checkHimokuPrice($book,$himoku,$price);\r
+ $this->checkUser($book,$from);\r
+ if($this->ERROR != ""){\r
+ mb_language("ja");\r
+ $headers = 'From: '.$to."\r\n".\r
+ 'Reply-To: '.$to."\r\n".\r
+ 'X-Mailer: PHP/'. phpversion();\r
+ //常にメインメールアドレスに送信(携帯メールだと文字化けやサーバーにはねられる可能性がある為)$this->zdb->getMainMailAddr($from)\r
+ mail($from,mb_encode_mimeheader(mb_convert_encoding("ズボラ家計簿エラー!", "ISO-2022-JP","AUTO")),mb_convert_encoding($this->ERROR, "ISO-2022-JP","AUTO"),$headers,"-f$from");\r
+ //このエラーをもっと分かりやすくする。\r
+ return false;\r
+ }else{\r
+ $this->session["note"] = trim(mb_convert_encoding($mail->body,"UTF-8","ISO-2022-JP"));\r
+ return true;\r
+ }\r
+ }\r
+ function checkPrefix($prefix){\r
+ if(PREFIX != $prefix){\r
+ $this->ERROR .= "メールアドレスのプレフィクス指定が間違っています。(".$prefix.")\n";\r
+ }else{\r
+ $this->session["prefix"] = $prefix;\r
+ }\r
+ }\r
+ function checkBook($book,$domain){\r
+ $book = $this->zdb->getBook($book,$domain);\r
+ if(false === $book){\r
+ $this->ERROR .= "投稿アドレスドメインに対応づけられた家計簿が存在しません。\n";\r
+ }else{\r
+ $this->session["book"] = $book["book"];\r
+ }\r
+ }\r
+ function checkHimokuPrice($book,$himoku,$price){\r
+ if(!is_numeric($price)){\r
+ $this->ERROR .= "金額欄が数字ではありません。(".$price.")\n";\r
+ $price = 0;\r
+ }else{\r
+ $price = intval($price);\r
+ }\r
+ $himoku = $this->zdb->getHimoku($book,$himoku);\r
+ if(false === $himoku){\r
+ $this->ERROR .= "存在しない費目が指定されています。(".$himoku.")\n";\r
+ }else{\r
+ if(($himoku["plus"] == true and $price < 0)or($himoku["plus"] == false and $price > 0)){\r
+ $price = -1 * $price;\r
+ }\r
+ $this->session["price"] = $price;\r
+ $this->session["himoku"] = $himoku["himoku"];\r
+ }\r
+ }\r
+ function checkUser($book,$from){\r
+ $mail = $this->zdb->getMainMailAddr($from);\r
+ $isSubscribed = $this->zdb->isSubscribed($book,$mail);\r
+ if(false === $mail){\r
+ $this->ERROR .= "この家計簿で有効な送信メールアドレスではありません。(".$from.")\n";\r
+ }else{\r
+ if($isSubscribed){\r
+ $this->session["mail"] = $mail;\r
+ }else{\r
+ $this->ERROR .= "この家計簿に関連付けれていないアドレスから送信されました。(".$mail.")\n";\r
+ }\r
+ }\r
+ }\r
+ function doInsert(){\r
+ if(!$this->zdb->addBalance($this->session["book"],$this->session["himoku"],$this->session["price"],$this->session["mail"],$this->session["note"])){\r
+ $this->ERROR .= $zdb->ERROR;\r
+ }\r
+ file_put_contents(dirname(__FILE__)."/log.txt",$this->ERROR."\nsuccess\n\n"."ユーザ: ".$this->session["mail"]."\r
+金額: ".$this->session["price"]."\r
+費目: ".$this->session["himoku"]."\r
+ノート: ".$this->session["note"]."\n\n");\r
+ }\r
+ function printError(){\r
+ file_put_contents(dirname(__FILE__)."/log.txt","error\n\n".$this->ERROR);\r
+ }\r
+}\r
+\r
+$dbw = new DBWriter();\r
+if($dbw->decodeMail(file_get_contents('php://stdin'))){\r
+ $dbw->doInsert();\r
+}else{\r
+ $dbw->printError();\r
+}\r
+?>
\ No newline at end of file
--- /dev/null
+<?php\r
+require_once(dirname(__FILE__)."/configure.phpl");\r
+/* 変更不可定数 */\r
+$ZUBORA = array();\r
+define("ADDR_ECHO", 0);\r
+define("ADDR_GET_INFOMATION", 0);\r
+define("ADDR_GET_BALANCE", 1);\r
+define("DB_CONNECT",DB.":host=".DB_HOST.";dbname=".DB_NAME);\r
+define("PREFIX_SEP_DB","_");\r
+define("PREFIX_SEP_MAIL",".");\r
+define("TBL","books,users,mails,subscribes,himoku,balance");\r
+$ZUBORA["tables"] = explode(",",TBL);\r
+foreach($ZUBORA["tables"] as $table){\r
+ define("TBL_".strtoupper($table),PREFIX.PREFIX_SEP_DB.$table);\r
+}\r
+\r
+/* ライブラリ */\r
+\r
+//データベース入出力クラス\r
+class ZuboraDB{\r
+ var $isConnected = false;\r
+ var $queryResult = null;\r
+ var $pdo = null;\r
+ var $ERROR = "";\r
+ function ZuboraDB(){}\r
+ function connect(){\r
+ if(!$this->isConnected){\r
+ try{\r
+ $this->pdo = new PDO(DB_CONNECT,DB_USER,DB_PASSWORD);\r
+ $this->isConnected = true;\r
+ return true;\r
+ } catch (PDOException $e) {\r
+ $this->ERROR .= "DB connection error!: " . $e->getMessage() . "\n";\r
+ throw new Exception($this->ERROR);\r
+ }\r
+ }\r
+ }\r
+ /*\r
+ function query($sql){\r
+ $this->connect();\r
+ return $this->pdo->query($sql);\r
+ }\r
+ function closeCursor(){\r
+ return $this->pdo->closeCursor();\r
+ }\r
+ */\r
+ function isExist($table){\r
+ if (preg_match("/^[_\-a-z0-9]+$/i",$table)){\r
+ $q = $this->pdo->prepare("SELECT * FROM ".$table.";");\r
+ return $q->execute();\r
+ }else{\r
+ throw new Exception("Charactor Error!: table name must be [-_0-9a-zA-Z]+\n");\r
+ }\r
+ }\r
+ function getBook($book,$domain){\r
+ $this->connect();\r
+ $stmt = $this->pdo->prepare("SELECT * FROM ".TBL_BOOKS." WHERE book = ? and domain = ?;");\r
+ $stmt->bindParam(1, $book, PDO::PARAM_STR,30);\r
+ $stmt->bindParam(2, $domain, PDO::PARAM_STR,250);\r
+ if(!$stmt->execute()){\r
+ $er = $stmt->errorInfo();\r
+ $this->ERROR .= $er[2];\r
+ return false;\r
+ }else{\r
+ return $stmt->fetch(PDO::FETCH_ASSOC);\r
+ }\r
+ }\r
+ function getMainMailAddr($from){\r
+ $this->connect();\r
+ $stmt = $this->pdo->prepare("SELECT mail FROM ".TBL_MAILS." WHERE submail = ?;");\r
+ $stmt->bindParam(1, $from, PDO::PARAM_STR,250);\r
+ if(!$stmt->execute()){\r
+ $er = $stmt->errorInfo();\r
+ $this->ERROR .= $er[2];\r
+ return false;\r
+ }else{\r
+ $result = $stmt->fetch(PDO::FETCH_ASSOC);\r
+ if(false === $result){\r
+ $this->ERROR .= "error! mail addr not found!\n";\r
+ return false;\r
+ }else{\r
+ return $result["mail"];\r
+ }\r
+ }\r
+ }\r
+ function isSubscribed($book,$mail){\r
+ $this->connect();\r
+ $stmt = $this->pdo->prepare("SELECT * FROM ".TBL_SUBSCRIBES." WHERE book = ? and mail = ?;");\r
+ $stmt->bindParam(1, $book, PDO::PARAM_STR,30);\r
+ $stmt->bindParam(2, $mail, PDO::PARAM_STR,250);\r
+ if(!$stmt->execute()){\r
+ $er = $stmt->errorInfo();\r
+ $this->ERROR .= $er[2];\r
+ return false;\r
+ }else{\r
+ if(false === $stmt->fetch(PDO::FETCH_ASSOC)){\r
+ return false;\r
+ }else{\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ function getHimoku($book,$himoku){\r
+ $this->connect();\r
+ $stmt = $this->pdo->prepare("SELECT * FROM ".TBL_HIMOKU." WHERE book = ? and himoku = ?;");\r
+ $stmt->bindParam(1, $book, PDO::PARAM_STR,30);\r
+ $stmt->bindParam(2, $himoku, PDO::PARAM_STR,30);\r
+ if(!$stmt->execute()){\r
+ $er = $stmt->errorInfo();\r
+ $this->ERROR .= $er[2];\r
+ return false;\r
+ }else{\r
+ return $stmt->fetch(PDO::FETCH_ASSOC);\r
+ }\r
+ }\r
+ function addBalance($book,$himoku,$val,$mail,$note){\r
+ $this->connect();\r
+ $stmt = $this->pdo->prepare("INSERT INTO ".TBL_BALANCE." (id,book,himoku,val,mail,note,date) VALUES (?,?,?,?,?,?,CURRENT_TIMESTAMP);");\r
+ $stmt->bindParam(1, md5(uniqid()), PDO::PARAM_STR,32);\r
+ $stmt->bindParam(2, $book, PDO::PARAM_STR,30);\r
+ $stmt->bindParam(3, $himoku, PDO::PARAM_STR,30);\r
+ $stmt->bindParam(4, $val, PDO::PARAM_INT);\r
+ $stmt->bindParam(5, $mail, PDO::PARAM_STR,250);\r
+ $stmt->bindParam(6, $note, PDO::PARAM_STR);\r
+ if(!$stmt->execute()){\r
+ $er = $stmt->errorInfo();\r
+ $this->ERROR .= $er[2];\r
+ return false;\r
+ }else{\r
+ return true;\r
+ }\r
+ }\r
+}\r
+?>
\ No newline at end of file