1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4/** 5 * A writer wrapper that will remove the files the eventual duplicate 6 * files from the reader to keep only the new ones 7 * When calling newFile, the file with the highest index in the reader 8 * and the same filename will be removed 9 * Note that it ensure that the archive won't have duplicates only if 10 * it didn't have duplicates before, and if no two calls to newFile with 11 * the same filename is done 12 * 13 * This library is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU Lesser General Public 15 * License as published by the Free Software Foundation; either 16 * version 2.1 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330,Boston,MA 02111-1307 USA 26 * 27 * @category File Formats 28 * @package File_Archive 29 * @author Vincent Lascaux <vincentlascaux@php.net> 30 * @copyright 1997-2005 The PHP Group 31 * @license http://www.gnu.org/copyleft/lesser.html LGPL 32 * @version CVS: $Id: UniqueAppender.php,v 1.1 2005/05/30 19:44:53 vincentlascaux Exp $ 33 * @link http://pear.php.net/package/File_Archive 34 */ 35 36require_once "File/Archive/Writer.php"; 37require_once "File/Archive/Reader.php"; 38require_once "File/Archive/Predicate/Index.php"; 39 40/** 41 * A writer wrapper that will remove the files the eventual duplicate 42 * files from the reader to keep only the new ones 43 * If there were already some duplications in the provided reader, not 44 * all duplication will be removed 45 * If you use newFile with the same filename several file, only the latest 46 * write will be kept (no time comparision is done) 47 */ 48class File_Archive_Writer_UniqueAppender extends File_Archive_Writer 49{ 50 var $reader; 51 var $writer; 52 var $fileList = array(); 53 var $toDelete = array(); 54 55 /** 56 * Construct a unique writer that will write to the specified writer 57 * and remove duplicate files from the reader on close 58 */ 59 function File_Archive_Writer_UniqueAppender(&$reader) 60 { 61 $reader->close(); 62 $pos = 0; 63 while ($reader->next()) { 64 $this->fileList[$reader->getFilename()] = $pos++; 65 } 66 67 $this->reader =& $reader; 68 $this->writer = $reader->makeAppendWriter(); 69 } 70 71 /** 72 * @see File_Archive_Writer::newFile() 73 */ 74 function newFile($filename, $stat = array(), $mime = "application/octet-stream") 75 { 76 if (isset($this->fileList[$filename])) { 77 $this->toDelete[$this->fileList[$filename]] = true; 78 } 79 80 return $this->writer->newFile($filename, $stat, $mime); 81 } 82 83 /** 84 * @see File_Archive_Writer::newFromTempFile() 85 */ 86 function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") 87 { 88 if (isset($this->fileList[$filename])) { 89 $this->toDelete[$this->fileList[$filename]] = true; 90 } 91 92 return $this->writer->newFromTempFile($tmpfile, $filename, $stat, $mime); 93 } 94 95 /** 96 * @see File_Archive_Writer::newFileNeedsMIME() 97 */ 98 function newFileNeedsMIME() 99 { 100 return $this->writer->newFileNeedsMIME(); 101 } 102 103 /** 104 * @see File_Archive_Writer::writeData() 105 */ 106 function writeData($data) 107 { 108 return $this->writer->writeData($data); 109 } 110 111 /** 112 * @see File_Archive_Writer::writeFile() 113 */ 114 function writeFile($filename) 115 { 116 return $this->writer->writeFile($filename); 117 } 118 119 /** 120 * Close the writer, eventually flush the data, write the footer... 121 * This function must be called before the end of the script 122 */ 123 function close() 124 { 125 $error = $this->writer->close(); 126 if (PEAR::isError($error)) { 127 return $error; 128 } 129 130 if (!empty($this->toDelete)) { 131 $tmp = $this->reader->makeWriterRemoveFiles( 132 new File_Archive_Predicate_Index($this->toDelete) 133 ); 134 if (PEAR::isError($tmp)) { 135 return $tmp; 136 } 137 138 return $tmp->close(); 139 } 140 } 141} 142 143?>