plugins:mobilewithsinglepage:mobilewithsinglepage_code

NP_MobileWithSinglePage.phpのソースコード

これは最新バージョンのソースコードではありません

<?php
 
/**
 * NP_MobileWithSinglePage v1.5.1
 * 携帯電話搭載のブラウザでの閲覧用にページの内容を変更します
 * --------
 *
 * Copyright (C) 2004 Jun (NP_Mobile)
 * Copyright (C) 2006 nakahara21 (NP_SkinSwitcher)
 * Copyright (C) 2006 NKJG
 * 
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * --------
 * History :
 * ver.1.0 (20060217)
 * - 最初のリリース
 * ver.1.1 (20060220)
 * - HTMLコメント除去部分の修正
 * ver.1.2 (20060315)
 * - コメント投稿時にエンコードを変更する機能を追加
 * - 管理ページは変換の対象外にした
 * ver.1.3 (20060323)
 * - 出力バッファリング周りのコードを修正
 * ver.1.4 (20060407)
 * - 各イベントハンドラのパラメータに「&」を付け忘れていた問題を修正
 * ver.1.5 (20060424)
 * - スキンの変更に失敗する不具合の修正
 * ver.1.5.1 (20060427)
 * - 動作しなくなる致命的な不具合の修正
 */
 
class NP_MobileWithSinglePage extends NucleusPlugin {
  var $isMobile;
  var $ob_started;
 
  var $aSafeAttributes;
  var $quote;
 
  function getName(){ return 'Mobile With Single Page'; }
  function getAuthor(){ return 'NKJG (original by Jun (NP_Mobile))'; }
  function getURL(){ return 'http://niku.suku.name/'; }
  function getVersion(){ return '1.5.1'; }
  function getMinNucleusVersion() { return '322'; }
  function getDescription(){
    return 'Change skin and encoding for mobile browser.';
  }
 
  function supportsFeature($what) { return (int)($what == 'SqlTablePrefix'); }
 
  function getEventList() {
    return array( 'InitSkinParse', 'PreSkinParse', 'PostSkinParse', 'PreSendContentType' ,'PreAddComment');
  }
 
  function Install() {
    $this->createOption('mobileSkin', 'Select mobile skin :', 'text', 'mobile');
    $this->createOption('convertIMG', 'Convert IMG into :', 'select', 'text', 'text|text|link|link|blank|blank|noconvert|noconvert');
    $this->createOption('convertHankaku', 'Convert Zenkaku-Katakana into Hankaku :', 'yesno', 'yes');
    $this->createOption('tagsNotRemove', 'Tags will NOT be removed :', 'text', 'html|head|title|meta|body|h1|h2|h3|h4|h5|h6|form|input|label|textarea|ul|ol|li|br|hr|p|div|table|tr|td|th|img|a');
    $this->createOption('removeAttributes', 'Remove attributes :', 'yesno', 'yes');
    $this->createOption('removeQuotation', 'Remove quotation mark of attributes :', 'yesno', 'no');
    $this->createOption('attributesNotRemove', 'Attributes will NOT be removed :', 'text', 'id|src|name|href|alt|action|method|enctype|accept|accpept-charset|value|type|for|title|http-equiv|content|scheme|accesskey');
    $this->createOption('UserAgent', 'User-Agents of Mobile :', 'text', 'DoCoMo|J-PHONE|UP\.Browser');
  }
 
  function Init(){
    $this->isMobile = 'unset';
    $this->ob_started = false;
 
    $this->aSafeAttributes = explode('|', $this->getOption('attributesNotRemove'));
    $this->quote = ($this->getOption('removeQuotation') != 'no') ? '' : '"';
  }
 
  function event_InitSkinParse(&$data) {
    // UAがモバイルと設定されたモノに該当するかどうかチェック
    if(!$this->_isMobileUA()) return;
 
    // モバイル用のスキンに切り替え(該当するスキンが存在しなくても処理は続行される)
    $skinName = trim($this->getOption('mobileSkin'));
    if (SKIN::exists($skinName)) {
      $skin =& SKIN::createFromName($skinName);
      // copied from NP_SkinSwitcher.php
      $data['skin']->SKIN($skin->getID()); 
    }
  }
 
  function event_PreSendContentType(&$data) {
    if($this->_isMobileUA()) {
      $data['charset'] = 'Shift_JIS';
      $data['contentType'] = 'text/html';
    }
  }
 
  function event_PreSkinParse(&$data) {
    if(!$this->_isMobileUA()) return;
 
    // header送信
    header("Pragma: no-cache");
 
    // 処理開始
    $this->ob_started = ob_start(array($this,'doConvert'));
  }
 
  function event_PostSkinParse(&$data) {
    if($this->ob_started)
      ob_end_flush();
  }
 
  function doConvert($contents) {
    // コメントの除去
    $contents = preg_replace('|<!--.*?-->|is', '', $contents);
 
    // DOCTYPE宣言やXML宣言の除去
    $contents = preg_replace('|<[!?][^>]*?>|is', '', $contents);
 
    // IMG要素を置き換え
    if(preg_match('!<img!is', $contents)) {
      $convertIMG = $this->getOption('convertIMG');
      switch($convertIMG) {
      case 'blank' :
        preg_replace('!<img[^>]*?>!is','',$contents);
        break;
      case 'text' :
        $aContents = preg_split('!(<img[^>]*>)!is', $contents, -1, PREG_SPLIT_DELIM_CAPTURE);
        for($i=0; $i<count($aContents); $i++) {
          if($i%2) {
            $aContents[$i] = $this->_convertIMGIntoText($aContents[$i]);
          }
        }
        $contents = implode('', $aContents);
        break;
      case 'link' :
        $aContents = preg_split('!(<img[^>]*>)!is', $contents, -1, PREG_SPLIT_DELIM_CAPTURE);
        for($i=0; $i<count($aContents); $i++) {
          if($i%2) {
            $aContents[$i] = $this->_convertIMGIntoLink($aContents[$i]);
          }
        }
        $contents = implode('', $aContents);
        break;
      default :
        break;
      }
    }
 
    // 不要なタグの除去
    $tagsNotRemove = ('<' . implode('><', explode('|', $this->getOption('tagsNotRemove'))) . '>');
    $contents = strip_Tags($contents, $tagsNotRemove);
 
    // 不要な文字の削除
    $contents = preg_replace('/[\n\r\t]+/','',$contents); // 改行文字・タブ文字の削除
    $contents = preg_replace('/\s+/',' ',$contents); // 連続するホワイトスペースの削除
 
    // 不要な属性の削除
    if($this->getOption('removeAttributes') != 'no'){
      $aContents = preg_split('!(<[^/>]*?\s[^>]*>)!is', $contents,  -1, PREG_SPLIT_DELIM_CAPTURE);
      for($i=0; $i<count($aContents); $i++) {
        if($i%2) {
          $aContents[$i] = $this->_removeAttributes($aContents[$i]);
        }
      }
      $contents = implode('', $aContents);
    }
 
    $contents = $this->_removeEmptyElement($contents);
 
    // 半角カナに変更
    if($this->getOption('convertHankaku')!='no' && function_exists('mb_convert_kana')) {
      $contents = mb_convert_kana($contents, 'rnask');
    }
 
    // SJISにエンコード
    if(function_exists('mb_convert_encoding')) {
      $contents = mb_convert_encoding($contents, 'sjis', _CHARSET);
    }
 
    return preg_replace('!^[\s\n\r]+|[\s\n\r]+$!is', '', $contents);
  }
 
  // コメントの文字化けを修正
  function event_PreAddComment(&$data) {
    if(!$this->_isMobileUA()) return;
 
    // エンコード元が'auto'になってるのはNP_NanasiSanとの衝突を避けるためです。
    $data['comment']['user'] = $contents = mb_convert_encoding($data['comment']['user'], _CHARSET, 'auto');
    $data['comment']['body'] = $contents = mb_convert_encoding($data['comment']['body'], _CHARSET, 'auto');
 
 
  }
 
  // UAとパスの判別
  function _isMobileUA() {
    global $CONF;
    if($this->isMobile == 'unset') {
      $ua = serverVar('HTTP_USER_AGENT');
      $this->isMobile = (
        preg_match('/' . $this->getOption('UserAgent') . '/i', $ua) &&
        !$CONF['UsingAdminArea']
        );
    }
    return $this->isMobile;
  }
 
  // IMGタグをプレーンテキストに変換
  function _convertIMGIntoText($tag) {
    if(preg_match('!alt="([^"]*)"!is',$tag,$matches)) {
      return $matches[1];
    } elseif(preg_match('!src="([^"]*)"!is',$tag,$matches)) {
      return $matches[1];
    }
    return '';
  }
 
  // IMGタグをA要素に変換
  function _convertIMGIntoLink($tag) {
    if(preg_match('!src="([^"]*)"!is',$tag,$matches)) {
      $src = $matches[1];
      if(preg_match('!alt="([^"]*)"!is',$tag,$out)) {
        $text = $out[1];
      } else {
        $text = '[image]';
      }
      return ('<a href="' . $src . '">' . $text . '</a>');
    }
    return '';
  }
 
  // 不要な属性の除去
  function _removeAttributes($tag) {
    preg_match_all('|\s*([^ ="]+)\s*=\s*"([^"]*)"\s*|is', $tag, $matches, PREG_SET_ORDER);
    if(!count($matches)) return $tag;
 
    preg_match('!^(<[^ >]*)!is',$tag,$matches_b);
    $newTag = $matches_b[1];
    $aAttributes = array();
    foreach($matches as $match) {
      if(in_array(strtolower($match[1]),$this->aSafeAttributes)) {
        $newTag .= ' ' . $match[1] . '=' . $this->quote . $match[2] . $this->quote;
      }
    }
    preg_match('!(\s/)?>$!is',$tag,$matches_c);
    $newTag .= $matches_c[0];
    return $newTag;
  }
 
  function _removeEmptyElement($text) {
    return preg_replace('!<([^ >/]*)></\1>!is', '', $text);
  }
}
 
?>
 
plugins/mobilewithsinglepage/mobilewithsinglepage_code.txt · 最終更新: 2011/03/23 21:28 (外部編集)