plugins:mobilewithsinglepage:mobilewithsinglepage_code

差分

この文書の現在のバージョンと選択したバージョンの差分を表示します。

この比較画面にリンクする

plugins:mobilewithsinglepage:mobilewithsinglepage_code [2011/03/23 21:28] (現在)
ライン 1: ライン 1:
 +====== NP_MobileWithSinglePage.phpのソースコード ======
  
 +**これは最新バージョンのソースコードではありません**
 +
 +<code 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);
 +  }
 +}
 +
 +?>
 +</​code>​
 
plugins/mobilewithsinglepage/mobilewithsinglepage_code.txt · 最終更新: 2011/03/23 21:28 (外部編集)