-<?php
-// vim: tabstop=2:shiftwidth=2
-
-/**
- * NP_Moblog ($Revision: 1.1 $)
- * by hsur ( http://blog.cles.jp/np_cles )
- * $Id: NP_Moblog.php,v 1.1 2008-05-04 07:04:50 hsur Exp $
- *
- * Based on NP_HeelloWorld v0.8
- * http://nakahara21.com/?itemid=133
-*/
-
-/*
- * Copyright (C) 2003 nakahara21 All rights reserved.
- * Copyright (C) 2004-2007 cles All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, mamio and cles gives
- * permission to link the code of this program with those files in the PEAR
- * library that are licensed under the PHP License (or with modified versions
- * of those files that use the same license as those files), and distribute
- * linked combinations including the two. You must obey the GNU General Public
- * License in all respects for all of the code used other than those files in
- * the PEAR library that are licensed under the PHP License. If you modify
- * this file, you may extend this exception to your version of the file,
- * but you are not obligated to do so. If you do not wish to do so, delete
- * this exception statement from your version.
-*/
-
-global $DIR_LIBS;
-require_once($DIR_LIBS . 'MEDIA.php');
-
-// クラスのロード
-require_once(dirname(__FILE__).'/sharedlibs/sharedlibs.php');
-require_once('Net/POP3.php');
-require_once('Mail/mimeDecode.php');
-require_once('Mail/RFC822.php');
-
-// バージョンチェック
-$required = '4.3.0';
-if( ! version_compare(phpversion() , $required , '>=') ){
- ACTIONLOG :: add(WARNING, 'NP_MoblogはPHP>=4.3.0であることが必要です。');
-}
-
-if (!function_exists('sql_table')) {
- function sql_table($name) {
- return 'nucleus_'.$name;
- }
-}
-
-class NP_Moblog extends NucleusPlugin {
-
- // name of plugin
- function getName() {
- return 'Moblog';
- }
-
- // author of plugin
- function getAuthor() {
- return 'hsur';
- }
-
- // an URL to the plugin website
- // can also be of the form mailto:foo@bar.com
- function getURL() {
- return 'http://blog.cles.jp/np_cles/category/31/subcatid/2';
- }
-
- // version of the plugin
- function getVersion() {
- return '1.16';
- }
-
- function hasAdminArea() {
- return 1;
- }
-
- function getEventList() {
- return array('PrePluginOptionsEdit');
- }
-
- function event_PrePluginOptionsEdit(&$data) {
- switch($data['context']){
- case 'member':
- // idandcat
- $m =& MEMBER :: createFromID($data['contextid']);
- $trimChar = array(
- '=' => '',
- '|' => '',
- ';' => '',
- );
-
- $blogs = Array();
- $res = mysql_query('SELECT bnumber, bname FROM '.sql_table('blog'));
- while( $o = mysql_fetch_object($res) ){
- if( $m->isTeamMember($o->bnumber) ){
- $blogs[$o->bnumber] = $o->bname;
- }
- }
-
- $idandcatTypeInfo = '';
- foreach($blogs as $blogid => $blogname){
- $res = mysql_query('SELECT catid, cname FROM '.sql_table('category').' WHERE cblog='.$blogid);
- if( @mysql_num_rows($res) > 0) {
- while( $o = mysql_fetch_object($res) ){
- if($idandcatTypeInfo)
- $idandcatTypeInfo .= '|';
- $o->cname = strtr($o->cname, $trimChar);
- $blogname = strtr($blogname, $trimChar);
- $idandcatTypeInfo .= "{$o->cname} ({$blogname})|{$blogid},{$o->catid}";
- }
- }
- }
- if( ! $idandcatTypeInfo ){
- $idandcatTypeInfo = "!!投稿可能なblogがありません!!|0,0";
- }
-
- // collection & thumb_col
- $collections = MEDIA::getCollectionList();
- $mid = intval($m->getID());
- $collections[$mid] = 'デフォルト(useridディレクトリ)';
-
- $collectionTypeInfo = '';
- foreach( $collections as $collection => $name ){
- if($collectionTypeInfo) $collectionTypeInfo .= '|';
- $name = strtr($name, $trimChar);
- $collection = strtr($collection, $trimChar);
- $collectionTypeInfo .= "{$name}|{$collection}";
- }
-
- // set options
- foreach($data['options'] as $oid => $option ){
- switch($data['options'][$oid]['name']){
- case 'idandcat':
- $data['options'][$oid]['typeinfo'] = $idandcatTypeInfo;
- break;
- case 'collection':
- case 'thumb_col':
- $data['options'][$oid]['typeinfo'] = $collectionTypeInfo;
- break;
- }
- }
-
- break;
- default:
- // nothing
- }
- }
-
- function install() {
- $this->createMemberOption('enable', 'プラグインを有効にするか?', 'yesno', 'no');
-
- $this->createMemberOption('host', 'POP3 ホスト名', 'text', 'localhost');
- $this->createMemberOption('port', 'POP3 ポート', 'text', '110', 'numerical=true');
- $this->createMemberOption('user', 'POP3 ユーザー名', 'text', '');
- $this->createMemberOption('pass', 'POP3 パスワード', 'password', '');
- $this->createMemberOption('useAPOP', 'APOPを使用するか?', 'yesno', 'no');
-
- $this->createMemberOption('idandcat', 'Nucleusカテゴリ(Blog)', 'select', '', '');
-
- $this->createMemberOption('collection', '画像を保存するディレクトリ', 'select', '', '');
- $this->createMemberOption('thumb_col', 'サムネイルをを保存するディレクトリ', 'select', '', '');
-
- $this->createMemberOption('imgonly', 'イメージ添付メールのみ追加?', 'yesno', 'no');
- $this->createMemberOption('DefaultPublish', 'デフォルトで公開するか?', 'yesno', 'no');
-
- $this->createMemberOption('optionsKeyword', 'オプション記述開始の区切り文字', 'text', '@');
- $this->createMemberOption('blogKeyword', 'オプションでblogidを指定する場合のキー', 'text', 'b');
- $this->createMemberOption('categoryKeyword', 'オプションでカテゴリを指定する場合のキー', 'text', 'c');
- $this->createMemberOption('publishKeyword', 'オプションでストレートにpublish指定する場合のキー', 'text', 's');
-
- $this->createMemberOption('moreDelimiter', '追記にする場合の区切り文字(利用しない場合は空欄)', 'text', '');
-
- $this->createMemberOption('accept', '投稿許可アドレス(複数の場合改行で区切ってください)', 'textarea', '');
- $this->createMemberOption('acceptSubjectPrefix','投稿許可SubjectPrefix(制限無しの場合は空欄)','text','');
-
- $this->createMemberOption('nosubject', '件名がないときの題名', 'text', '');
- $this->createMemberOption('no_strip_tags', 'htmlメールの場合に除去しないタグ', 'textarea', '<title><hr><h1><h2><h3><h4><h5><h6><div><p><pre><sup><ul><ol><br><dl><dt><table><caption><tr><li><dd><th><td><a><area><img><form><input><textarea><button><select><option>');
- $this->createMemberOption('maxbyte', '最大添付量(B)', 'text', '300000', 'numerical=true');
- $this->createMemberOption('subtype', '対応MIMEタイプ(正規表現)', 'text', 'gif|jpe?g|png|bmp|octet-stream|x-pmd|x-mld|x-mid|x-smd|x-smaf|x-mpeg|pdf');
- $this->createMemberOption('viri', '保存しないファイル(正規表現)', 'text', '.+\.exe$|.+\.zip$|.+\.pif$|.+\.scr$');
- $this->createMemberOption('imgExt', '画像ファイルの拡張子(正規表現)', 'text', '.+\.png$|.+\.jpe?g$|.+\.gif$|.+\.bmp$');
-
- $this->createMemberOption('thumb_ok', 'サムネイルを使用する?', 'yesno', 'yes');
- $this->createMemberOption('W', 'サムネイルの大きさ(Width)', 'text', '120', 'numerical=true');
- $this->createMemberOption('H', 'サムネイルの大きさ(Hight)', 'text', '120', 'numerical=true');
- $this->createMemberOption('thumb_ext', 'サムネイルを作る対象画像', 'text', '.+\.jpe?g$|.+\.png$');
- $this->createMemberOption('smallW', 'アイテム内に表示する画像の最大横幅', 'text', '120', 'numerical=true');
-
- $this->createMemberOption('textTpl', 'テキストテンプレート', 'textarea', '<%body%>');
- $this->createMemberOption('withThumbTpl', 'サムネイル付きテンプレート', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%image(<%thumbUrl%>|<%thumbW%>|<%thumbH%>|)%></a></div><%body%>');
- $this->createMemberOption('withoutThumbTpl', 'サムネイルなしテンプレート', 'textarea', '<div class="leftbox"><%image(<%imageUrl%>|<%sizeW%>|<%sizeH%>|)%></div><%body%>');
- $this->createMemberOption('reductionTpl', 'サムネイルなしテンプレート(縮小)', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%image(<%imageUrl%>|<%reductionW%>|<%reductionH%>|)%></a></div><%body%>');
- $this->createMemberOption('dataTpl', 'データファイルテンプレート', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%fileName%></a></div><%body%>');
-
- $this->createOption('execMode', '動作モード', 'select', '1', '振分対応モード|0|互換モード|1');
- $this->createOption('spamCheck', 'SPAMチェックを有効にする', 'yesno', 'no');
-
- $this->createOption('interval', 'メール取得の間隔(秒)', 'text', '600', 'numerical=true');
- $this->createOption('nextUpdate', '次回更新時刻(変更できません)', 'text', '-', 'access=readonly');
- $this->createOption('lastUpdate', '最終更新時刻(UnixTimeStamp,)', 'text', '0', 'access=hidden');
- $this->createOption('debug', 'ログを出力を行うか?', 'yesno', 'no');
- }
-
- function unInstall() {}
- function getMinNucleusVersion() { return 320; }
- function getMinNucleusPatchLevel() { return 0; }
-
- // a description to be shown on the installed plugins listing
- function getDescription() {
- return '[$Revision: 1.1 $]<br />メールを拾ってアイテムを追加します。<%Moblog%>の記述のあるスキンを適用するページを開くと実行されます。<br />
- <%Moblog(link)%>と記入することでメールを取得するためのリンクを表示することができます(要ログイン)<br />
- 個人ごとに設定ができるようになりましたので「あなたの設定」か「メンバー管理」から設定を行ってください。';
- }
-
- function supportsFeature($what) {
- switch ($what) {
- case 'SqlTablePrefix' :
- case 'HelpPage':
- return 1;
- default :
- return 0;
- }
- }
-
- function _info($msg) {
- if ($this->getOption('debug') == 'yes') {
- ACTIONLOG :: add(INFO, 'Moblog: '.$msg);
- }
- }
-
- function _warn($msg) {
- ACTIONLOG :: add(WARNING, 'Moblog: '.$msg);
- }
-
- function _getEnableUserId() {
- $userOptions = $this->getAllMemberOptions('enable');
- $userIds = Array ();
- foreach( $userOptions as $userId => $value ){
- if( $value == 'yes') $userIds[] = $userId;
- }
- return $userIds;
- }
-
- function _initMediaDirByUserId($userId) {
- global $DIR_MEDIA;
-
- $this->_info(__LINE__ . ": ユーザ($userId)の初期設定");
- $this->memid = $userId;
-
- /*-- 受信メールサーバーの設定--*/
- $this->host = $this->getMemberOption($userId, 'host');
- $this->port = $this->getMemberOption($userId, 'port');
- $this->user = $this->getMemberOption($userId, 'user');
- $this->pass = $this->getMemberOption($userId, 'pass');
-
- // メールでアイテムを追加するblogのID
- $idandcat = $this->getMemberOption($userId, 'idandcat');
- list($this->blogid, $this->categoryNameOrId) = explode(",", $idandcat);
-
- $this->imgonly = ($this->getMemberOption($userId, 'imgonly') == 'yes') ? 1 : 0;
- $this->DefaultPublish = ($this->getMemberOption($userId, 'DefaultPublish') == 'yes') ? 1 : 0;
-
- /*-- メールのタイトルに各種オプションを含める場合の設定--*/
- $this->optionsKeyword = $this->getMemberOption($userId, 'optionsKeyword');
- $this->blogKeyword = $this->getMemberOption($userId, 'blogKeyword');
- $this->categoryKeyword = $this->getMemberOption($userId, 'categoryKeyword');
- $this->publishKeyword = $this->getMemberOption($userId, 'publishKeyword');
-
- // 投稿許可アドレス
- $this->accept = explode("\n", $this->getMemberOption($userId, 'accept'));
- $this->accept = Array_Map("Trim", $this->accept);
- $this->accept = Array_Map("strtolower", $this->accept);
- foreach( $this->accept as $mailAddr ){
- $this->_info(__LINE__ . "許可アドレス user:$userId, $mailAddr");
- }
-
- // 投稿許可SubjectPrefix
- $this->acceptSubjectPrefix = Trim($this->getMemberOption($userId, 'acceptSubjectPrefix'));
-
- // 追記の区切り
- $this->moreDelimiter = Trim($this->getMemberOption($userId, 'moreDelimiter'));
-
- // 件名がないときの題名
- $this->nosubject = $this->getMemberOption($userId, 'nosubject');
- $this->no_strip_tags = $this->getMemberOption($userId, 'no_strip_tags');
-
- // 最大添付量(バイト・1ファイルにつき)※超えるものは保存しない
- $this->maxbyte = $this->getMemberOption($userId, 'maxbyte');
- $this->subtype = $this->getMemberOption($userId, 'subtype');
- $this->viri = $this->getMemberOption($userId, 'viri');
- $this->imgExt = $this->getMemberOption($userId, 'imgExt');
-
- // サムネイル
- $this->thumb_ok = ($this->getMemberOption($userId, 'thumb_ok') == 'yes') ? 1 : 0;
- $this->W = $this->getMemberOption($userId, 'W');
- $this->H = $this->getMemberOption($userId, 'H');
- $this->thumb_ext = $this->getMemberOption($userId, 'thumb_ext');
- $this->smallW = $this->getMemberOption($userId, 'smallW');
-
- // 画像保存ディレクトリ
- $collections = MEDIA::getCollectionList();
- $collection = $this->getMemberOption($userId, 'collection');
- if( $collection && isset($collections[$collection]) ){
- $this->collection = $collection;
- } else {
- $this->_info(__LINE__ . ": 画像保存ディレクトリが正しくありません。デフォルトを使用します");
- $this->collection = $this->memid;
- }
-
- $this->tmpdir = $DIR_MEDIA.$this->collection.'/';
- $this->_info(__LINE__ . ": 画像保存ディレクトリ: $this->tmpdir");
-
- if (!@is_dir($this->tmpdir)) {
- $this->_warn(__LINE__ . ": {$DIR_MEDIA}.{$this->collection} ディレクトリが存在しないので、ディレクトリを作成します。");
- $oldumask = umask(0000);
- if (!@mkdir($this->tmpdir, 0777))
- return $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->collection} ディレクトリの作成に失敗しました。パーミッションを確認してください。");
- umask($oldumask);
- }
-
- if (!is_writable($this->tmpdir)) {
- $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->collection} ディレクトリが存在しないか、書き込み可能になっていません");
- }
-
- // サムネイル保存ディレクトリ
- $thumb_collection = $this->getMemberOption($userId, 'thumb_col');
- if( $collection && isset($collections[$thumb_collection]) ){
- $this->thumb_collection = $thumb_collection;
- } else {
- $this->_info(__LINE__ . ": サムネイル画像保存ディレクトリが正しくありません。デフォルトを使用します");
- $this->thumb_collection = $this->memid;
- }
-
- $this->thumb_dir = $DIR_MEDIA.$this->thumb_collection.'/';
- $this->_info(__LINE__ . ": サムネイル画像保存ディレクトリ: $this->thumb_dir");
-
- if (!@is_dir($this->thumb_dir)) {
- $this->_warn(__LINE__ . ": {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリが存在しないので、ディレクトリを作成します。");
- $oldumask = umask(0000);
- if (!@mkdir($this->thumb_dir, 0777))
- return $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリの作成に失敗しました。パーミッションを確認してください。");
- umask($oldumask);
- }
-
- if (!is_writable($this->thumb_dir)) {
- $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリが存在しないか、書き込み可能になっていません");
- }
- }
-
- function _convert($str, $input_encoding = false) {
- if( ! $input_encoding ){
- $input_encoding = "ISO-2022-JP,ASCII,JIS,UTF-8,EUC-JP,SJIS,ISO-2022-JP";
- $encoding = mb_detect_encoding($input_encoding);
- if( ! $encoding )
- $input_encoding = "ISO-2022-JP";
- }
- return mb_convert_encoding($str, _CHARSET, $input_encoding);
- }
-
- function _addr_search($str) {
- if( PEAR::isError($addresses = Mail_RFC822::parseAddressList($str)) ){
- return false;
- }
- $addr = array_shift($addresses);
- if($addr)
- return $addr->mailbox . "@" .$addr->host;
- return false;
- }
-
- function _thumb_create($src, $W, $H, $thumb_dir = "./") {
- // 画像の幅と高さとタイプを取得
- $size = GetImageSize($src);
- switch ($size[2]) {
- case 1 :
- return false;
- break;
- case 2 :
- $im_in = @ImageCreateFromJPEG($src);
- break;
- case 3 :
- $im_in = @ImageCreateFromPNG($src);
- break;
- }
- if (!$im_in) {
- $this->_warn(__LINE__ . ": GDをサポートしていないか、ソースが見つかりません<br>phpinfo()でGDオプションを確認してください");
- return false;
- }
- // リサイズ
- if ($size[0] > $W || $size[1] > $H) {
- $key_w = $W / $size[0];
- $key_h = $H / $size[1];
- ($key_w < $key_h) ? $keys = $key_w : $keys = $key_h;
- $out_w = $size[0] * $keys;
- $out_h = $size[1] * $keys;
- } else {
- $out_w = $size[0];
- $out_h = $size[1];
- }
- // 出力画像(サムネイル)のイメージを作成し、元画像をコピーします。(GD2.0用)
- $im_out = ImageCreateTrueColor($out_w, $out_h);
- $resize = ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $out_w, $out_h, $size[0], $size[1]);
-
- // サムネイル画像をブラウザに出力、保存
- $filename = substr($src, strrpos($src, "/") + 1);
- ImageJPEG($im_out, $thumb_dir.$this->_getThumbFileName($filename)); //jpgサムネイル作成
- // 作成したイメージを破棄
- ImageDestroy($im_in);
- ImageDestroy($im_out);
-
- $this->_info(__LINE__ . ": サムネイルを作成しました" . $thumb_dir.$this->_getThumbFileName($filename));
- return true;
- }
-
- function _getThumbFileName($filename){
- $filename = substr($filename, 0, strrpos($filename, "."));
- return $filename."-small.jpg";
- }
-
- function _getExecuteLink() {
- global $CONF;
- return $CONF['ActionURL'].'?action=plugin&name=Moblog&type=execute';
- }
-
- function _checkLastupdate() {
- $now = time();
- $lastUpdate = $this->getOption('lastUpdate');
- $interval = $this->getOption('interval');
-
- if ($lastUpdate + $interval < $now) {
- $this->setOption('lastUpdate', $now);
- $this->setOption('nextUpdate', date("Y-m-d H:i:s", $lastUpdate + $interval));
- $this->_info(__LINE__ . ": 更新します。");
- return true;
- }
- $this->_info(__LINE__ . ": 更新しません。次回更新は".date("Y-m-d H:i:s", $lastUpdate + $interval)."以降です。");
- return false;
- }
-
- function doSkinVar($skinType, $type = "") {
- global $member;
- switch ($type) {
- case '' :
- case 'execute' :
- if ( $this->_checkLastupdate() )
- $this->execute();
- break;
-
- case 'link' :
- if ( $member->isLoggedIn() )
- echo '<a href="'.$this->_getExecuteLink().'">Add Item by Mail</a>';
- break;
- }
- } //end of function doSkinVar($skinType)
-
- function doAction($type) {
- global $member;
-
- switch ($type) {
- case '' :
- case 'execute' :
- if (!$member->isLoggedIn())
- return "ログインが必要です";
- $this->execute();
- header('Location: ' . serverVar('HTTP_REFERER'));
- break;
-
- default :
- return 'アクションが定義されていません: '.$type;
- }
- }
-
- function execute() {
- $this->execMode = intval($this->getOption('execMode'));
- if( $this->execMode == 0 ){
- // false
- $this->_info(__LINE__ . ": 振分対応モードで動作します。");
- } elseif ( $this->execMode == 1 ) {
- // true
- $this->_info(__LINE__ . ": 互換モードで動作します");
- }
-
- $enabledUserIds = $this->_getEnableUserId();
- foreach ($enabledUserIds as $userId) {
- $this->_info(__LINE__ . ": ユーザ($userId)のメールを取得開始します");
- $this->_initMediaDirByUserId($userId);
-
- // 接続
- $pop3 =& new Net_POP3();
- $pop3->_timeout = 10;
-
- if( ! $pop3->connect($this->host, $this->port) ){
- $this->_warn(__LINE__ . ": POPサーバーに接続できません");
- continue;
- }
-
- // 認証
- $authMethod = $this->getMemberOption($this->memid, 'useAPOP') == 'yes' ? 'APOP' : 'USER';
- $this->_info(__LINE__ . ": $authMethod で認証を行います");
- if(PEAR::isError($ret =& $pop3->login($this->user , $this->pass , $authMethod)) ){
- $this->_warn(__LINE__ . ": 認証に失敗しました:" . $ret->getMessage() );
- $pop3->disconnect();
- continue;
- }
-
- // 件数確認
- $num = $pop3->numMsg();
- $this->_info(__LINE__ . ": $num 件のメールがあります");
- if ($num == "0") {
- $pop3->disconnect();
- continue;
- }
-
- // Msg取得
- for ($i = 1; $i <= $num; $i ++) {
- if(! $msg =& $pop3->getMsg($i) ){
- $this->_warn(__LINE__ . ": メールの取得に失敗しました。");
- }
-
- $result = $this->addItemByMail($userId, $msg);
- if( $result ){
- $this->_info(__LINE__ . ": メッセージを削除します");
- $pop3->deleteMsg($i);
- }
- }
- //切断
- $pop3->disconnect();
- $this->_info(__LINE__ . ": ユーザ($userId)のメールを取得終了しました");
- }
- }
-
- function addItemByMail($userId, $msg) {
- // メールデコード
- $params['include_bodies'] = TRUE;
- $params['decode_bodies'] = TRUE;
- $params['decode_headers'] = TRUE;
- $params['input'] = $msg;
- if(PEAR::isError( $decodedMsg = Mail_mimeDecode::decode($params)) ){
- $this->_warn(__LINE__ . ": メールデコードに失敗しました:" . $decodedMsg->getMessage() );
- return true;
- }
-
- // From:
- if ( $decodedMsg->headers['from'] ) {
- $from = $this->_addr_search($decodedMsg->headers['from']);
- }
- if ( (! $from ) && $decodedMsg->headers['reply-to'] ) {
- $from = $this->_addr_search($decodedMsg->headers['reply-to']);
- }
- if ( (! $from ) && $decodedMsg->headers['return-path'] ) {
- $from = $this->_addr_search($decodedMsg->headers['return-path']);
- }
- if ( ! $from ){
- $this->_warn(__LINE__ . ": メールに送信者アドレスが見つかりません");
- return true;
- }
- $this->_info(__LINE__ . ": From($from)");
-
- // 投稿可能かチェック
- $from = strtolower(Trim($from));
- if ( in_array($from, $this->accept) ) {
- $this->_info(__LINE__ . ": 投稿許可アドレスに含まれているので受付($from)");
- } elseif( in_array( "*", $this->accept) ){
- $this->_info(__LINE__ . ": 投稿許可アドレスにワイルドカードが含まれているので受付($from)");
- }else {
- if( $this->execMode == 0 ){
- $this->_info(__LINE__ . ": 投稿許可アドレスに含まれていないので拒否($from)。振り分け対応モードなので他のアカウントで取得が行われる場合があります。");
- } else {
- $this->_warn(__LINE__ . ": 投稿許可アドレスに含まれていないので拒否($from)");
- }
- // 互換の場合は true
- // 振り分けの場合は false
- return $this->execMode;
- }
-
- // Date:
- $blog =& new BLOG($this->blogid);
-
- $timestamp = strtotime( trim($decodedMsg->headers['date']) );
- if ($timestamp == -1){
- $this->_info(__LINE__ . ": Dateヘッダからのtimestamp取得に失敗しました。");
- $timestamp = 0;
- }
- $timestamp = $blog->getCorrectTime($timestamp);
-
- // Subject:
- $subject = $this->_convert($decodedMsg->headers['subject']);
-
- // Subject: prefixチェック
- if ( $this->acceptSubjectPrefix ){
- $this->_info(__LINE__ . ": 投稿許可SubjectPrefixがあります(prefix: $this->acceptSubjectPrefix)");
- $pos = mb_strpos($subject, $this->acceptSubjectPrefix);
- if( $pos === 0 ){
- // prefix切り取り
- $subject = mb_substr($subject, mb_strlen($this->acceptSubjectPrefix) );
- $this->_info(__LINE__ . ": 投稿許可SubjectPrefixをみつけました(prefix削除後subject: $subject)");
- } else {
- $this->_warn(__LINE__ . ": 投稿許可SubjectPrefixがないので拒否します($subject)");
- return true;
- }
- }
-
- // subject: オプション分割
- if (preg_match('/'.$this->optionsKeyword.'/i', $subject)) {
- list ($subject, $option) = spliti($this->optionsKeyword, $subject, 2);
-
- $this->_info(__LINE__ . ": Subject($subject), Option($option)");
-
- $option = '&'.$option;
- if (preg_match('/&' . $this->blogKeyword . '=([^&=]+)/i', $option, $word)) {
- $this->blogid = $word[1];
- $this->_info(__LINE__ . ': blogidを' . $this->blogid . 'で上書きします');
- }
- if (preg_match('/&' . $this->categoryKeyword . '=([^&=]+)/i', $option, $word)) {
- $this->categoryNameOrId = $word[1];
- $this->_info(__LINE__ . ': Categoryを' . $this->categoryNameOrId . 'で上書きします');
- }
- if (preg_match('/&' . $this->publishKeyword . '=([^&=]+)/i', $option, $word)) {
- $this->DefaultPublish = $word[1];
- $this->_info(__LINE__ . ($this->DefaultPublish ? ': 投稿を公開に上書きします' : ': 投稿を下書きに上書きします'));
- }
- }
-
- // Subject: 空の場合
- if( ! $subject = trim(htmlspecialchars($subject)) ){
- $subject = $this->nosubject;
- }
-
- // body
- $text = "";
- if( strtolower($decodedMsg->ctype_primary) == "text" ){
- $this->_info(__LINE__ . ": single partメッセージです");
- $text = $this->_textPart($decodedMsg);
- } elseif ( strtolower($decodedMsg->ctype_primary) == "multipart" ){
- $this->_info(__LINE__ . ": multipart partメッセージです");
- $texts = Array();
- $fileNames = Array();
- $this->_decodeMultiPart($decodedMsg->parts, $texts, $fileNames);
-
- $text = $texts['plain'];
- if( $texts['html'] ) $text = $texts['html'];
- }
-
- if ($this->imgonly && (! $fileNames) ) {
- $this->_info(__LINE__ . ": 添付ファイルがないので書き込みません");
- return true;
- }
-
- if( $this->_isSpam($text) ){
- $this->_warn(__LINE__ . ": SPAMのため追加しません");
- return true;
- }
-
- $body = '';
- // body 生成
- if ( ! $fileNames ) {
- // 添付ファイルがない場合のbody
- $vars = array (
- 'body' => $text,
- );
- // textTpl
- $body .= TEMPLATE :: fill($this->getMemberOption($this->memid, 'textTpl'), $vars);
- } else {
- // 添付ファイルがある場合のbody
- $lastFile = array_pop($fileNames);
-
- foreach( $fileNames as $filename ){
- $body .= $this->_imageHtml($filename);
- }
-
- $body .= $this->_imageHtml($lastFile, $text);
- }
-
- // item追加
- $this->_info(__LINE__ . ": アイテム追加します");
-
- // bodyをbodyとmoreに分割
- $more = '';
- if( $this->moreDelimiter )
- list($body, $more) = spliti($this->moreDelimiter, $body, 2);
-
- $body = trim($body);
- $more = trim($more);
-
- $this->_addDatedItem($this->blogid, $subject, $body, $more, 0, $timestamp, 0, $this->categoryNameOrId);
- return true;
- }
-
- function _decodeMultiPart($parts, &$texts, &$fileNames){
- foreach($parts as $part){\r switch ( strtolower( $part->ctype_primary )){
- // multipart
- case 'multipart':
- $this->_decodeMultiPart($part->parts, $texts, $fileNames);
- break;
- //text part
- case 'text':
- $this->_info(__LINE__ . ": text part をみつけました[{$part->ctype_primary}/{$part->ctype_secondary}]");
- $texts[$part->ctype_secondary] = $this->_textPart($part);
- break;
- // imagepart
- case 'image':
- default:
- $this->_info(__LINE__ . ": image/data part をみつけました[{$part->ctype_primary}/{$part->ctype_secondary}]");
- if( $fileName = $this->_imagePart($part) )
- $fileNames[] = $fileName;
- break;
- }
- }
- }
-
- function _textPart(&$part){
- $encoding = false;
- if( $part->ctype_parameters )
- $encoding = $this->ctype_parameters['charset'];
-
- $text = $this->_convert($part->body, $encoding);
- $text = strip_tags($text, $this->no_strip_tags);
-
- $blog =& new BLOG($this->blogid);
- //blog設定で改行を<br />に置換onの場合
- if ($blog->getSetting('bconvertbreaks')) {
- if ( strtolower($part->ctype_secondary) == 'html' ) {
- //改行文字を削除、<br>タグを\nへ
- $text = str_replace("\r\n", "\r", $text);
- $text = str_replace("\r", "\n", $text);
- $text = str_replace("\n", "", $text);
- $text = str_replace("<br>", "\n", $text);
- }
- }
- return $text;
- }
-
- function _imagePart(&$part){
- if( !$this->prefixDate ){
- $this->prefixDate = date('YmdHis');
- $this->fileCount = 0;
- } else {
- $this->fileCount += 1;
- }
- $this->filePrefix = $this->prefixDate . sprintf('%02d', $this->fileCount);
-
- $filename = "";
- if( $part->d_parameters ){
- $filename = $part->d_parameters['filename'];
- } elseif( $part->ctype_parameters ){
- $filename = $part->ctype_parameters['name'];
- } else {
- $filename = $part->ctype_secondary;
- }
-
- $filename = $this->_convert($filename);
- $filename = $this->filePrefix . "-" . $filename;
- $this->_info(__LINE__ . ": FileName($filename)");
-
- // subtypeチェック
- $size = strlen($part->body);
- if( eregi($this->subtype, trim($part->ctype_secondary) )){
- // サイズ、拡張子チェック
- if ($size < $this->maxbyte && !eregi($this->viri, $filename)) {
-
- $fp = fopen($this->tmpdir.$filename, "w");
- fputs($fp, $part->body);
- fclose($fp);
-
- $size = @getimagesize($this->tmpdir.$filename);
- //サムネイル作成する場合
- if ($this->thumb_ok && function_exists('ImageCreate')) {
- //サムネイル作成する拡張子の場合
- if ( preg_match("/$this->thumb_ext/i", $filename) ) {
- if ($size[0] > $this->W || $size[1] > $this->H) {
- $this->_thumb_create($this->tmpdir.$filename, $this->W, $this->H, $this->thumb_dir);
- }
- }
- }
- return $filename;
- }
- $this->_warn(__LINE__ . ": 添付ファイルを無視します。(サイズ超過: $size B or 保存しないファイルに該当しています) [$part->ctype_primary/$part->ctype_secondary]");
- return false;
- }
- $this->_warn(__LINE__ . ": 添付ファイルを無視します。(subtypeチェック: $part->ctype_secondary が対応MIMEタイプに入っていますか?) [$part->ctype_primary/$part->ctype_secondary]");
- return false;
- }
-
- function _imageHtml($filename, $body = ""){
- global $CONF;
-
- $size = @getimagesize($this->tmpdir.$filename);
- $thumb_size = @getimagesize($this->thumb_dir.$this->_getThumbFileName($filename));
- $smallH = round($this->smallW / $size[0] * $size[1], 0);
-
- $vars = array (
- 'thumbW' => $thumb_size[0],
- 'thumbH' => $thumb_size[1],
- 'reductionW' => $this->smallW,
- 'reductionH' => $smallH,
- 'sizeW' => $size[0],
- 'sizeH' => $size[1],
- 'body' => $body,
- 'thumbUrl' => $this->thumb_collection.'/'.$this->_getThumbFileName($filename),
- 'imageUrl' => $this->collection.'/'.$filename,
- 'mediaUrl' => $CONF['MediaURL'],
- 'fileName' => $filename
- );
-
- // データファイルチェック
- if( ! preg_match("/$this->imgExt/i", $filename) ){
- $this->_info(__LINE__ . ": 画像ファイルに該当しないので、データファイルテンプレートを使用します");
- return TEMPLATE :: fill($this->getMemberOption($this->memid, 'dataTpl'), $vars);
- }
-
- if ( $thumb_size[0] ) { //サムネイルがある場合のソース
- $this->_info(__LINE__ . ": サムネイルがあります");
- return TEMPLATE :: fill($this->getMemberOption($this->memid, 'withThumbTpl'), $vars);
- } else { //サムネイルがない場合のソース
- if ($size[0] > $this->smallW) { //縮小表示
- $this->_info(__LINE__ . ": サムネイルがありません、縮小表示します");
- return TEMPLATE :: fill($this->getMemberOption($this->memid, 'reductionTpl'), $vars);
- } else { //そのまま表示
- $this->_info(__LINE__ . ": サムネイルがありません");
- return TEMPLATE :: fill($this->getMemberOption($this->memid, 'withoutThumbTpl'), $vars);
- }
- }
- }
-
- function _addDatedItem($blogid, $title, $body, $more, $closed, $timestamp, $future, $catNameOrId = "") {
- // 1. ログイン======================
- $mem = MEMBER :: createFromID($this->memid);
-
- // 2. ブログ追加できるかチェック======================
- if (!BLOG :: existsID($this->blogid)) {
- $this->_info(__LINE__ . ": 存在しないblogです");
- return false;
- }
- $this->_info(__LINE__ . ": blogidはOK!");
-
- if (!$mem->isTeamMember($blogid)) {
- $this->_warn(__LINE__ . ": メンバーではありません");
- return false;
- }
- $this->_info(__LINE__ . ": メンバーチェックもok!");
-
- if (!trim($body)) {
- $this->_warn(__LINE__ . ": 空のアイテムは追加できません");
- return false;
- }
- $this->_info(__LINE__ . ": アイテムは空じゃないです");
-
- // 3. 値の補完
- $blog =& new BLOG($this->blogid);
- if( $blog->isValidCategory($catNameOrId) ){
- // カテゴリIDとして有効なときはそのまま使う
- $catid = $catNameOrId;
- } else {
- // カテゴリID ゲット (誤ったカテゴリID使用時はデフォを使用)
- $catid = $blog->getCategoryIdFromName($catNameOrId);
- }
-
- $this->_info(__LINE__ . ": 追加するcatid: ".$catid);
- if ($this->DefaultPublish) {
- $draft = 0;
- } else {
- $draft = 1; //ドラフト追加
- $this->_info(__LINE__ . ": ドラフトで追加します");
- }
- if ($closed != 1)
- $closed = 0; //コメントを許可
- $this->_info(__LINE__ . ": \$catid:".$catid.", \$draft:".$draft.", \$closed:".$closed);
-
- // 4. blogに追加
- $itemid = $blog->additem($catid, $title, $body, $more, $blogid, $mem->getID(), $timestamp, $closed, $draft);
-
- $this->_info(__LINE__ . ": itemid: $itemid");
- return $itemid;
- }
-
- function _isSpam($str){
- global $manager;
- if( $this->getOption('spamCheck') == 'yes' ){
- $spamcheck = array (
- 'type' => 'Moblog',
- 'data' => $str,
- 'return' => true,
- 'ipblock' => false
- );
- $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
- if (isset($spamcheck['result']) && $spamcheck['result'] == true)
- return true;
- }
- return false;
- }
-}
+<?php\r
+// vim: tabstop=2:shiftwidth=2\r
+\r
+/**\r
+ * NP_Moblog ($Revision: 1.136 $)\r
+ * by hsur ( http://blog.cles.jp/np_cles )\r
+ * $Id: NP_Moblog.php,v 1.136 2010/06/06 11:44:19 hsur Exp $\r
+ *\r
+ * Based on NP_HeelloWorld v0.8 \r
+ * http://nakahara21.com/?itemid=133\r
+*/\r
+\r
+/*\r
+ * Copyright (C) 2003 nakahara21 All rights reserved.\r
+ * Copyright (C) 2004-2010 cles All rights reserved.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
+ * \r
+ * In addition, as a special exception, mamio and cles gives\r
+ * permission to link the code of this program with those files in the PEAR\r
+ * library that are licensed under the PHP License (or with modified versions\r
+ * of those files that use the same license as those files), and distribute\r
+ * linked combinations including the two. You must obey the GNU General Public\r
+ * License in all respects for all of the code used other than those files in\r
+ * the PEAR library that are licensed under the PHP License. If you modify\r
+ * this file, you may extend this exception to your version of the file,\r
+ * but you are not obligated to do so. If you do not wish to do so, delete\r
+ * this exception statement from your version.\r
+*/\r
+\r
+if (!class_exists('NucleusPlugin')) exit;\r
+global $DIR_LIBS;\r
+require_once($DIR_LIBS . 'MEDIA.php');\r
+\r
+// クラスのロード\r
+require_once(dirname(__FILE__).'/sharedlibs/sharedlibs.php');\r
+require_once('Net/POP3.php');\r
+require_once('Mail/mimeDecode.php');\r
+require_once('Mail/RFC822.php');\r
+\r
+// バージョンチェック\r
+$required = '4.3.0';\r
+if( ! version_compare(phpversion() , $required , '>=') ){\r
+ ACTIONLOG :: add(WARNING, 'NP_MoblogはPHP>=4.3.0であることが必要です。');\r
+}\r
+\r
+class NP_Moblog extends NucleusPlugin {\r
+\r
+ // name of plugin\r
+ function getName() {\r
+ return 'Moblog';\r
+ }\r
+\r
+ // author of plugin\r
+ function getAuthor() {\r
+ return 'hsur';\r
+ }\r
+\r
+ // an URL to the plugin website\r
+ // can also be of the form mailto:foo@bar.com\r
+ function getURL() {\r
+ return 'http://blog.cles.jp/np_cles/category/31/subcatid/2';\r
+ }\r
+\r
+ // version of the plugin\r
+ function getVersion() {\r
+ return '1.17.0';\r
+ }\r
+ \r
+ function hasAdminArea() {\r
+ return 1;\r
+ }\r
+ \r
+ function getEventList() {\r
+ return array('PrePluginOptionsEdit');\r
+ }\r
+ \r
+ function event_PrePluginOptionsEdit(&$data) {\r
+ switch($data['context']){\r
+ case 'member':\r
+ // idandcat\r
+ $m =& MEMBER :: createFromID($data['contextid']);\r
+ $trimChar = array(\r
+ '=' => '',\r
+ '|' => '',\r
+ ';' => '',\r
+ );\r
+ \r
+ $blogs = Array();\r
+ $res = sql_query('SELECT bnumber, bname FROM '.sql_table('blog'));\r
+ while( $o = mysql_fetch_object($res) ){\r
+ if( $m->isTeamMember($o->bnumber) ){\r
+ $blogs[$o->bnumber] = $o->bname;\r
+ }\r
+ }\r
+ \r
+ $idandcatTypeInfo = '';\r
+ foreach($blogs as $blogid => $blogname){\r
+ $res = sql_query('SELECT catid, cname FROM '.sql_table('category').' WHERE cblog='.$blogid);\r
+ if( @mysql_num_rows($res) > 0) {\r
+ while( $o = mysql_fetch_object($res) ){\r
+ if($idandcatTypeInfo)\r
+ $idandcatTypeInfo .= '|';\r
+ $o->cname = strtr($o->cname, $trimChar);\r
+ $blogname = strtr($blogname, $trimChar);\r
+ $idandcatTypeInfo .= "{$o->cname} ({$blogname})|{$blogid},{$o->catid}";\r
+ }\r
+ }\r
+ }\r
+ if( ! $idandcatTypeInfo ){\r
+ $idandcatTypeInfo = "!!投稿可能なblogがありません!!|0,0";\r
+ }\r
+ \r
+ // collection & thumb_col\r
+ $collections = MEDIA::getCollectionList();\r
+ $mid = intval($m->getID());\r
+ $collections[$mid] = 'デフォルト(useridディレクトリ)';\r
+ \r
+ $collectionTypeInfo = '';\r
+ foreach( $collections as $collection => $name ){\r
+ if($collectionTypeInfo) $collectionTypeInfo .= '|';\r
+ $name = strtr($name, $trimChar);\r
+ $collection = strtr($collection, $trimChar);\r
+ $collectionTypeInfo .= "{$name}|{$collection}";\r
+ }\r
+ \r
+ // set options\r
+ foreach($data['options'] as $oid => $option ){\r
+ switch($data['options'][$oid]['name']){\r
+ case 'idandcat':\r
+ $data['options'][$oid]['typeinfo'] = $idandcatTypeInfo;\r
+ break;\r
+ case 'collection':\r
+ case 'thumb_col':\r
+ $data['options'][$oid]['typeinfo'] = $collectionTypeInfo;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ break;\r
+ default:\r
+ // nothing \r
+ }\r
+ }\r
+ \r
+ function install() {\r
+ $this->createMemberOption('enable', 'プラグインを有効にするか?', 'yesno', 'no');\r
+\r
+ $this->createMemberOption('host', 'POP3 ホスト名', 'text', 'localhost');\r
+ $this->createMemberOption('port', 'POP3 ポート', 'text', '110', 'numerical=true');\r
+ $this->createMemberOption('user', 'POP3 ユーザー名', 'text', '');\r
+ $this->createMemberOption('pass', 'POP3 パスワード', 'password', '');\r
+ $this->createMemberOption('useAPOP', 'APOPを使用するか?', 'yesno', 'no');\r
+\r
+ $this->createMemberOption('idandcat', 'Nucleusカテゴリ(Blog)', 'select', '', '');\r
+\r
+ $this->createMemberOption('collection', '画像を保存するディレクトリ', 'select', '', '');\r
+ $this->createMemberOption('thumb_col', 'サムネイルをを保存するディレクトリ', 'select', '', '');\r
+\r
+ $this->createMemberOption('imgonly', 'イメージ添付メールのみ追加?', 'yesno', 'no');\r
+ $this->createMemberOption('DefaultPublish', 'デフォルトで公開するか?', 'yesno', 'no');\r
+\r
+ $this->createMemberOption('optionsKeyword', 'オプション記述開始の区切り文字', 'text', '@');\r
+ $this->createMemberOption('blogKeyword', 'オプションでblogidを指定する場合のキー', 'text', 'b');\r
+ $this->createMemberOption('categoryKeyword', 'オプションでカテゴリを指定する場合のキー', 'text', 'c');\r
+ $this->createMemberOption('publishKeyword', 'オプションでストレートにpublish指定する場合のキー', 'text', 's');\r
+\r
+ $this->createMemberOption('moreDelimiter', '追記にする場合の区切り文字(利用しない場合は空欄)', 'text', '');\r
+\r
+ $this->createMemberOption('accept', '投稿許可アドレス(複数の場合改行で区切ってください)', 'textarea', '');\r
+ $this->createMemberOption('acceptSubjectPrefix','投稿許可SubjectPrefix(制限無しの場合は空欄)','text','');\r
+\r
+ $this->createMemberOption('nosubject', '件名がないときの題名', 'text', '');\r
+ $this->createMemberOption('no_strip_tags', 'htmlメールの場合に除去しないタグ', 'textarea', '<title><hr><h1><h2><h3><h4><h5><h6><div><p><pre><sup><ul><ol><br><dl><dt><table><caption><tr><li><dd><th><td><a><area><img><form><input><textarea><button><select><option>');\r
+ $this->createMemberOption('maxbyte', '最大添付量(B)', 'text', '300000', 'numerical=true');\r
+ $this->createMemberOption('subtype', '対応MIMEタイプ(正規表現)', 'text', 'gif|jpe?g|png|bmp|octet-stream|x-pmd|x-mld|x-mid|x-smd|x-smaf|x-mpeg|pdf');\r
+ $this->createMemberOption('viri', '保存しないファイル(正規表現)', 'text', '.+\.exe$|.+\.zip$|.+\.pif$|.+\.scr$');\r
+ $this->createMemberOption('imgExt', '画像ファイルの拡張子(正規表現)', 'text', '.+\.png$|.+\.jpe?g$|.+\.gif$|.+\.bmp$');\r
+\r
+ $this->createMemberOption('thumb_ok', 'サムネイルを使用する?', 'yesno', 'yes');\r
+ $this->createMemberOption('W', 'サムネイルの大きさ(Width)', 'text', '120', 'numerical=true');\r
+ $this->createMemberOption('H', 'サムネイルの大きさ(Hight)', 'text', '120', 'numerical=true');\r
+ $this->createMemberOption('thumb_ext', 'サムネイルを作る対象画像', 'text', '.+\.jpe?g$|.+\.png$');\r
+ $this->createMemberOption('smallW', 'アイテム内に表示する画像の最大横幅', 'text', '120', 'numerical=true');\r
+\r
+ $this->createMemberOption('textTpl', 'テキストテンプレート', 'textarea', '<%body%>');\r
+ $this->createMemberOption('withThumbTpl', 'サムネイル付きテンプレート', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%image(<%thumbUrl%>|<%thumbW%>|<%thumbH%>|)%></a></div><%body%>');\r
+ $this->createMemberOption('withoutThumbTpl', 'サムネイルなしテンプレート', 'textarea', '<div class="leftbox"><%image(<%imageUrl%>|<%sizeW%>|<%sizeH%>|)%></div><%body%>');\r
+ $this->createMemberOption('reductionTpl', 'サムネイルなしテンプレート(縮小)', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%image(<%imageUrl%>|<%reductionW%>|<%reductionH%>|)%></a></div><%body%>');\r
+ $this->createMemberOption('dataTpl', 'データファイルテンプレート', 'textarea', '<div class="leftbox"><a href="<%mediaUrl%><%imageUrl%>" target="_blank"><%fileName%></a></div><%body%>');\r
+ \r
+ $this->createOption('execMode', '動作モード', 'select', '1', '振分対応モード|0|互換モード|1');\r
+ $this->createOption('spamCheck', 'SPAMチェックを有効にする', 'yesno', 'no');\r
+ \r
+ $this->createOption('interval', 'メール取得の間隔(秒)', 'text', '600', 'numerical=true');\r
+ $this->createOption('nextUpdate', '次回更新時刻(変更できません)', 'text', '-', 'access=readonly');\r
+ $this->createOption('lastUpdate', '最終更新時刻(UnixTimeStamp,)', 'text', '0', 'access=hidden');\r
+ $this->createOption('debug', 'ログを出力を行うか?', 'yesno', 'no');\r
+ }\r
+ \r
+ function unInstall() {}\r
+ function getMinNucleusVersion() { return 320; }\r
+ function getMinNucleusPatchLevel() { return 0; }\r
+\r
+ // a description to be shown on the installed plugins listing\r
+ function getDescription() {\r
+ return '[$Revision: 1.136 $]<br />メールを拾ってアイテムを追加します。<%Moblog%>の記述のあるスキンを適用するページを開くと実行されます。<br />\r
+ <%Moblog(link)%>と記入することでメールを取得するためのリンクを表示することができます(要ログイン)<br />\r
+ 個人ごとに設定ができるようになりましたので「あなたの設定」か「メンバー管理」から設定を行ってください。';\r
+ }\r
+\r
+ function supportsFeature($what) {\r
+ switch ($what) {\r
+ case 'SqlTablePrefix' :\r
+ case 'HelpPage':\r
+ return 1;\r
+ default :\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ function _info($msg) {\r
+ if ($this->getOption('debug') == 'yes') {\r
+ ACTIONLOG :: add(INFO, 'Moblog: '.$msg);\r
+ }\r
+ }\r
+\r
+ function _warn($msg) {\r
+ ACTIONLOG :: add(WARNING, 'Moblog: '.$msg);\r
+ }\r
+\r
+ function _getEnableUserId() {\r
+ $userOptions = $this->getAllMemberOptions('enable');\r
+ $userIds = Array ();\r
+ foreach( $userOptions as $userId => $value ){\r
+ if( $value == 'yes') $userIds[] = $userId;\r
+ }\r
+ return $userIds;\r
+ }\r
+\r
+ function _initMediaDirByUserId($userId) {\r
+ global $DIR_MEDIA;\r
+\r
+ $this->_info(__LINE__ . ": ユーザ($userId)の初期設定");\r
+ $this->memid = $userId;\r
+\r
+ /*-- 受信メールサーバーの設定--*/\r
+ $this->host = $this->getMemberOption($userId, 'host');\r
+ $this->port = $this->getMemberOption($userId, 'port');\r
+ $this->user = $this->getMemberOption($userId, 'user');\r
+ $this->pass = $this->getMemberOption($userId, 'pass'); \r
+\r
+ // メールでアイテムを追加するblogのID\r
+ $idandcat = $this->getMemberOption($userId, 'idandcat');\r
+ list($this->blogid, $this->categoryNameOrId) = explode(",", $idandcat);\r
+ \r
+ $this->imgonly = ($this->getMemberOption($userId, 'imgonly') == 'yes') ? 1 : 0;\r
+ $this->DefaultPublish = ($this->getMemberOption($userId, 'DefaultPublish') == 'yes') ? 1 : 0;\r
+\r
+ /*-- メールのタイトルに各種オプションを含める場合の設定--*/\r
+ $this->optionsKeyword = $this->getMemberOption($userId, 'optionsKeyword');\r
+ $this->blogKeyword = $this->getMemberOption($userId, 'blogKeyword');\r
+ $this->categoryKeyword = $this->getMemberOption($userId, 'categoryKeyword');\r
+ $this->publishKeyword = $this->getMemberOption($userId, 'publishKeyword');\r
+\r
+ // 投稿許可アドレス\r
+ $this->accept = explode("\n", $this->getMemberOption($userId, 'accept'));\r
+ $this->accept = Array_Map("Trim", $this->accept);\r
+ $this->accept = Array_Map("strtolower", $this->accept);\r
+ foreach( $this->accept as $mailAddr ){\r
+ $this->_info(__LINE__ . "許可アドレス user:$userId, $mailAddr");\r
+ } \r
+\r
+ // 投稿許可SubjectPrefix\r
+ $this->acceptSubjectPrefix = Trim($this->getMemberOption($userId, 'acceptSubjectPrefix'));\r
+ \r
+ // 追記の区切り\r
+ $this->moreDelimiter = Trim($this->getMemberOption($userId, 'moreDelimiter'));\r
+ \r
+ // 件名がないときの題名\r
+ $this->nosubject = $this->getMemberOption($userId, 'nosubject');\r
+ $this->no_strip_tags = $this->getMemberOption($userId, 'no_strip_tags');\r
+\r
+ // 最大添付量(バイト・1ファイルにつき)※超えるものは保存しない\r
+ $this->maxbyte = $this->getMemberOption($userId, 'maxbyte');\r
+ $this->subtype = $this->getMemberOption($userId, 'subtype');\r
+ $this->viri = $this->getMemberOption($userId, 'viri');\r
+ $this->imgExt = $this->getMemberOption($userId, 'imgExt');\r
+\r
+ // サムネイル\r
+ $this->thumb_ok = ($this->getMemberOption($userId, 'thumb_ok') == 'yes') ? 1 : 0;\r
+ $this->W = $this->getMemberOption($userId, 'W');\r
+ $this->H = $this->getMemberOption($userId, 'H');\r
+ $this->thumb_ext = $this->getMemberOption($userId, 'thumb_ext');\r
+ $this->smallW = $this->getMemberOption($userId, 'smallW');\r
+ \r
+ // 画像保存ディレクトリ\r
+ $collections = MEDIA::getCollectionList();\r
+ $collection = $this->getMemberOption($userId, 'collection');\r
+ if( $collection && isset($collections[$collection]) ){\r
+ $this->collection = $collection;\r
+ } else {\r
+ $this->_info(__LINE__ . ": 画像保存ディレクトリが正しくありません。デフォルトを使用します");\r
+ $this->collection = $this->memid;\r
+ }\r
+ \r
+ $this->tmpdir = $DIR_MEDIA.$this->collection.'/';\r
+ $this->_info(__LINE__ . ": 画像保存ディレクトリ: $this->tmpdir");\r
+ \r
+ if (!@is_dir($this->tmpdir)) {\r
+ $this->_warn(__LINE__ . ": {$DIR_MEDIA}.{$this->collection} ディレクトリが存在しないので、ディレクトリを作成します。");\r
+ $oldumask = umask(0000);\r
+ if (!@mkdir($this->tmpdir, 0777))\r
+ return $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->collection} ディレクトリの作成に失敗しました。パーミッションを確認してください。");\r
+ umask($oldumask); \r
+ } \r
+\r
+ if (!is_writable($this->tmpdir)) {\r
+ $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->collection} ディレクトリが存在しないか、書き込み可能になっていません");\r
+ }\r
+ \r
+ // サムネイル保存ディレクトリ\r
+ $thumb_collection = $this->getMemberOption($userId, 'thumb_col');\r
+ if( $collection && isset($collections[$thumb_collection]) ){\r
+ $this->thumb_collection = $thumb_collection;\r
+ } else {\r
+ $this->_info(__LINE__ . ": サムネイル画像保存ディレクトリが正しくありません。デフォルトを使用します");\r
+ $this->thumb_collection = $this->memid;\r
+ }\r
+\r
+ $this->thumb_dir = $DIR_MEDIA.$this->thumb_collection.'/';\r
+ $this->_info(__LINE__ . ": サムネイル画像保存ディレクトリ: $this->thumb_dir");\r
+ \r
+ if (!@is_dir($this->thumb_dir)) {\r
+ $this->_warn(__LINE__ . ": {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリが存在しないので、ディレクトリを作成します。");\r
+ $oldumask = umask(0000);\r
+ if (!@mkdir($this->thumb_dir, 0777))\r
+ return $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリの作成に失敗しました。パーミッションを確認してください。");\r
+ umask($oldumask); \r
+ } \r
+ \r
+ if (!is_writable($this->thumb_dir)) {\r
+ $this->_warn(__LINE__ . ": 設定エラー: {$DIR_MEDIA}.{$this->thumb_dir} ディレクトリが存在しないか、書き込み可能になっていません");\r
+ }\r
+ }\r
+\r
+ function _convert($str, $input_encoding = false) {\r
+ if( ! $input_encoding ){\r
+ $input_encoding = "ISO-2022-JP,ASCII,JIS,UTF-8,EUC-JP,SJIS,ISO-2022-JP";\r
+ $encoding = mb_detect_encoding($str, $input_encoding);\r
+ if( ! $encoding )\r
+ $input_encoding = "ISO-2022-JP";\r
+ }\r
+ return mb_convert_encoding($str, _CHARSET, $input_encoding);\r
+ }\r
+ \r
+ function _addr_search($str) {\r
+ if( PEAR::isError($addresses = Mail_RFC822::parseAddressList($str)) ){\r
+ return false;\r
+ }\r
+ $addr = array_shift($addresses);\r
+ if($addr)\r
+ return $addr->mailbox . "@" .$addr->host;\r
+ return false;\r
+ }\r
+\r
+ function _thumb_create($src, $W, $H, $thumb_dir = "./") {\r
+ // 画像の幅と高さとタイプを取得\r
+ $size = GetImageSize($src);\r
+ switch ($size[2]) {\r
+ case 1 :\r
+ return false;\r
+ break;\r
+ case 2 :\r
+ $im_in = @ImageCreateFromJPEG($src);\r
+ break;\r
+ case 3 :\r
+ $im_in = @ImageCreateFromPNG($src);\r
+ break;\r
+ }\r
+ if (!$im_in) {\r
+ $this->_warn(__LINE__ . ": GDをサポートしていないか、ソースが見つかりません<br>phpinfo()でGDオプションを確認してください");\r
+ return false;\r
+ }\r
+ // リサイズ\r
+ if ($size[0] > $W || $size[1] > $H) {\r
+ $key_w = $W / $size[0];\r
+ $key_h = $H / $size[1];\r
+ ($key_w < $key_h) ? $keys = $key_w : $keys = $key_h;\r
+ $out_w = $size[0] * $keys;\r
+ $out_h = $size[1] * $keys;\r
+ } else {\r
+ $out_w = $size[0];\r
+ $out_h = $size[1];\r
+ }\r
+ // 出力画像(サムネイル)のイメージを作成し、元画像をコピーします。(GD2.0用)\r
+ $im_out = ImageCreateTrueColor($out_w, $out_h);\r
+ $resize = ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $out_w, $out_h, $size[0], $size[1]);\r
+\r
+ // サムネイル画像をブラウザに出力、保存\r
+ $filename = substr($src, strrpos($src, "/") + 1);\r
+ ImageJPEG($im_out, $thumb_dir.$this->_getThumbFileName($filename)); //jpgサムネイル作成\r
+ // 作成したイメージを破棄\r
+ ImageDestroy($im_in);\r
+ ImageDestroy($im_out);\r
+ \r
+ $this->_info(__LINE__ . ": サムネイルを作成しました" . $thumb_dir.$this->_getThumbFileName($filename));\r
+ return true;\r
+ }\r
+ \r
+ function _getThumbFileName($filename){\r
+ $filename = substr($filename, 0, strrpos($filename, "."));\r
+ return $filename."-small.jpg";\r
+ }\r
+\r
+ function _getExecuteLink() {\r
+ global $CONF;\r
+ return $CONF['ActionURL'].'?action=plugin&name=Moblog&type=execute';\r
+ }\r
+\r
+ function _checkLastupdate() {\r
+ $now = time();\r
+ $lastUpdate = $this->getOption('lastUpdate');\r
+ $interval = $this->getOption('interval');\r
+\r
+ if ($lastUpdate + $interval < $now) {\r
+ $this->setOption('lastUpdate', $now);\r
+ $this->setOption('nextUpdate', date("Y-m-d H:i:s", $lastUpdate + $interval));\r
+ $this->_info(__LINE__ . ": 更新します。");\r
+ return true;\r
+ }\r
+ $this->_info(__LINE__ . ": 更新しません。次回更新は".date("Y-m-d H:i:s", $lastUpdate + $interval)."以降です。");\r
+ return false;\r
+ }\r
+\r
+ function doSkinVar($skinType, $type = "") {\r
+ global $member;\r
+ switch ($type) {\r
+ case '' :\r
+ case 'execute' :\r
+ if ( $this->_checkLastupdate() )\r
+ $this->execute();\r
+ break;\r
+\r
+ case 'link' :\r
+ if ( $member->isLoggedIn() )\r
+ echo '<a href="'.$this->_getExecuteLink().'">Add Item by Mail</a>';\r
+ break;\r
+ }\r
+ } //end of function doSkinVar($skinType)\r
+\r
+ function doAction($type) {\r
+ global $member;\r
+\r
+ switch ($type) {\r
+ case '' :\r
+ case 'execute' :\r
+ if (!$member->isLoggedIn())\r
+ return "ログインが必要です";\r
+ $this->execute();\r
+ header('Location: ' . serverVar('HTTP_REFERER'));\r
+ break;\r
+\r
+ default :\r
+ return 'アクションが定義されていません: '.$type;\r
+ }\r
+ }\r
+\r
+ function execute() {\r
+ $this->execMode = intval($this->getOption('execMode'));\r
+ if( $this->execMode == 0 ){\r
+ // false\r
+ $this->_info(__LINE__ . ": 振分対応モードで動作します。");\r
+ } elseif ( $this->execMode == 1 ) {\r
+ // true\r
+ $this->_info(__LINE__ . ": 互換モードで動作します"); \r
+ }\r
+ \r
+ $enabledUserIds = $this->_getEnableUserId();\r
+ foreach ($enabledUserIds as $userId) {\r
+ $this->_info(__LINE__ . ": ユーザ($userId)のメールを取得開始します");\r
+ $this->_initMediaDirByUserId($userId);\r
+ \r
+ // 接続\r
+ $pop3 =& new Net_POP3();\r
+ $pop3->_timeout = 10;\r
+ \r
+ if( ! $pop3->connect($this->host, $this->port) ){\r
+ $this->_warn(__LINE__ . ": POPサーバーに接続できません");\r
+ continue;\r
+ }\r
+ \r
+ // 認証\r
+ $authMethod = $this->getMemberOption($this->memid, 'useAPOP') == 'yes' ? 'APOP' : 'USER';\r
+ $this->_info(__LINE__ . ": $authMethod で認証を行います");\r
+ if(PEAR::isError($ret =& $pop3->login($this->user , $this->pass , $authMethod)) ){ \r
+ $this->_warn(__LINE__ . ": 認証に失敗しました:" . $ret->getMessage() );\r
+ $pop3->disconnect();\r
+ continue;\r
+ }\r
+ \r
+ // 件数確認\r
+ $num = $pop3->numMsg();\r
+ $this->_info(__LINE__ . ": $num 件のメールがあります");\r
+ if ($num == "0") {\r
+ $pop3->disconnect();\r
+ continue;\r
+ }\r
+ \r
+ // Msg取得\r
+ for ($i = 1; $i <= $num; $i ++) {\r
+ if(! $msg =& $pop3->getMsg($i) ){\r
+ $this->_warn(__LINE__ . ": メールの取得に失敗しました。");\r
+ }\r
+ \r
+ $result = $this->addItemByMail($userId, $msg);\r
+ if( $result ){\r
+ $this->_info(__LINE__ . ": メッセージを削除します");\r
+ $pop3->deleteMsg($i);\r
+ }\r
+ }\r
+ //切断\r
+ $pop3->disconnect();\r
+ $this->_info(__LINE__ . ": ユーザ($userId)のメールを取得終了しました");\r
+ }\r
+ }\r
+\r
+ function addItemByMail($userId, $msg) {\r
+ // メールデコード\r
+ $params['include_bodies'] = TRUE;\r
+ $params['decode_bodies'] = TRUE;\r
+ $params['decode_headers'] = TRUE;\r
+ $params['input'] = $msg;\r
+ if(PEAR::isError( $decodedMsg = Mail_mimeDecode::decode($params)) ){ \r
+ $this->_warn(__LINE__ . ": メールデコードに失敗しました:" . $decodedMsg->getMessage() );\r
+ return true;\r
+ }\r
+\r
+ // From:\r
+ if ( $decodedMsg->headers['from'] ) {\r
+ $from = $this->_addr_search($decodedMsg->headers['from']);\r
+ }\r
+ if ( (! $from ) && $decodedMsg->headers['reply-to'] ) {\r
+ $from = $this->_addr_search($decodedMsg->headers['reply-to']);\r
+ }\r
+ if ( (! $from ) && $decodedMsg->headers['return-path'] ) {\r
+ $from = $this->_addr_search($decodedMsg->headers['return-path']);\r
+ }\r
+ if ( ! $from ){\r
+ $this->_warn(__LINE__ . ": メールに送信者アドレスが見つかりません");\r
+ return true;\r
+ }\r
+ $this->_info(__LINE__ . ": From($from)");\r
+\r
+ // 投稿可能かチェック\r
+ $from = strtolower(Trim($from));\r
+ if ( in_array($from, $this->accept) ) {\r
+ $this->_info(__LINE__ . ": 投稿許可アドレスに含まれているので受付($from)");\r
+ } elseif( in_array( "*", $this->accept) ){\r
+ $this->_info(__LINE__ . ": 投稿許可アドレスにワイルドカードが含まれているので受付($from)");\r
+ }else {\r
+ if( $this->execMode == 0 ){\r
+ $this->_info(__LINE__ . ": 投稿許可アドレスに含まれていないので拒否($from)。振り分け対応モードなので他のアカウントで取得が行われる場合があります。");\r
+ } else {\r
+ $this->_warn(__LINE__ . ": 投稿許可アドレスに含まれていないので拒否($from)");\r
+ }\r
+ // 互換の場合は true\r
+ // 振り分けの場合は false\r
+ return $this->execMode;\r
+ }\r
+\r
+ // Date:\r
+ $blog =& new BLOG($this->blogid);\r
+ \r
+ $timestamp = strtotime( trim($decodedMsg->headers['date']) );\r
+ if ($timestamp == -1){\r
+ $this->_info(__LINE__ . ": Dateヘッダからのtimestamp取得に失敗しました。");\r
+ $timestamp = 0; \r
+ }\r
+ $timestamp = $blog->getCorrectTime($timestamp);\r
+\r
+ // Subject:\r
+ $subject = $this->_convert($decodedMsg->headers['subject']);\r
+ \r
+ // Subject: prefixチェック \r
+ if ( $this->acceptSubjectPrefix ){\r
+ $this->_info(__LINE__ . ": 投稿許可SubjectPrefixがあります(prefix: $this->acceptSubjectPrefix)"); \r
+ $pos = mb_strpos($subject, $this->acceptSubjectPrefix);\r
+ if( $pos === 0 ){\r
+ // prefix切り取り\r
+ $subject = mb_substr($subject, mb_strlen($this->acceptSubjectPrefix) );\r
+ $this->_info(__LINE__ . ": 投稿許可SubjectPrefixをみつけました(prefix削除後subject: $subject)"); \r
+ } else {\r
+ $this->_warn(__LINE__ . ": 投稿許可SubjectPrefixがないので拒否します($subject)");\r
+ return true;\r
+ }\r
+ }\r
+ \r
+ // subject: オプション分割\r
+ if (preg_match('/'.$this->optionsKeyword.'/i', $subject)) {\r
+ list ($subject, $option) = spliti($this->optionsKeyword, $subject, 2);\r
+\r
+ $this->_info(__LINE__ . ": Subject($subject), Option($option)");\r
+ \r
+ $option = '&'.$option;\r
+ if (preg_match('/&' . $this->blogKeyword . '=([^&=]+)/i', $option, $word)) {\r
+ $this->blogid = $word[1];\r
+ $this->_info(__LINE__ . ': blogidを' . $this->blogid . 'で上書きします');\r
+ }\r
+ if (preg_match('/&' . $this->categoryKeyword . '=([^&=]+)/i', $option, $word)) {\r
+ $this->categoryNameOrId = $word[1];\r
+ $this->_info(__LINE__ . ': Categoryを' . $this->categoryNameOrId . 'で上書きします');\r
+ }\r
+ if (preg_match('/&' . $this->publishKeyword . '=([^&=]+)/i', $option, $word)) {\r
+ $this->DefaultPublish = $word[1];\r
+ $this->_info(__LINE__ . ($this->DefaultPublish ? ': 投稿を公開に上書きします' : ': 投稿を下書きに上書きします'));\r
+ }\r
+ }\r
+ \r
+ // Subject: 空の場合\r
+ if( ! $subject = trim(htmlspecialchars($subject, ENT_QUOTES)) ){\r
+ $subject = $this->nosubject;\r
+ }\r
+\r
+ // body\r
+ $text = ""; \r
+ if( strtolower($decodedMsg->ctype_primary) == "text" ){\r
+ $this->_info(__LINE__ . ": single partメッセージです");\r
+ $text = $this->_textPart($decodedMsg);\r
+ } elseif ( strtolower($decodedMsg->ctype_primary) == "multipart" ){\r
+ $this->_info(__LINE__ . ": multipart partメッセージです");\r
+ $texts = Array();\r
+ $fileNames = Array(); \r
+ $this->_decodeMultiPart($decodedMsg->parts, $texts, $fileNames);\r
+ \r
+ $text = $texts['plain'];\r
+ if( $texts['html'] ) $text = $texts['html'];\r
+ }\r
+ \r
+ if ($this->imgonly && (! $fileNames) ) {\r
+ $this->_info(__LINE__ . ": 添付ファイルがないので書き込みません");\r
+ return true;\r
+ }\r
+\r
+ if( $this->_isSpam($text) ){\r
+ $this->_warn(__LINE__ . ": SPAMのため追加しません");\r
+ return true;\r
+ }\r
+ \r
+ $body = '';\r
+ // body 生成\r
+ if ( ! $fileNames ) {\r
+ // 添付ファイルがない場合のbody \r
+ $vars = array (\r
+ 'body' => $text,\r
+ );\r
+ // textTpl\r
+ $body .= TEMPLATE :: fill($this->getMemberOption($this->memid, 'textTpl'), $vars);\r
+ } else {\r
+ // 添付ファイルがある場合のbody\r
+ $lastFile = array_pop($fileNames);\r
+ \r
+ foreach( $fileNames as $filename ){\r
+ $body .= $this->_imageHtml($filename);\r
+ }\r
+ \r
+ $body .= $this->_imageHtml($lastFile, $text);\r
+ }\r
+ \r
+ // item追加\r
+ $this->_info(__LINE__ . ": アイテム追加します");\r
+ \r
+ // bodyをbodyとmoreに分割\r
+ $more = '';\r
+ if( $this->moreDelimiter )\r
+ list($body, $more) = spliti($this->moreDelimiter, $body, 2);\r
+ \r
+ $body = trim($body);\r
+ $more = trim($more);\r
+ \r
+ $this->_addDatedItem($this->blogid, $subject, $body, $more, 0, $timestamp, 0, $this->categoryNameOrId);\r
+ return true;\r
+ }\r
+ \r
+ function _decodeMultiPart($parts, &$texts, &$fileNames){\r
+ foreach($parts as $part){\r switch ( strtolower( $part->ctype_primary )){\r
+ // multipart\r
+ case 'multipart':\r
+ $this->_decodeMultiPart($part->parts, $texts, $fileNames);\r
+ break;\r
+ //text part\r
+ case 'text':\r
+ $this->_info(__LINE__ . ": text part をみつけました[{$part->ctype_primary}/{$part->ctype_secondary}]");\r
+ $texts[$part->ctype_secondary] = $this->_textPart($part);\r
+ break;\r
+ // imagepart\r
+ case 'image':\r
+ default:\r
+ $this->_info(__LINE__ . ": image/data part をみつけました[{$part->ctype_primary}/{$part->ctype_secondary}]");\r
+ if( $fileName = $this->_imagePart($part) )\r
+ $fileNames[] = $fileName;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ function _textPart(&$part){\r
+ $encoding = false;\r
+ if( $part->ctype_parameters )\r
+ $encoding = $this->ctype_parameters['charset'];\r
+ \r
+ $text = $this->_convert($part->body, $encoding);\r
+ $text = strip_tags($text, $this->no_strip_tags);\r
+ \r
+ $blog =& new BLOG($this->blogid);\r
+ //blog設定で改行を<br />に置換onの場合\r
+ if ($blog->getSetting('bconvertbreaks')) { \r
+ if ( strtolower($part->ctype_secondary) == 'html' ) {\r
+ //改行文字を削除、<br>タグを\nへ\r
+ $text = str_replace("\r\n", "\r", $text);\r
+ $text = str_replace("\r", "\n", $text);\r
+ $text = str_replace("\n", "", $text);\r
+ $text = str_replace("<br>", "\n", $text);\r
+ }\r
+ }\r
+ return $text;\r
+ }\r
+ \r
+ function _imagePart(&$part){\r
+ if( !$this->prefixDate ){\r
+ $this->prefixDate = date('YmdHis');\r
+ $this->fileCount = 0;\r
+ } else {\r
+ $this->fileCount += 1;\r
+ }\r
+ $this->filePrefix = $this->prefixDate . sprintf('%02d', $this->fileCount);\r
+ \r
+ $filename = "";\r
+ if( $part->d_parameters ){\r
+ $filename = $part->d_parameters['filename'];\r
+ } elseif( $part->ctype_parameters ){\r
+ $filename = $part->ctype_parameters['name'];\r
+ } else {\r
+ $filename = $part->ctype_secondary;\r
+ }\r
+\r
+ $filename = $this->_convert($filename);\r
+ $filename = $this->filePrefix . "-" . $filename; \r
+ $this->_info(__LINE__ . ": FileName($filename)");\r
+ \r
+ // subtypeチェック\r
+ $size = strlen($part->body);\r
+ if( preg_match("/".$this->subtype."/i", trim($part->ctype_secondary) )){\r
+ // サイズ、拡張子チェック\r
+ if ($size < $this->maxbyte && preg_match("/".$this->viri.'/i', $filename)) {\r
+ \r
+ $fp = fopen($this->tmpdir.$filename, "w");\r
+ fputs($fp, $part->body);\r
+ fclose($fp);\r
+ \r
+ $size = @getimagesize($this->tmpdir.$filename);\r
+ //サムネイル作成する場合\r
+ if ($this->thumb_ok && function_exists('ImageCreate')) {\r
+ //サムネイル作成する拡張子の場合\r
+ if ( preg_match("/$this->thumb_ext/i", $filename) ) {\r
+ if ($size[0] > $this->W || $size[1] > $this->H) {\r
+ $this->_thumb_create($this->tmpdir.$filename, $this->W, $this->H, $this->thumb_dir);\r
+ }\r
+ }\r
+ }\r
+ return $filename;\r
+ }\r
+ $this->_warn(__LINE__ . ": 添付ファイルを無視します。(サイズ超過: $size B or 保存しないファイルに該当しています) [$part->ctype_primary/$part->ctype_secondary]");\r
+ return false;\r
+ }\r
+ $this->_warn(__LINE__ . ": 添付ファイルを無視します。(subtypeチェック: $part->ctype_secondary が対応MIMEタイプに入っていますか?) [$part->ctype_primary/$part->ctype_secondary]");\r
+ return false; \r
+ }\r
+ \r
+ function _imageHtml($filename, $body = ""){\r
+ global $CONF;\r
+ \r
+ $size = @getimagesize($this->tmpdir.$filename);\r
+ $thumb_size = @getimagesize($this->thumb_dir.$this->_getThumbFileName($filename));\r
+ $smallH = round($this->smallW / $size[0] * $size[1], 0);\r
+\r
+ $vars = array (\r
+ 'thumbW' => $thumb_size[0],\r
+ 'thumbH' => $thumb_size[1],\r
+ 'reductionW' => $this->smallW, \r
+ 'reductionH' => $smallH,\r
+ 'sizeW' => $size[0],\r
+ 'sizeH' => $size[1],\r
+ 'body' => $body,\r
+ 'thumbUrl' => $this->thumb_collection.'/' . urlencode($this->_getThumbFileName($filename)),\r
+ 'imageUrl' => $this->collection.'/' . urlencode($filename),\r
+ 'mediaUrl' => $CONF['MediaURL'],\r
+ 'fileName' => $filename\r
+ );\r
+ \r
+ // データファイルチェック\r
+ if( ! preg_match("/$this->imgExt/i", $filename) ){\r
+ $this->_info(__LINE__ . ": 画像ファイルに該当しないので、データファイルテンプレートを使用します");\r
+ return TEMPLATE :: fill($this->getMemberOption($this->memid, 'dataTpl'), $vars);\r
+ }\r
+\r
+ if ( $thumb_size[0] ) { //サムネイルがある場合のソース\r
+ $this->_info(__LINE__ . ": サムネイルがあります");\r
+ return TEMPLATE :: fill($this->getMemberOption($this->memid, 'withThumbTpl'), $vars);\r
+ } else { //サムネイルがない場合のソース\r
+ if ($size[0] > $this->smallW) { //縮小表示\r
+ $this->_info(__LINE__ . ": サムネイルがありません、縮小表示します");\r
+ return TEMPLATE :: fill($this->getMemberOption($this->memid, 'reductionTpl'), $vars);\r
+ } else { //そのまま表示\r
+ $this->_info(__LINE__ . ": サムネイルがありません");\r
+ return TEMPLATE :: fill($this->getMemberOption($this->memid, 'withoutThumbTpl'), $vars);\r
+ }\r
+ }\r
+ }\r
+ \r
+ function _addDatedItem($blogid, $title, $body, $more, $closed, $timestamp, $future, $catNameOrId = "") {\r
+ // 1. ログイン======================\r
+ $mem = MEMBER :: createFromID($this->memid);\r
+\r
+ // 2. ブログ追加できるかチェック======================\r
+ if (!BLOG :: existsID($this->blogid)) {\r
+ $this->_info(__LINE__ . ": 存在しないblogです");\r
+ return false;\r
+ }\r
+ $this->_info(__LINE__ . ": blogidはOK!");\r
+\r
+ if (!$mem->isTeamMember($blogid)) {\r
+ $this->_warn(__LINE__ . ": メンバーではありません");\r
+ return false;\r
+ }\r
+ $this->_info(__LINE__ . ": メンバーチェックもok!");\r
+ \r
+ if (!trim($body)) {\r
+ $this->_warn(__LINE__ . ": 空のアイテムは追加できません");\r
+ return false;\r
+ }\r
+ $this->_info(__LINE__ . ": アイテムは空じゃないです");\r
+\r
+ // 3. 値の補完\r
+ $blog =& new BLOG($this->blogid);\r
+ if( $blog->isValidCategory($catNameOrId) ){\r
+ // カテゴリIDとして有効なときはそのまま使う\r
+ $catid = $catNameOrId;\r
+ } else {\r
+ // カテゴリID ゲット (誤ったカテゴリID使用時はデフォを使用)\r
+ $catid = $blog->getCategoryIdFromName($catNameOrId);\r
+ }\r
+ \r
+ $this->_info(__LINE__ . ": 追加するcatid: ".$catid);\r
+ if ($this->DefaultPublish) {\r
+ $draft = 0;\r
+ } else {\r
+ $draft = 1; //ドラフト追加\r
+ $this->_info(__LINE__ . ": ドラフトで追加します");\r
+ }\r
+ if ($closed != 1)\r
+ $closed = 0; //コメントを許可\r
+ $this->_info(__LINE__ . ": \$catid:".$catid.", \$draft:".$draft.", \$closed:".$closed);\r
+\r
+ // 4. blogに追加\r
+ $itemid = $blog->additem($catid, $title, $body, $more, $blogid, $mem->getID(), $timestamp, $closed, $draft);\r
+ \r
+ $this->_info(__LINE__ . ": itemid: $itemid");\r
+ return $itemid;\r
+ }\r
+ \r
+ function _isSpam($str){\r
+ global $manager;\r
+ if( $this->getOption('spamCheck') == 'yes' ){ \r
+ $spamcheck = array (\r
+ 'type' => 'Moblog',\r
+ 'data' => $str,\r
+ 'return' => true,\r
+ 'ipblock' => false\r
+ );\r
+ $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));\r
+ if (isset($spamcheck['result']) && $spamcheck['result'] == true)\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+}\r