Ignore:
Timestamp:
2013/08/28 13:55:43 (11 years ago)
Author:
m_uehara
Message:

#2348 r23140 をマージ

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_13_0/data/module/SearchReplace.php

    r23126 r23143  
    11<?php 
    2 /* 
    3  * This file is part of EC-CUBE 
     2// +-----------------------------------------------------------------------+ 
     3// | Copyright (c) 2002-2005, Richard Heyes                                | 
     4// | All rights reserved.                                                  | 
     5// |                                                                       | 
     6// | Redistribution and use in source and binary forms, with or without    | 
     7// | modification, are permitted provided that the following conditions    | 
     8// | are met:                                                              | 
     9// |                                                                       | 
     10// | o Redistributions of source code must retain the above copyright      | 
     11// |   notice, this list of conditions and the following disclaimer.       | 
     12// | o Redistributions in binary form must reproduce the above copyright   | 
     13// |   notice, this list of conditions and the following disclaimer in the | 
     14// |   documentation and/or other materials provided with the distribution.| 
     15// | o The names of the authors may not be used to endorse or promote      | 
     16// |   products derived from this software without specific prior written  | 
     17// |   permission.                                                         | 
     18// |                                                                       | 
     19// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   | 
     20// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     | 
     21// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
     22// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  | 
     23// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
     24// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      | 
     25// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
     26// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
     27// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   | 
     28// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
     29// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  | 
     30// |                                                                       | 
     31// +-----------------------------------------------------------------------+ 
     32// | Author: Richard Heyes <richard@phpguru.org>                           | 
     33// +-----------------------------------------------------------------------+ 
     34// 
     35// $Id$ 
     36// 
     37// Search and Replace Utility 
     38// 
     39 
     40/** 
     41 * Search and Replace Utility 
    442 * 
    5  * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved. 
    643 * 
    7  * http://www.lockon.co.jp/ 
    8  * 
    9  * This program is free software; you can redistribute it and/or 
    10  * modify it under the terms of the GNU General Public License 
    11  * as published by the Free Software Foundation; either version 2 
    12  * of the License, or (at your option) any later version. 
    13  * 
    14  * This program is distributed in the hope that it will be useful, 
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    17  * GNU General Public License for more details. 
    18  * 
    19  * You should have received a copy of the GNU General Public License 
    20  * along with this program; if not, write to the Free Software 
    21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
     44 * @author  Richard Heyes <richard@phpguru.org> 
     45 * @version 1.0 
     46 * @package File 
    2247 */ 
    23  
    24 /* 
    25  * r21237 より前の誤ったファイル配置を前提とした決済モジュールでのエラーを抑制する役割。 
    26  * 本来のファイルはオートローダーが読み込みを行う。 
    27  * @deprecated 
    28  */ 
    29  
    30 trigger_error('従来互換用の HTTP_Request が読み込まれました。', E_USER_WARNING); 
     48class File_SearchReplace 
     49{ 
     50     
     51    // {{{ Properties (All private) 
     52 
     53    var $find; 
     54    var $replace; 
     55    var $files; 
     56    var $directories; 
     57    var $include_subdir; 
     58    var $ignore_lines; 
     59    var $ignore_sep; 
     60    var $occurences; 
     61    var $search_function; 
     62    var $php5; 
     63    var $last_error; 
     64 
     65    // }}} 
     66    // {{{ Constructor 
     67 
     68    /** 
     69     * Sets up the object 
     70     * 
     71     * @access public 
     72     * @param string $find                      The string/regex to find. 
     73     * @param string $replace                   The string/regex to replace $find with. 
     74     * @param array  $files                     The file(s) to perform this operation on. 
     75     * @param array  $directories    (optional) The directories to perform this operation on. 
     76     * @param bool   $include_subdir            If performing on directories, whether to traverse subdirectories. 
     77     * @param array  $ignore_lines              Ignore lines beginning with any of the strings in this array. This 
     78     *                                          feature only works with the "normal" search. 
     79     */ 
     80    function File_SearchReplace($find, $replace, $files, $directories = '', $include_subdir = TRUE, $ignore_lines = array()) 
     81    { 
     82 
     83        $this->find            = $find; 
     84        $this->replace         = $replace; 
     85        $this->files           = $files; 
     86        $this->directories     = $directories; 
     87        $this->include_subdir  = $include_subdir; 
     88        $this->ignore_lines    = (array) $ignore_lines; 
     89 
     90        $this->occurences      = 0; 
     91        $this->search_function = 'search'; 
     92        $this->php5            = (substr(PHP_VERSION, 0, 1) == 5) ? TRUE : FALSE; 
     93        $this->last_error      = ''; 
     94 
     95    } 
     96 
     97    // }}} 
     98    // {{{ getNumOccurences() 
     99 
     100    /** 
     101     * Accessor to return the number of occurences found. 
     102     * 
     103     * @access public 
     104     * @return int Number of occurences found. 
     105     */ 
     106    function getNumOccurences() 
     107    { 
     108        return $this->occurences; 
     109    } 
     110 
     111    // }}} 
     112    // {{{ getLastError() 
     113 
     114    /** 
     115     * Accessor for retrieving last error. 
     116     * 
     117     * @access public 
     118     * @return string The last error that occurred, if any. 
     119     */ 
     120    function getLastError() 
     121    { 
     122        return $this->last_error; 
     123    } 
     124 
     125    // }}} 
     126    // {{{ setFind() 
     127 
     128    /** 
     129     * Accessor for setting find variable. 
     130     * 
     131     * @access public 
     132     * @param string $find The string/regex to find. 
     133     */ 
     134    function setFind($find) 
     135    { 
     136        $this->find = $find; 
     137    } 
     138 
     139    // }}} 
     140    // {{{ setReplace() 
     141 
     142    /** 
     143     * Accessor for setting replace variable. 
     144     * 
     145     * @access public 
     146     * @param string $replace The string/regex to replace the find string/regex with. 
     147     */ 
     148    function setReplace($replace) 
     149    { 
     150        $this->replace = $replace; 
     151    } 
     152 
     153    // }}} 
     154    // {{{ setFiles() 
     155 
     156    /** 
     157     * Accessor for setting files variable. 
     158     * 
     159     * @access public 
     160     * @param array $files The file(s) to perform this operation on. 
     161     */ 
     162    function setFiles($files) 
     163    { 
     164        $this->files = $files; 
     165    } 
     166 
     167    // }}} 
     168    // {{{ setDirectories() 
     169 
     170    /** 
     171     * Accessor for setting directories variable. 
     172     * 
     173     * @access public 
     174     * @param array $directories The directories to perform this operation on. 
     175     */ 
     176    function setDirectories($directories) 
     177    { 
     178        $this->directories = $directories; 
     179    } 
     180 
     181    // }}} 
     182    // {{{ setIncludeSubdir 
     183 
     184    /** 
     185     * Accessor for setting include_subdir variable. 
     186     * 
     187     * @access public 
     188     * @param bool $include_subdir Whether to traverse subdirectories or not. 
     189     */ 
     190    function setIncludeSubdir($include_subdir) 
     191    { 
     192        $this->include_subdir = $include_subdir; 
     193    } 
     194 
     195    // }}} 
     196    // {{{ setIgnoreLines() 
     197 
     198    /** 
     199     * Accessor for setting ignore_lines variable. 
     200     * 
     201     * @access public 
     202     * @param array $ignore_lines Ignore lines beginning with any of the strings in this array. This 
     203     *                            feature only works with the "normal" search. 
     204     */ 
     205    function setIgnoreLines($ignore_lines) 
     206    { 
     207        $this->ignore_lines = $ignore_lines; 
     208    } 
     209 
     210    // }}} 
     211    // {{{ setSearchFunction() 
     212 
     213    /** 
     214     * Function to determine which search function is used. 
     215     * 
     216     * @access public 
     217     * @param string The search function that should be used. Can be any one of: 
     218     *               normal - Default search. Goes line by line. Ignore lines feature only works with this type. 
     219     *               quick  - Uses str_replace for straight replacement throughout file. Quickest of the lot. 
     220     *               preg   - Uses preg_replace(), so any regex valid with this function is valid here. 
     221     *               ereg   - Uses ereg_replace(), so any regex valid with this function is valid here. 
     222     */ 
     223    function setSearchFunction($search_function) 
     224    { 
     225        switch($search_function) { 
     226        case 'normal': $this->search_function = 'search'; 
     227            return TRUE; 
     228            break; 
     229 
     230        case 'quick' : $this->search_function = 'quickSearch'; 
     231            return TRUE; 
     232            break; 
     233 
     234        case 'preg'  : $this->search_function = 'pregSearch'; 
     235            return TRUE; 
     236            break; 
     237 
     238        case 'ereg'  : $this->search_function = 'eregSearch'; 
     239            return TRUE; 
     240            break; 
     241 
     242        default      : $this->last_error      = 'Invalid search function specified'; 
     243            return FALSE; 
     244            break; 
     245        } 
     246    } 
     247 
     248    // }}} 
     249    // {{{ search() 
     250 
     251    /** 
     252     * Default ("normal") search routine. 
     253     * 
     254     * @access private 
     255     * @param string $filename The filename to search and replace upon. 
     256     * @return array Will return an array containing the new file contents and the number of occurences. 
     257     *               Will return FALSE if there are no occurences. 
     258     */ 
     259    function search($filename) 
     260    { 
     261        $occurences = 0; 
     262        $file_array = file($filename); 
     263 
     264        if (empty($this->ignore_lines) && $this->php5) { // PHP5 acceleration 
     265            $file_array = str_replace($this->find, $this->replace, $file_array, $occurences); 
     266 
     267        } else { // str_replace() doesn't return number of occurences in PHP4 
     268                 // so we need to count them manually and/or filter strings 
     269            $ignore_lines_num = count($this->ignore_lines); 
     270 
     271            // just for the sake of catching occurences 
     272            $local_find    = array_values((array) $this->find); 
     273            $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; 
     274 
     275            for ($i=0; $i < count($file_array); $i++) { 
     276 
     277                if ($ignore_lines_num > 0) { 
     278                    for ($j=0; $j < $ignore_lines_num; $j++) { 
     279                        if (substr($file_array[$i],0,strlen($this->ignore_lines[$j])) == $this->ignore_lines[$j]) continue 2; 
     280                    } 
     281                } 
     282 
     283                if ($this->php5) { 
     284                    $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i], $counted); 
     285                    $occurences += $counted; 
     286                } else { 
     287                    foreach ($local_find as $fk => $ff) { 
     288                        $occurences += substr_count($file_array[$i], $ff); 
     289                        if (!is_array($local_replace)) { 
     290                            $fr = $local_replace; 
     291                        } else { 
     292                            $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; 
     293                        } 
     294                        $file_array[$i] = str_replace($ff, $fr, $file_array[$i]); 
     295                    } 
     296                } 
     297            } 
     298 
     299        } 
     300        if ($occurences > 0) $return = array($occurences, implode('', $file_array)); else $return = FALSE; 
     301        return $return; 
     302 
     303    } 
     304 
     305    // }}} 
     306    // {{{ quickSearch() 
     307 
     308    /** 
     309     * Quick search routine. 
     310     * 
     311     * @access private 
     312     * @param string $filename The filename to search and replace upon. 
     313     * @return array Will return an array containing the new file contents and the number of occurences. 
     314     *               Will return FALSE if there are no occurences. 
     315     */ 
     316    function quickSearch($filename) 
     317    { 
     318 
     319        clearstatcache(); 
     320 
     321        $file          = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); 
     322        $local_find    = array_values((array) $this->find); 
     323        $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; 
     324 
     325        $occurences    = 0; 
     326 
     327        // logic is the same as in str_replace function with one exception: 
     328        //   if <search> is a string and <replacement> is an array - substitution 
     329        //   is done from the first element of array. str_replace in this case 
     330        //   usualy fails with notice and returns "ArrayArrayArray..." string 
     331        // (this exclusive logic of SearchReplace will not work for php5, though, 
     332        // because I haven't decided yet whether it is bug or feature) 
     333 
     334        if ($this->php5) { 
     335            $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i], $counted); 
     336            $occurences += $counted; 
     337        } else { 
     338            foreach ($local_find as $fk => $ff) { 
     339                $occurences += substr_count($file, $ff); 
     340                if (!is_array($local_replace)) { 
     341                    $fr = $local_replace; 
     342                } else { 
     343                    $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; 
     344                } 
     345                $file = str_replace($ff, $fr, $file); 
     346            } 
     347        } 
     348 
     349        if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; 
     350        return $return; 
     351 
     352    } 
     353 
     354    // }}} 
     355    // {{{ pregSearch() 
     356 
     357    /** 
     358     * Preg search routine. 
     359     * 
     360     * @access private 
     361     * @param string $filename The filename to search and replace upon. 
     362     * @return array Will return an array containing the new file contents and the number of occurences. 
     363     *               Will return FALSE if there are no occurences. 
     364     */ 
     365    function pregSearch($filename) 
     366    { 
     367 
     368        clearstatcache(); 
     369 
     370        $file       = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); 
     371        $local_find    = array_values((array) $this->find); 
     372        $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; 
     373 
     374        $occurences = 0; 
     375 
     376        foreach($local_find as $fk => $ff) { 
     377            $occurences += preg_match_all($ff, $file, $matches); 
     378            if (!is_array($local_replace)) { 
     379                $fr = $local_replace; 
     380            } else { 
     381                $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; 
     382            } 
     383            $file = preg_replace($ff, $fr, $file); 
     384        } 
     385 
     386        if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; 
     387        return $return; 
     388 
     389    } 
     390 
     391    // }}} 
     392    // {{{ eregSearch() 
     393 
     394    /** 
     395     * Ereg search routine. 
     396     * 
     397     * @access private 
     398     * @param string $filename The filename to search and replace upon. 
     399     * @return array Will return an array containing the new file contents and the number of occurences. 
     400     *               Will return FALSE if there are no occurences. 
     401     */ 
     402    function eregSearch($filename) 
     403    { 
     404 
     405        clearstatcache(); 
     406 
     407        $file = fread($fp = fopen($filename, 'r'), max(1, filesize($filename))); fclose($fp); 
     408        $local_find    = array_values((array) $this->find); 
     409        $local_replace = (is_array($this->replace)) ? array_values($this->replace) : $this->replace; 
     410 
     411        $occurences = 0; 
     412 
     413        foreach($local_find as $fk => $ff) { 
     414            $occurences += count(split($ff, $file)) - 1; 
     415            if (!is_array($local_replace)) { 
     416                $fr = $local_replace; 
     417            } else { 
     418                $fr = (isset($local_replace[$fk])) ? $local_replace[$fk] : ""; 
     419            } 
     420            $file = ereg_replace($ff, $fr, $file); 
     421        } 
     422 
     423        if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE; 
     424        return $return; 
     425 
     426    } 
     427 
     428    // }}} 
     429    // {{{ writeout() 
     430     
     431    /** 
     432     * Function to writeout the file contents. 
     433     * 
     434     * @access private 
     435     * @param string $filename The filename of the file to write. 
     436     * @param string $contents The contents to write to the file. 
     437     */ 
     438    function writeout($filename, $contents) 
     439    { 
     440 
     441        if ($fp = @fopen($filename, 'w')) { 
     442            flock($fp,2); 
     443            fwrite($fp, $contents); 
     444            flock($fp,3); 
     445            fclose($fp); 
     446        } else { 
     447            $this->last_error = 'Could not open file: '.$filename; 
     448        } 
     449 
     450    } 
     451 
     452    // }}} 
     453    // {{{ doFiles() 
     454 
     455    /** 
     456     * Function called by doSearch() to go through any files that need searching. 
     457     * 
     458     * @access private 
     459     * @param string $ser_func The search function to use. 
     460     */ 
     461    function doFiles($ser_func) 
     462    { 
     463        if (!is_array($this->files)) $this->files = explode(',', $this->files); 
     464        for ($i=0; $i<count($this->files); $i++) { 
     465            if ($this->files[$i] == '.' OR $this->files[$i] == '..') continue; 
     466            if (is_dir($this->files[$i]) == TRUE) continue; 
     467            $newfile = $this->$ser_func($this->files[$i]); 
     468            if (is_array($newfile) == TRUE){ 
     469                $this->writeout($this->files[$i], $newfile[1]); 
     470                $this->occurences += $newfile[0]; 
     471            } 
     472        } 
     473    } 
     474 
     475    // }}} 
     476    // {{{ doDirectories() 
     477 
     478    /** 
     479     * Function called by doSearch() to go through any directories that need searching. 
     480     * 
     481     * @access private 
     482     * @param string $ser_func The search function to use. 
     483     */ 
     484    function doDirectories($ser_func) 
     485    { 
     486        if (!is_array($this->directories)) $this->directories = explode(',', $this->directories); 
     487        for ($i=0; $i<count($this->directories); $i++) { 
     488            $dh = opendir($this->directories[$i]); 
     489            while ($file = readdir($dh)) { 
     490                if ($file == '.' OR $file == '..') continue; 
     491 
     492                if (is_dir($this->directories[$i].$file) == TRUE) { 
     493                    if ($this->include_subdir == TRUE) { 
     494                        $this->directories[] = $this->directories[$i].$file.'/'; 
     495                        continue; 
     496                    } else { 
     497                        continue; 
     498                    } 
     499                } 
     500 
     501                $newfile = $this->$ser_func($this->directories[$i].$file); 
     502                if (is_array($newfile) == TRUE) { 
     503                    $this->writeout($this->directories[$i].$file, $newfile[1]); 
     504                    $this->occurences += $newfile[0]; 
     505                } 
     506            } 
     507        } 
     508    } 
     509 
     510    // }}} 
     511    // {{{ doSearch() 
     512     
     513    /** 
     514     * This starts the search/replace off. The behavior of this function will likely 
     515     * to be changed in future versions to work in read only mode. If you want to do 
     516     * actual replace with writing files - use doReplace method instead.  
     517     * 
     518     * @access public 
     519     */ 
     520    function doSearch() 
     521    { 
     522        $this->doReplace(); 
     523    } 
     524     
     525    // }}} 
     526    // {{{ doReplace() 
     527     
     528    /** 
     529     * This starts the search/replace off. Call this to do the replace. 
     530     * First do whatever files are specified, and/or if directories are specified, 
     531     * do those too. 
     532     * 
     533     * @access public 
     534     */ 
     535    function doReplace() 
     536    { 
     537        $this->occurences = 0; 
     538        if ($this->find != '') { 
     539            if ((is_array($this->files) AND count($this->files) > 0) OR $this->files != '') $this->doFiles($this->search_function); 
     540            if ($this->directories != '')                                                   $this->doDirectories($this->search_function); 
     541        } 
     542    } 
     543     
     544    // }}} 
     545 
     546} 
     547?> 
Note: See TracChangeset for help on using the changeset viewer.