supported directory download
This commit is contained in:
		@ -223,7 +223,7 @@ class Code extends Controller
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		$this->load->model ('ProjectModel', 'projects');
 | 
							$this->load->model ('ProjectModel', 'projects');
 | 
				
			||||||
		$this->load->model ('SubversionModel', 'subversion');
 | 
							$this->load->model ('SubversionModel', 'subversion');
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
		$login = $this->login->getUser ();
 | 
							$login = $this->login->getUser ();
 | 
				
			||||||
		if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '')
 | 
							if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '')
 | 
				
			||||||
			redirect ("main/signin/" . $this->converter->AsciiTohex(current_url()));
 | 
								redirect ("main/signin/" . $this->converter->AsciiTohex(current_url()));
 | 
				
			||||||
@ -665,7 +665,7 @@ class Code extends Controller
 | 
				
			|||||||
			if ($file === FALSE)
 | 
								if ($file === FALSE)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				$data['project'] = $project;
 | 
									$data['project'] = $project;
 | 
				
			||||||
				$data['message'] = 'Failed to get file';
 | 
									$data['message'] = "Failed to get a file - $path";
 | 
				
			||||||
				$this->load->view ($this->VIEW_ERROR, $data);
 | 
									$this->load->view ($this->VIEW_ERROR, $data);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if ($file['type'] == 'file')
 | 
								else if ($file['type'] == 'file')
 | 
				
			||||||
@ -682,33 +682,49 @@ class Code extends Controller
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				$data['project'] = $project;
 | 
									$forced_name = $projectid . $file['fullpath'];
 | 
				
			||||||
				$data['headpath'] = $path;
 | 
									$forced_name = str_replace ('/', '-', $forced_name);
 | 
				
			||||||
				$data['file'] = $file;
 | 
									//$tag = $this->subversion->getRevProp (
 | 
				
			||||||
 | 
										//	$projectid, $file['created_rev'], CODEPOT_SVN_TAG_PROPERTY);
 | 
				
			||||||
 | 
									//if ($tag === FALSE) $tag = '';
 | 
				
			||||||
 | 
									//if (!empty($tag)) 
 | 
				
			||||||
 | 
									//{
 | 
				
			||||||
 | 
									//	$forced_name = $forced_name . '-' . $tag;
 | 
				
			||||||
 | 
									//}
 | 
				
			||||||
 | 
									//else
 | 
				
			||||||
 | 
									//{
 | 
				
			||||||
 | 
										$forced_name = $forced_name . '-r' . $file['created_rev'];
 | 
				
			||||||
 | 
									//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				$data['revision'] = $rev;
 | 
									$filename = $this->subversion->zipSubdir ($projectid, $path, $rev, $forced_name);
 | 
				
			||||||
				$data['prev_revision'] =
 | 
									if ($filename === FALSE)
 | 
				
			||||||
					$this->subversion->getPrevRev ($projectid, $path, $rev);
 | 
					 | 
				
			||||||
				$data['next_revision'] =
 | 
					 | 
				
			||||||
					$this->subversion->getNextRev ($projectid, $path, $rev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				$data['readme_text'] = '';
 | 
					 | 
				
			||||||
				$data['readme_file'] = '';
 | 
					 | 
				
			||||||
				foreach (explode(',', CODEPOT_CODE_FOLDER_README) as $rf)
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					$rf = trim($rf);
 | 
										$data['project'] = $project;
 | 
				
			||||||
					if (strlen($rf) > 0)
 | 
										$data['message'] = "Failed to zip a directory for $path";
 | 
				
			||||||
					{
 | 
										$this->load->view ($this->VIEW_ERROR, $data);
 | 
				
			||||||
						$readme = $this->subversion->getFile ($projectid, $path . '/' . $rf, $rev);
 | 
									}
 | 
				
			||||||
						if ($readme !== FALSE)
 | 
									else
 | 
				
			||||||
						{
 | 
									{
 | 
				
			||||||
							$data['readme_text'] = $readme['content'];
 | 
										$dir_name = $filename . '.d';
 | 
				
			||||||
							$data['readme_file'] = $rf;
 | 
										$zip_name = $filename . '.zip';
 | 
				
			||||||
							break;
 | 
					
 | 
				
			||||||
						}
 | 
										$forced_zip_name = $forced_name . '.zip';
 | 
				
			||||||
					}
 | 
					
 | 
				
			||||||
 | 
										header ('Content-Description: File Transfer');
 | 
				
			||||||
 | 
										header ('Content-Type: application/zip');
 | 
				
			||||||
 | 
										header ('Content-Disposition: attachment; filename='. $forced_zip_name);
 | 
				
			||||||
 | 
										header ('Content-Transfer-Encoding: binary');
 | 
				
			||||||
 | 
										header ('Content-Length: ' . filesize($zip_name));
 | 
				
			||||||
 | 
										flush ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										@readfile ($zip_name);
 | 
				
			||||||
 | 
										// meaningless to show the error page after headers
 | 
				
			||||||
 | 
										// have been sent event if readfile fails.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										codepot_delete_files ($dir_name, TRUE);
 | 
				
			||||||
 | 
										@unlink ($zip_name);
 | 
				
			||||||
 | 
										@unlink ($filename);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				$this->load->view ($this->VIEW_FOLDER, $data);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -737,7 +753,7 @@ class Code extends Controller
 | 
				
			|||||||
			if ($file === FALSE)
 | 
								if ($file === FALSE)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				$data['project'] = $project;
 | 
									$data['project'] = $project;
 | 
				
			||||||
				$data['message'] = "Failed to get file - %path";
 | 
									$data['message'] = "Failed to get file - $path";
 | 
				
			||||||
				$this->load->view ($this->VIEW_ERROR, $data);
 | 
									$this->load->view ($this->VIEW_ERROR, $data);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -982,8 +998,7 @@ class Code extends Controller
 | 
				
			|||||||
							$stats[$date] = 1;
 | 
												$stats[$date] = 1;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
				ksort ($stats);
 | 
									ksort ($stats);
 | 
				
			||||||
				$stats_count = count($stats);
 | 
									$stats_count = count($stats);
 | 
				
			||||||
				$idx = 1;
 | 
									$idx = 1;
 | 
				
			||||||
@ -994,24 +1009,23 @@ class Code extends Controller
 | 
				
			|||||||
						$min_year = substr($k, 0, 4);
 | 
											$min_year = substr($k, 0, 4);
 | 
				
			||||||
						$min_month = substr($k, 5, 2);
 | 
											$min_month = substr($k, 5, 2);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
					if ($idx == $stats_count) 
 | 
										if ($idx == $stats_count) 
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						$max_year = substr($k, 0, 4);
 | 
											$max_year = substr($k, 0, 4);
 | 
				
			||||||
						$max_month = substr($k, 5, 2);
 | 
											$max_month = substr($k, 5, 2);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					$idx++;	
 | 
										$idx++;	
 | 
				
			||||||
					$total_commits += $v;
 | 
										$total_commits += $v;
 | 
				
			||||||
				}	
 | 
									}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
				$total_months  = 0; 
 | 
									$total_months  = 0; 
 | 
				
			||||||
				for ($year = $min_year; $year <= $max_year; $year++)
 | 
									for ($year = $min_year; $year <= $max_year; $year++)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					$month = ($year == $min_year)? $min_month: 1;
 | 
										$month = ($year == $min_year)? $min_month: 1;
 | 
				
			||||||
					$month_end = ($year == $max_year)? $max_month: 12;
 | 
										$month_end = ($year == $max_year)? $max_month: 12;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
					while ($month <= $month_end)
 | 
										while ($month <= $month_end)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						$date = sprintf ("%04d-%02d", $year, $month);
 | 
											$date = sprintf ("%04d-%02d", $year, $month);
 | 
				
			||||||
 | 
				
			|||||||
@ -143,6 +143,82 @@ if ( !function_exists ('codepot_delete_files'))
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ( !function_exists ('codepot_zip_dir'))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// $output_file: zip file to create
 | 
				
			||||||
 | 
						// $path: directory to zip recursively
 | 
				
			||||||
 | 
						// $local_path: the leading $path part is translated to $local_path
 | 
				
			||||||
 | 
						// $exclude: file names to exclude. string or array of strings
 | 
				
			||||||
 | 
						function codepot_zip_dir ($output_file, $path, $local_path = NULL, $exclude = NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							$stack = array ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!is_dir($path)) return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							array_push ($stack, $path); 
 | 
				
			||||||
 | 
							$prefix = strlen($path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$zip = new ZipArchive();
 | 
				
			||||||
 | 
							if (@$zip->open ($output_file, ZipArchive::OVERWRITE) === FALSE) return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while (!empty($stack))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								$dir = array_pop($stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$d = @opendir ($dir);
 | 
				
			||||||
 | 
								if ($d === FALSE) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								$new_path = empty($local_path)? $dir: substr_replace($dir, $local_path, 0, $prefix);
 | 
				
			||||||
 | 
								if (@$zip->addEmptyDir($new_path) == FALSE)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									@closedir ($dir);
 | 
				
			||||||
 | 
									$zip->close ();
 | 
				
			||||||
 | 
									return FALSE;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//printf (">> [%s] [%s]\n", $dir, $new_path);
 | 
				
			||||||
 | 
								while (($f = @readdir($d)) !== FALSE)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ($f == '.' || $f == '..') continue;
 | 
				
			||||||
 | 
									if (!empty($exclude))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										$found = FALSE;
 | 
				
			||||||
 | 
										if (is_array($exclude))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											foreach ($exclude as $ex)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												if (fnmatch ($ex, $f, FNM_PERIOD | FNM_PATHNAME)) 
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													$found = TRUE;
 | 
				
			||||||
 | 
													break;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if ($found) continue;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else if (fnmatch($exclude, $f, FNM_PERIOD | FNM_PATHNAME)) continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									$full_path = $dir . DIRECTORY_SEPARATOR . $f;
 | 
				
			||||||
 | 
									if (is_dir($full_path))
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										array_push ($stack, $full_path);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										$new_path = empty($local_path)? $dir: substr_replace($full_path, $local_path, 0, $prefix);
 | 
				
			||||||
 | 
										@$zip->addFile ($full_path, $new_path);
 | 
				
			||||||
 | 
										//printf ("[%s] [%s]\n", $full_path, $new_path);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@closedir ($dir);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$zip->close ();
 | 
				
			||||||
 | 
							return TRUE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( !function_exists ('codepot_find_longest_matching_sequence'))
 | 
					if ( !function_exists ('codepot_find_longest_matching_sequence'))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	function codepot_find_longest_matching_sequence ($old, $old_start, $old_len, $new, $new_start, $new_len)
 | 
						function codepot_find_longest_matching_sequence ($old, $old_start, $old_len, $new, $new_start, $new_len)
 | 
				
			||||||
 | 
				
			|||||||
@ -921,25 +921,25 @@ class SubversionModel extends Model
 | 
				
			|||||||
		$cloc = @popen ($cloc_cmd, 'r');
 | 
							$cloc = @popen ($cloc_cmd, 'r');
 | 
				
			||||||
		if ($cloc === FALSE)
 | 
							if ($cloc === FALSE)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
				codepot_delete_files ($actual_tfname, TRUE);
 | 
								codepot_delete_files ($actual_tfname, TRUE);
 | 
				
			||||||
				@unlink ($tfname);
 | 
								@unlink ($tfname);
 | 
				
			||||||
				return FALSE;
 | 
								return FALSE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		$line_count = 0;
 | 
							$line_count = 0;
 | 
				
			||||||
		$cloc_data = array ();
 | 
							$cloc_data = array ();
 | 
				
			||||||
		while (!feof($cloc))
 | 
							while (!feof($cloc))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
				$line = @fgets ($cloc);
 | 
								$line = @fgets ($cloc);
 | 
				
			||||||
				if ($line === FALSE) break;
 | 
								if ($line === FALSE) break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				$line_count++;
 | 
								$line_count++;
 | 
				
			||||||
				$line = trim($line);
 | 
								$line = trim($line);
 | 
				
			||||||
				if ($line_count >= 3)
 | 
								if ($line_count >= 3)
 | 
				
			||||||
				{
 | 
								{
 | 
				
			||||||
					$counter = explode (':', $line);
 | 
									$counter = explode (':', $line);
 | 
				
			||||||
					$cloc_data[$counter[1]] = array ($counter[0], $counter[2], $counter[3], $counter[4]);
 | 
									$cloc_data[$counter[1]] = array ($counter[0], $counter[2], $counter[3], $counter[4]);
 | 
				
			||||||
				}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@pclose ($cloc);
 | 
							@pclose ($cloc);
 | 
				
			||||||
@ -999,6 +999,61 @@ class SubversionModel extends Model
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return $cloc_data;
 | 
							return $cloc_data;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function zipSubdir ($projectid, $path, $rev, $topdir)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							$orgurl = 'file://'.$this->_canonical_path(CODEPOT_SVNREPO_DIR."/{$projectid}/{$path}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$workurl = ($path == '')? $orgurl: "{$orgurl}@"; // trailing @ for collision prevention
 | 
				
			||||||
 | 
							$info = @svn_info ($workurl, FALSE, $rev);
 | 
				
			||||||
 | 
							if ($info === FALSE || count($info) != 1) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// If a URL is at the root of repository and the url type is file://
 | 
				
			||||||
 | 
								// (e.g. file:///svnrepo/codepot/ where /svnrepo/codepot is a project root),
 | 
				
			||||||
 | 
								// some versions of libsvn end up with an assertion failure like
 | 
				
			||||||
 | 
								//  ... libvvn_subr/path.c:114: svn_path_join: Assertion `svn_path_is_canonical(base, pool)' failed. 
 | 
				
			||||||
 | 
								// 
 | 
				
			||||||
 | 
								// Since the root directory is guaranteed to exist at the head revision,
 | 
				
			||||||
 | 
								// the information can be acquired without using a peg revision.
 | 
				
			||||||
 | 
								// In this case, a normal operational revision is used to work around
 | 
				
			||||||
 | 
								// the assertion failure. Other functions that has to deal with 
 | 
				
			||||||
 | 
								// the root directory should implement this check to work around it.
 | 
				
			||||||
 | 
								//
 | 
				
			||||||
 | 
								if ($rev == SVN_REVISION_HEAD || $path == '') return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// rebuild the URL with a peg revision and retry it.
 | 
				
			||||||
 | 
								$workurl = "{$orgurl}@{$rev}";
 | 
				
			||||||
 | 
								$info = @svn_info ($workurl, FALSE, $rev);
 | 
				
			||||||
 | 
								if ($info === FALSE || count($info) != 1)  return FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// pass __FILE__ as the first argument so that tempnam creates a name
 | 
				
			||||||
 | 
							// in the system directory. __FILE__ can never be a valid directory.
 | 
				
			||||||
 | 
							$tfname = @tempnam(__FILE__, 'codepot-fetch-folder-');
 | 
				
			||||||
 | 
							if ($tfname === FALSE) return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$actual_tfname = $tfname . '.d';
 | 
				
			||||||
 | 
							codepot_delete_files ($actual_tfname, TRUE); // delete the directory in case it exists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (@svn_checkout ($workurl, $actual_tfname, $rev, 0) === FALSE)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								codepot_delete_files ($actual_tfname, TRUE);
 | 
				
			||||||
 | 
								@unlink ($tfname);
 | 
				
			||||||
 | 
								return FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//exec ("zip {$tfname}.zip -r {$actual_tfname}");
 | 
				
			||||||
 | 
							if (codepot_zip_dir ("{$tfname}.zip", $actual_tfname, $topdir, array('.svn')) === FALSE) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								codepot_delete_files ($actual_tfname, TRUE);
 | 
				
			||||||
 | 
								@unlink ($tfname);
 | 
				
			||||||
 | 
								@unlink ("{$tfname}.zip"); // delete potentially residual zip file 
 | 
				
			||||||
 | 
								return FALSE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//codepot_delete_files ($actual_tfname, TRUE); // delete the directory in case it exists
 | 
				
			||||||
 | 
							return $tfname;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
?>
 | 
					?>
 | 
				
			||||||
 | 
				
			|||||||
@ -282,7 +282,7 @@ $this->load->view (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="infostrip" id="code_folder_mainarea_infostrip">
 | 
					<div class="infostrip" id="code_folder_mainarea_infostrip">
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	<?php if (CODEPOT_SIGNIN_FOR_CODE_SEARCH === FALSE || (isset($login['id']) && $login['id'] != '')): ?>
 | 
						<?php if (CODEPOT_SIGNIN_FOR_CODE_SEARCH === FALSE || (isset($login['id']) && $login['id'] != '')): ?>
 | 
				
			||||||
	<?php print form_open("code/search/{$project->id}/", 'id="code_folder_search_form"')?>
 | 
						<?php print form_open("code/search/{$project->id}/", 'id="code_folder_search_form"')?>
 | 
				
			||||||
	<?php print form_hidden('search_folder', set_value('search_folder', $file['fullpath']), 'id="code_folder_search_folder"')?>
 | 
						<?php print form_hidden('search_folder', set_value('search_folder', $file['fullpath']), 'id="code_folder_search_folder"')?>
 | 
				
			||||||
@ -350,6 +350,11 @@ $this->load->view (
 | 
				
			|||||||
		else
 | 
							else
 | 
				
			||||||
			print anchor ("code/history/{$project->id}/{$xpar}", $this->lang->line('History'));
 | 
								print anchor ("code/history/{$project->id}/{$xpar}", $this->lang->line('History'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							print ' | ';
 | 
				
			||||||
 | 
							print anchor (
 | 
				
			||||||
 | 
								"code/fetch/{$project->id}/${xpar}{$revreq}",
 | 
				
			||||||
 | 
								$this->lang->line('Download'));
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		print '</div>';
 | 
							print '</div>';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		usort ($file['content'], 'comp_files');
 | 
							usort ($file['content'], 'comp_files');
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user