home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 August / PCWorld_2001-08_cd.bin / Komunikace / phptriad / phptriadsetup2-11.exe / php / pear / File / SearchReplace.php < prev   
PHP Script  |  2000-10-08  |  14KB  |  390 lines

  1. <?php
  2. //
  3. // Search and Replace Utility
  4. //
  5.  
  6. //
  7. // +----------------------------------------------------------------------+
  8. // | Author:  Richard Heyes <richard.heyes@heyes-computing.net            |
  9. // | Version: 1.00                                                        |
  10. // | Updated: 08/10/2000                                                  |
  11. // |                                                                      |
  12. // |         See http://www.heyes-computing.net/scripts/ for full tar/zip |
  13. // |         including example file.                                      |
  14. // +----------------------------------------------------------------------+
  15.  
  16. class File_SearchReplace {
  17.     
  18.     // {{{ Properties (All private)
  19.  
  20.     var $find;
  21.     var $replace;
  22.     var $files;
  23.     var $directories;
  24.     var $include_subdir;
  25.     var $ignore_lines;
  26.     var $ignore_sep;
  27.     var $occurences;
  28.     var $search_function;
  29.     var $last_error;
  30.  
  31.     // }}}
  32.  
  33.     /**
  34.      * Sets up the object
  35.      *
  36.      * @access public
  37.      * @param string $find                      The string/regex to find.
  38.      * @param string $replace                   The string/regex to replace $find with.
  39.      * @param array  $files                     The file(s) to perform this operation on.
  40.      * @param array  $directories    (optional) The directories to perform this operation on.
  41.      * @param int    $include_subdir            If performing on directories, whether to traverse subdirectories.
  42.      * @param array  $ignore_lines              Ignore lines beginning with any of the strings in this array. This
  43.      *                                          feature only works with the "normal" search.
  44.      *
  45.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  46.      */
  47.     function File_SearchReplace($find, $replace, $files, $directories = '', $include_subdir = 1, $ignore_lines = array()){
  48.  
  49.         $this->find            = $find;
  50.         $this->replace         = $replace;
  51.         $this->files           = $files;
  52.         $this->directories     = $directories;
  53.         $this->include_subdir  = $include_subdir;
  54.         $this->ignore_lines    = $ignore_lines;
  55.  
  56.         $this->occurences      = 0;
  57.         $this->search_function = 'search';
  58.         $this->last_error      = '';
  59.  
  60.     }
  61.     
  62.     /**
  63.      * Accessor to return the number of occurences found.
  64.      *
  65.      * @access public
  66.      * @return int Number of occurences found.
  67.      *
  68.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  69.      */
  70.     function getNumOccurences(){
  71.         return $this->occurences;
  72.     }
  73.  
  74.     /**
  75.      * Accessor for retrieving last error.
  76.      *
  77.      * @access public
  78.      * @return string The last error that occurred, if any.
  79.      *
  80.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  81.      */
  82.     function getLastError(){
  83.         return $this->last_error;
  84.     }
  85.  
  86.     /**
  87.      * Accessor for setting find variable.
  88.      *
  89.      * @access public
  90.      * @param string $find The string/regex to find.
  91.      *
  92.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  93.      */
  94.     function setFind($find){
  95.         $this->find = $find;
  96.     }
  97.  
  98.     /**
  99.      * Accessor for setting replace variable.
  100.      *
  101.      * @access public
  102.      * @param string $replace The string/regex to replace the find string/regex with.
  103.      *
  104.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  105.      */
  106.     function setReplace($replace){
  107.         $this->replace = $replace;
  108.     }
  109.     
  110.     /**
  111.      * Accessor for setting files variable.
  112.      *
  113.      * @access public
  114.      * @param array $files The file(s) to perform this operation on.
  115.      *
  116.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  117.      */
  118.     function setFiles($files){
  119.         $this->files = $files;
  120.     }
  121.     
  122.     /**
  123.      * Accessor for setting directories variable.
  124.      *
  125.      * @access public
  126.      * @param array $directories The directories to perform this operation on.
  127.      *
  128.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  129.      */
  130.     function setDirectories($directories){
  131.         $this->directories = $directories;
  132.     }
  133.     
  134.     /**
  135.      * Accessor for setting include_subdir variable.
  136.      *
  137.      * @access public
  138.      * @param int $include_subdir Whether to traverse subdirectories or not.
  139.      *
  140.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  141.      */
  142.     function setIncludeSubdir($include_subdir){
  143.         $this->include_subdir = $include_subdir;
  144.     }
  145.     
  146.     /**
  147.      * Accessor for setting ignore_lines variable.
  148.      *
  149.      * @access public
  150.      * @param array $ignore_lines Ignore lines beginning with any of the strings in this array. This
  151.      *                            feature only works with the "normal" search.
  152.      *
  153.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  154.      */
  155.     function setIgnoreLines($ignore_lines){
  156.         $this->ignore_lines = $ignore_lines;
  157.     }
  158.     
  159.     /**
  160.      * Function to determine which search function is used.
  161.      *
  162.      * @access public
  163.      * @param string The search function that should be used. Can be any one of:
  164.      *               normal - Default search. Goes line by line. Ignore lines feature only works with this type.
  165.      *               quick  - Uses str_replace for straight replacement throughout file. Quickest of the lot.
  166.      *               preg   - Uses preg_replace(), so any regex valid with this function is valid here.
  167.      *               ereg   - Uses ereg_replace(), so any regex valid with this function is valid here.
  168.      *
  169.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  170.      */
  171.     function setSearchFunction($search_function){
  172.         switch($search_function){
  173.         case 'normal': $this->search_function = 'search';
  174.             return TRUE;
  175.             break;
  176.  
  177.         case 'quick' : $this->search_function = 'quickSearch';
  178.             return TRUE;
  179.             break;
  180.  
  181.         case 'preg'  : $this->search_function = 'pregSearch';
  182.             return TRUE;
  183.             break;
  184.  
  185.         case 'ereg'  : $this->search_function = 'eregSearch';
  186.             return TRUE;
  187.             break;
  188.  
  189.         default      : $this->last_error      = 'Invalid search function specified';
  190.             return FALSE;
  191.             break;
  192.         }
  193.     }
  194.     
  195.     /**
  196.      * Default ("normal") search routine.
  197.      *
  198.      * @access private
  199.      * @param string $filename The filename to search and replace upon.
  200.      * @return array Will return an array containing the new file contents and the number of occurences.
  201.      *               Will return FALSE if there are no occurences.
  202.      *
  203.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  204.      */
  205.     function search($filename){
  206.  
  207.         $occurences = 0;
  208.         $file_array = file($filename);
  209.  
  210.         for($i=0; $i<count($file_array); $i++){
  211.  
  212.             if(count($this->ignore_lines) > 0){
  213.                 for($j=0; $j<count($this->ignore_lines); $j++){
  214.                     if(substr($file_array[$i],0,strlen($this->ignore_lines[$j])) == $this->ignore_lines[$j]) continue 2;
  215.                 }
  216.             }
  217.  
  218.             $occurences += count(explode($this->find, $file_array[$i])) - 1;
  219.             $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i]);
  220.         }
  221.         if($occurences > 0) $return = array($occurences, implode('', $file_array)); else $return = FALSE;
  222.         return $return;
  223.  
  224.     }
  225.     
  226.     /**
  227.      * Quick search routine.
  228.      *
  229.      * @access private
  230.      * @param string $filename The filename to search and replace upon.
  231.      * @return array Will return an array containing the new file contents and the number of occurences.
  232.      *               Will return FALSE if there are no occurences.
  233.      *
  234.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  235.      */
  236.     function quickSearch($filename){
  237.  
  238.         clearstatcache();
  239.  
  240.         $file       = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  241.         $occurences = count(explode($this->find, $file)) - 1;
  242.         $file       = str_replace($this->find, $this->replace, $file);
  243.  
  244.         if($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  245.         return $return;
  246.  
  247.     }
  248.     
  249.     /**
  250.      * Preg search routine.
  251.      *
  252.      * @access private
  253.      * @param string $filename The filename to search and replace upon.
  254.      * @return array Will return an array containing the new file contents and the number of occurences.
  255.      *               Will return FALSE if there are no occurences.
  256.      *
  257.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  258.      */
  259.     function pregSearch($filename){
  260.  
  261.         clearstatcache();
  262.  
  263.         $file       = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  264.         $occurences = count($matches = preg_split($this->find, $file)) - 1;
  265.         $file       = preg_replace($this->find, $this->replace, $file);
  266.  
  267.         if($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  268.         return $return;
  269.  
  270.     }
  271.     
  272.     /**
  273.      * Ereg search routine.
  274.      *
  275.      * @access private
  276.      * @param string $filename The filename to search and replace upon.
  277.      * @return array Will return an array containing the new file contents and the number of occurences.
  278.      *               Will return FALSE if there are no occurences.
  279.      *
  280.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  281.      */
  282.     function eregSearch($filename){
  283.  
  284.         clearstatcache();
  285.  
  286.         $file = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  287.  
  288.         $occurences = count($matches = split($this->find, $file)) -1;
  289.         $file       = ereg_replace($this->find, $this->replace, $file);
  290.  
  291.         if($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  292.         return $return;
  293.  
  294.     }
  295.     
  296.     /**
  297.      * Function to writeout the file contents.
  298.      *
  299.      * @access private
  300.      * @param string $filename The filename of the file to write.
  301.      * @param string $contents The contents to write to the file.
  302.      *
  303.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  304.      */
  305.     function writeout($filename, $contents){
  306.  
  307.         if($fp = @fopen($filename, 'w')){
  308.             flock($fp,2);
  309.             fwrite($fp, $contents);
  310.             flock($fp,3);
  311.             fclose($fp);
  312.         }else{
  313.             $this->last_error = 'Could not open file: '.$filename;
  314.         }
  315.  
  316.     }
  317.     
  318.     /**
  319.      * Function called by doSearch() to go through any files that need searching.
  320.      *
  321.      * @access private
  322.      * @param string $ser_func The search function to use.
  323.      *
  324.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  325.      */
  326.     function doFiles($ser_func){
  327.         if(!is_array($this->files)) $this->files = explode(',', $this->files);
  328.         for($i=0; $i<count($this->files); $i++){
  329.             if($this->files[$i] == '.' OR $this->files[$i] == '..') continue;
  330.             if(is_dir($this->files[$i]) == TRUE) continue;
  331.             $newfile = $this->$ser_func($this->files[$i]);
  332.             if(is_array($newfile) == TRUE){
  333.                 $this->writeout($this->files[$i], $newfile[1]);
  334.                 $this->occurences += $newfile[0];
  335.             }
  336.         }
  337.     }
  338.     
  339.     /**
  340.      * Function called by doSearch() to go through any directories that need searching.
  341.      *
  342.      * @access private
  343.      * @param string $ser_func The search function to use.
  344.      *
  345.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  346.      */
  347.     function doDirectories($ser_func){
  348.         if(!is_array($this->directories)) $this->directories = explode(',', $this->directories);
  349.         for($i=0; $i<count($this->directories); $i++){
  350.             $dh = opendir($this->directories[$i]);
  351.             while($file = readdir($dh)){
  352.                 if($file == '.' OR $file == '..') continue;
  353.  
  354.                 if(is_dir($this->directories[$i].$file) == TRUE){
  355.                     if($this->include_subdir == 1){
  356.                         $this->directories[] = $this->directories[$i].$file.'/';
  357.                         continue;
  358.                     }else{
  359.                         continue;
  360.                     }
  361.                 }
  362.  
  363.                 $newfile = $this->$ser_func($this->directories[$i].$file);
  364.                 if(is_array($newfile) == TRUE){
  365.                     $this->writeout($this->directories[$i].$file, $newfile[1]);
  366.                     $this->occurences += $newfile[0];
  367.                 }
  368.             }
  369.         }
  370.     }
  371.     
  372.     /**
  373.      * This starts the search/replace off. Call this to do the search.
  374.      * First do whatever files are specified, and/or if directories are specified,
  375.      * do those too.
  376.      *
  377.      * @access public
  378.      *
  379.      * @author Richard Heyes <richard.heyes@heyes-computing.net>
  380.      */
  381.     function doSearch(){
  382.         if($this->find != ''){
  383.             if((is_array($this->files) AND count($this->files) > 0) OR $this->files != '') $this->doFiles($this->search_function);
  384.             if($this->directories != '')                                                   $this->doDirectories($this->search_function);
  385.         }
  386.     }
  387.  
  388. }
  389. ?>
  390.