swfedなしのpure phpでreplaceEditStringを実現する

長らくご無沙汰しておりました。

swfedを入れられない....環境向けにpure phpでreplaceEditString するコードがないか、ぐぐったのですが、action script経由での挿入しか見つからなかったのでコードを書いてみました。リファクタをしていない、とりあえず動くだけのコードになります。結構面倒だったので、気が向いたらそのうちリファクタします。

以下、参考にしたURLを列挙します。主にyoyaさんのGREE LABSの記事とSWF仕様書和訳Wikiページを参考にしました。yoyaさんのGREE LABSの連載記事にreplaceEditStringの記事があれば良かったのですが、なかったので作ることになりました。尚、GREE LABSの記事で使用されているyoyaさんが作成したライブラリが必須ですので事前にインストールをしておいてください。これは...まぁあれですね。素直にswfedをインストールした方がいいんじゃないかと思います。

yoyaさんのライブラリをインストール

pear channel-discover openpear.org
pear install openpear/IO_Bit
pear install openpear/IO_SWF
<?php
require 'IO/SWF.php';
$swfdata = file_get_contents($argv[1]);
$swf = new IO_SWF();
$swf->parse($swfdata);

function readDefineEditText($data){
    $det = array();
    $reader = new IO_Bit();
    $reader->input($data);
    $det['CharacterID'] = $reader->getUI16LE();
    $det['Bounds']['NBits'] = $reader->getUIBits(5);
    $det['Bounds']['Xmin']  = $reader->getUIBits($det['Bounds']['NBits']);
    $det['Bounds']['Xmax']  = $reader->getUIBits($det['Bounds']['NBits']);
    $det['Bounds']['Ymin']  = $reader->getUIBits($det['Bounds']['NBits']);
    $det['Bounds']['Ymax']  = $reader->getUIBits($det['Bounds']['NBits']);
    $reader->byteAlign();
    $flags = array(
      'HasText'     , 'WordWrap'    , 'Multiline'   , 'Password'   ,
      'ReadOnly'    , 'HasTextColor', 'HasMaxLength', 'HasFont'    ,
      'HasFontClass', 'AutoSize'    , 'HasLayout'   , 'NoSelect'   ,
      'Border'      , 'WasStatic'   , 'HTML'        , 'UseOutlines',
    );
    foreach($flags as $flag){
      $det[$flag]      = $reader->getUIBit();
    }
    if($det['HasFont']){
      $det['FontID']  = $reader->getUI16LE();
    }
    if($det['HasFontClass']){
      $str='';
      while( $ch = $reader->getUI8()){
        if($ch == chr(0x00)) break;
        $str.=chr($ch);
      }
      $det['FontClass']  = $str;
    }
    if($det['HasFont']){
      $det['FontHeight']  = $reader->getUI16LE();
    }
    if($det['HasTextColor']){
        $det['TextColor']['Red']   = $reader->getUI8();
        $det['TextColor']['Blue']  = $reader->getUI8();
        $det['TextColor']['Green'] = $reader->getUI8();
        $det['TextColor']['Alpha'] = $reader->getUI8();
    }
    if($det['HasMaxLength']){
      $det['MaxLength']  = $reader->getUI16LE();
    }
    if($det['HasLayout']){
      $det['Align']       = $reader->getUI8();
      $det['LeftMargin']  = $reader->getUI16LE();
      $det['RightMargin'] = $reader->getUI16LE();
      $det['Indent']      = $reader->getUI16LE();
      $det['Leading']     = $reader->getUI16LE();
    }
    $str='';
    while( $ch = $reader->getUI8()){
      if($ch == chr(0x00)) break;
      $str.=chr($ch);
    }
    $det['VariableName']  = $str;
    $str='';
    while( $ch = $reader->getUI8()){
      if($ch == chr(0x00)) break;
      $str.=chr($ch);
    }
    $det['InitialText']  = $str;
   return $det;
}

function writeDefineEditText($det){
    $writer = new IO_Bit();
    $writer->putUI16LE($det['CharacterID']);
    $writer->putUIBits($det['Bounds']['NBits'],5);
    $writer->putUIBits($det['Bounds']['Xmin'],$det['Bounds']['NBits']);
    $writer->putUIBits($det['Bounds']['Xmax'],$det['Bounds']['NBits']);
    $writer->putUIBits($det['Bounds']['Ymin'],$det['Bounds']['NBits']);
    $writer->putUIBits($det['Bounds']['Ymax'],$det['Bounds']['NBits']);
    $writer->byteAlign();
    $flags = array(
      'HasText'     , 'WordWrap'    , 'Multiline'   , 'Password'   ,
      'ReadOnly'    , 'HasTextColor', 'HasMaxLength', 'HasFont'    ,
      'HasFontClass', 'AutoSize'    , 'HasLayout'   , 'NoSelect'   ,
      'Border'      , 'WasStatic'   , 'HTML'        , 'UseOutlines',
    );
    foreach($flags as $flag){
      $writer->putUIBit($det[$flag]); 
    }
    if($det['HasFont']){
      $writer->putUI16LE($det['FontID']);
    }
    if($det['HasFontClass']){
      foreach(str_split($det['FontClass']) as $ch){
        $writer->putUI8(ord($ch));
      }
      $writer->putUI8(0x00);
    }
    if($det['HasFont']){
      $writer->putUI16LE($det['FontHeight']);
    }
    if($det['HasTextColor']){
      $writer->putUI8($det['TextColor']['Red']);
      $writer->putUI8($det['TextColor']['Blue']); 
      $writer->putUI8($det['TextColor']['Green']); 
      $writer->putUI8($det['TextColor']['Alpha']); 
    }
    if($det['HasMaxLength']){
      $writer->putUI16LE($det['MaxLength']);
    }
    if($det['HasLayout']){
       $writer->putUI8(   $det['Align']       );
       $writer->putUI16LE($det['LeftMargin']  );
       $writer->putUI16LE($det['RightMargin'] );
       $writer->putUI16LE($det['Indent']      );
       $writer->putUI16LE($det['Leading']     );
    }

    foreach(str_split($det['VariableName']) as $ch){
      $writer->putUI8(ord($ch));
    }
    $writer->putUI8(0x00);

    foreach(str_split($det['InitialText'])  as $ch){
      $writer->putUI8(ord($ch));
    }
    $writer->putUI8(0x00);

   return $writer->output();
}

foreach($swf->_tags as $tag_id=>$tag){
  if($tag['Code']==37){
    $old = $tag['Content'];
    $det = readDefineEditText($tag['Content']);
    // 置換文字列
    $replace_texts = array(
	'text' 	=> mb_convert_encoding('テスト','sjis-win'),
	'url1' 	=> 'http://www.yahoo.co.jp/',
	'url2' 	=> 'http://www.google.com/' ,
    );
      
    foreach($replace_texts as $k => $v){
      if($det['VariableName']==$k){
        $det['InitialText']=$v;
      }
    }
    $tag['Content'] = writeDefineEditText($det);
    $tag['Length']  = strlen($tag['Content']);
    $swf->_tags[$tag_id]=$tag;
  }
}

echo $swf->build();