00001 <?php
00002
00014 class SnapExternalFile extends SObject {
00015 protected $path = "";
00016 protected $url = "";
00017 protected $name = "";
00018 protected $versionId = "";
00019 protected $exists = false;
00020 protected $acceptableFileTypes = array();
00021
00028 public function __construct($version, $array = "") {
00029 parent::__construct();
00030
00031 $this->version = $version;
00032 if($array != "")
00033 $this->load($array);
00034 }
00035
00040 public function getPath() {
00041 $path = Snap2::getMediaPathBase() . '/' . $this->path;
00042 return $path;
00043 }
00044
00049 public function getURL() {
00050 return Snap2::getMediaURLBase() . '/' . $this->url;
00051 }
00052
00060 public function unzip($callIt) {
00061 $zipFile = Snap2::getMediaPathBase() . '/' . $this->path;
00062 $extractDir = substr($this->path,0,-4) . '/';
00063 $extractDirFull = Snap2::getMediaPathBase() . '/' . $extractDir;
00064 $extractURL = substr($this->url, 0,-4) . '/';
00065 $extractURLFull = Snap2::getMediaPathBase() . '/' . $extractURL;
00066 if(!mkdir($extractDirFull, 0777, true)) return false;
00067 if(!copy($zipFile, $extractDirFull.'zipFile.zip')) return false;
00068 if(!chdir($extractDirFull)) return false;
00069 if(!shell_exec("unzip 'zipFile.zip'")) return false;
00070
00071
00072 $dirs = scandir(substr($zipFile, 0, -4));
00073 $dontMoveUp = false;
00074 foreach($dirs as $dir) {
00075 if($dir == '.' || $dir == '..')
00076 continue;
00077 if($dir == 'applet' || $dir == 'documentation') {
00078 $dontMoveUp = true;
00079 break;
00080 }
00081 }
00082 if(!$dontMoveUp) {
00083 $dir = '';
00084 foreach($dirs as $d) {
00085 if($d == '.' || $d == '..' || $d == '__MACOSX' || substr($d, -4) == '.zip')
00086 continue;
00087 $dir = $d;
00088 break;
00089 }
00090 shell_exec($cmd = "mv $extractDirFull$dir/* $extractDirFull");
00091 shell_exec($cmd = "rm -rf $extractDirFull$dir");
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 if(!unlink($extractDirFull.'zipFile.zip')) return false;
00102
00103 $newDir = new SnapExternalFile($this->version);
00104 $newDir->load(array('path' => $extractDir, 'url' => $extractURL, 'name' => basename($extractDir)));
00105 return $newDir;
00106 }
00107
00115 public function getName() {
00116 return $this->name;
00117 }
00118
00126 public function getArray() {
00127 return array('path' => $this->path, 'url' => $this->url, 'name' => $this->name);
00128 }
00129
00135 public function load($array) {
00136 if(!is_array($array)) {
00137 $this->setError("load() expects array from database content");
00138 return false;
00139 }
00140
00141
00142 $this->path = $array['path'];
00143 $this->url = $array['url'];
00144 $this->name = $array['name'];
00145 $this->exists = true;
00146
00147 return true;
00148 }
00149
00157 public function setAcceptable($fileTypes) {
00158 if (is_array($fileTypes))
00159 $this->acceptableFileTypes = $fileTypes;
00160 else {
00161 $this->setError("Acceptable File Types not an array!");
00162 return false;
00163 }
00164 }
00165
00174 public function weedFiles($directory = 'default') {
00175 if ($directory == 'default')
00176 $directory = $this->path;
00177 foreach(glob(rtrim($directory, '/').'/*') as $file) {
00178 if (is_dir($file) && !is_link($file)) {
00179 $this->weedFiles($file);
00180 }
00181 else {
00182 $e = substr(strrchr($file, '.'), 1);
00183 $flag = false;
00184 foreach($this->acceptableFileTypes as $accepted) {
00185 if (($e == $accepted))
00186 $flag = true;
00187 }
00188 if (!$flag)
00189 unlink($file);
00190 }
00191 }
00192
00193 return true;
00194 }
00195
00216 public function create($tmpFile, $originalName, $name = "") {
00217 if($this->exists) {
00218 $this->setError("Cannot create a file when this file already exists (use update instead!)");
00219 return false;
00220 }
00221 list($this->url, $this->path) = $this->generateFilePaths($tmpFile, $originalName);
00222 $realPath = Snap2::getMediaPathBase() . '/' . $this->path;
00223 if(substr($realPath, -1) == '/')
00224 $dirname = dirname(substr($realPath, 0, -1));
00225 else
00226 $dirname = dirname($realPath);
00227 if(!is_dir($dirname) && !@mkdir($dirname, 0755, true)) {
00228 $this->setError("Could not create directory '" . dirname($realPath) . "'");
00229 return false;
00230 }
00231 if(substr($realPath, -1) != '/') {
00232 if(!@copy($tmpFile, $realPath)) {
00233 $this->setError("Could not copy '$tmpFile' to '$realPath'");
00234 @rmdir($dirname);
00235 return false;
00236 }
00237 }
00238 else {
00239 $dest = $realPath;
00240 $src = $tmpFile;
00241 system("/bin/cp -Rp $src $dest", $retval);
00242 if($retval != 0) {
00243 $this->setError("Could not copy '$tmpFile' to '$realPath' recursively");
00244 @rmdir($dirname);
00245 return false;
00246 }
00247 }
00248 $this->exists = true;
00249 if($name == "")
00250 $this->name = $originalName;
00251 else
00252 $this->name = $name;
00253 $query = 'INSERT INTO ExternalFiles SET path = \'' . mysql_escape_string($this->path) . '\', versionId = '
00254 . $this->version->getId();
00255 SnapDBI::query($query);
00256 return true;
00257 }
00258
00269 public function update($tmpFile, $originalName, $name = "") {
00270 if(!$this->exists) {
00271 $this->setError("Cannot update a non-existent file");
00272 return false;
00273 }
00274 // only intending to update the name...
00275 if($tmpFile != "")
00276 copy($tmpFile, Snap2::getMediaPathBase() . '/' .$this->path);
00277 if($name == "")
00278 $this->name = $originalName;
00279 else
00280 $this->name = $name;
00281 return true;
00282 }
00283
00292 public function copy($newName = "") {
00293 if(!$this->exists) {
00294 $this->setError("Cannot copy a non-existent file");
00295 return null;
00296 }
00297 if($newName == "")
00298 $newName = $this->name;
00299 $nfile = new SnapExternalFile($this->version);
00300 if(!$nfile->create(Snap2::getMediaPathBase() . '/' . $this->path, $this->path, $newName)) {
00301 $this->setError('Could not create new copy: <ul><li>' . implode('</li><li>', $nfile->getError()) . '</li></ul>');
00302 return null;
00303 }
00304 return $nfile;
00305 }
00306
00313 public function delete() {
00314 if(!$this->exists) {
00315 $this->setError("Cannot delete a non-existent file");
00316 return false;
00317 }
00318 if(substr($this->path, -1) == "/")
00319 system("/bin/rm -rf " . Snap2::getMediaPathBase() . '/' . $this->path);
00320 else
00321 @unlink(Snap2::getMediaPathBase() . '/' . $this->path);
00322 $query = 'DELETE FROM ExternalFiles WHERE path = \'' . mysql_escape_string($this->path)
00323 . '\' AND versionId = ' . $this->version->getId();
00324 SnapDBI::query($query);
00325 $this->path = "";
00326 $this->url = "";
00327 $this->name = "";
00328 $this->exists = false;
00329 return true;
00330 }
00331
00335 public function updateDB() {
00336 $query = 'INSERT INTO ExternalFiles (path, versionId) VALUES (\'' . $this->path . '\', ' . $this->version->getId()
00337 . ') ON DUPLICATE KEY UPDATE path=\'' . $this->path . '\',versionId = ' . $this->version->getId();
00338 if(!SnapDBI::query($query))
00339 return false;
00340 else
00341 return true;
00342 }
00343
00357 private function generateRelPath($fileName, $origFileName) {
00358 if(is_dir($fileName))
00359 $contents = implode(':', scandir($fileName));
00360 else if(is_file($fileName))
00361 $contents = @file_get_contents($fileName);
00362 else {
00363 $this->setError("No such file: '$fileName'");
00364 return null;
00365 }
00366 $hash = MD5($contents . microtime() . $fileName . $origFileName);
00367 $hash = base64_encode($hash);
00368 $hash = strtr($hash, "/+", "-_");
00369 $hash = rtrim($hash, "=");
00370 $tmp = strrchr($origFileName, ".");
00371 $suffix = substr($tmp, 1);
00372 $path = $hash[0] . "/" . $hash[1] . "/" . $hash[2]
00373 . "/" . substr($hash, 3);
00374 if(is_dir($fileName))
00375 $path .= '/';
00376 else
00377 $path .= "." . $suffix;
00378 return $path;
00379 }
00380
00391 private function generateFilePaths($fileName, $origFileName) {
00392 $path = $this->generateRelPath($fileName, $origFileName);
00393
00394
00395 $arr = array($path, $path);
00396 return $arr;
00397 }
00398 }
00399
00400 ?>