readdir's ordering is filesystem-dependent. On many systems, that means it might as well be random. People uploading archives will reasonably expect the files to appear in alphabetical order, so we should make sure they do.
		
			
				
	
	
		
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /*
 | |
|  * Name: Handle Archives
 | |
|  * Author: Shish <webmaster@shishnet.org>
 | |
|  * Description: Allow users to upload archives (zip, etc)
 | |
|  * Documentation:
 | |
|  *  Note: requires exec() access and an external unzip command
 | |
|  *  <p>Any command line unzipper should work, some examples:
 | |
|  *  <p>unzip: <code>unzip -d "%d" "%f"</code>
 | |
|  *  <br>7-zip: <code>7zr x -o"%d" "%f"</code>
 | |
|  */
 | |
| 
 | |
| class ArchiveFileHandler extends Extension {
 | |
| 	public function onInitExt(InitExtEvent $event) {
 | |
| 		global $config;
 | |
| 		$config->set_default_string('archive_extract_command', 'unzip -d "%d" "%f"');
 | |
| 	}
 | |
| 
 | |
| 	public function onSetupBuilding(SetupBuildingEvent $event) {
 | |
| 		$sb = new SetupBlock("Archive Handler Options");
 | |
| 		$sb->add_text_option("archive_tmp_dir", "Temporary folder: ");
 | |
| 		$sb->add_text_option("archive_extract_command", "<br>Extraction command: ");
 | |
| 		$sb->add_label("<br>%f for archive, %d for temporary directory");
 | |
| 		$event->panel->add_block($sb);
 | |
| 	}
 | |
| 
 | |
| 	public function onDataUpload(DataUploadEvent $event) {
 | |
| 		if($this->supported_ext($event->type)) {
 | |
| 			global $config;
 | |
| 			$tmp = sys_get_temp_dir();
 | |
| 			$tmpdir = "$tmp/shimmie-archive-{$event->hash}";
 | |
| 			$cmd = $config->get_string('archive_extract_command');
 | |
| 			$cmd = str_replace('%f', $event->tmpname, $cmd);
 | |
| 			$cmd = str_replace('%d', $tmpdir, $cmd);
 | |
| 			exec($cmd);
 | |
| 			$this->add_dir($tmpdir);
 | |
| 			deltree($tmpdir);
 | |
| 			$event->image_id = -2; // default -1 = upload wasn't handled
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	private function supported_ext($ext) {
 | |
| 		$exts = array("zip");
 | |
| 		return in_array(strtolower($ext), $exts);
 | |
| 	}
 | |
| 
 | |
| 	// copied from bulk add extension
 | |
| 	private function add_image($tmpname, $filename, $tags) {
 | |
| 		assert(file_exists($tmpname));
 | |
| 
 | |
| 		try {
 | |
| 			global $user;
 | |
| 			$pathinfo = pathinfo($filename);
 | |
| 			if(!array_key_exists('extension', $pathinfo)) {
 | |
| 				throw new UploadException("File has no extension");
 | |
| 			}
 | |
| 			$metadata['filename'] = $pathinfo['basename'];
 | |
| 			$metadata['extension'] = $pathinfo['extension'];
 | |
| 			$metadata['tags'] = $tags;
 | |
| 			$metadata['source'] = null;
 | |
| 			$event = new DataUploadEvent($tmpname, $metadata);
 | |
| 			send_event($event);
 | |
| 		}
 | |
| 		catch(UploadException $ex) {
 | |
| 			return $ex->getMessage();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// copied from bulk add extension
 | |
| 	private function add_dir($base, $subdir="") {
 | |
| 		global $page;
 | |
| 
 | |
| 		$list = "";
 | |
| 
 | |
| 		$dir = opendir("$base/$subdir");
 | |
| 
 | |
| 		$files = array();
 | |
| 		while($f = readdir($dir)) {
 | |
| 			$files[] = $f;
 | |
| 		}
 | |
| 		sort($files);
 | |
| 
 | |
| 		foreach($files as $filename) {
 | |
| 			$fullpath = "$base/$subdir/$filename";
 | |
| 
 | |
| 			if(is_link($fullpath)) {
 | |
| 				// ignore
 | |
| 			}
 | |
| 			else if(is_dir($fullpath)) {
 | |
| 				if($filename[0] != ".") {
 | |
| 					$this->add_dir($base, "$subdir/$filename");
 | |
| 				}
 | |
| 			}
 | |
| 			else {
 | |
| 				$tmpfile = $fullpath;
 | |
| 				$tags = $subdir;
 | |
| 				$tags = str_replace("/", " ", $tags);
 | |
| 				$tags = str_replace("__", " ", $tags);
 | |
| 				$list .= "<br>".html_escape("$subdir/$filename (".str_replace(" ", ",", $tags).")...");
 | |
| 				$error = $this->add_image($tmpfile, $filename, $tags);
 | |
| 				if(is_null($error)) {
 | |
| 					$list .= "ok\n";
 | |
| 				}
 | |
| 				else {
 | |
| 					$list .= "failed: $error\n";
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		closedir($dir);
 | |
| 
 | |
| 		// $this->theme->add_status("Adding $subdir", $list);
 | |
| 	}
 | |
| }
 | |
| ?>
 |