Issue 81: Allow users to create downloads that point offsite
This commit is contained in:
		| @@ -44,6 +44,15 @@ class IDF_Form_Upload extends Pluf_Form | ||||
|                                                        'size' => 67, | ||||
|                                                                     ), | ||||
|                                             )); | ||||
|         $this->fields['ext_file'] = new Pluf_Form_Field_Varchar( | ||||
|             array('required' => false, | ||||
|                 'label' => __('External File'), | ||||
|                 'initial' => '', | ||||
|                 'widget_attrs' => array( | ||||
|                     'maxlength' => 200, | ||||
|                     'size' => 67, | ||||
|                 ), | ||||
|             )); | ||||
|         $this->fields['changelog'] = new Pluf_Form_Field_Varchar( | ||||
|                                       array('required' => false, | ||||
|                                             'label' => __('Description'), | ||||
| @@ -55,7 +64,7 @@ class IDF_Form_Upload extends Pluf_Form | ||||
|                                                                     ), | ||||
|                                             )); | ||||
|         $this->fields['file'] = new Pluf_Form_Field_File( | ||||
|                                       array('required' => true, | ||||
|                                       array('required' => false, | ||||
|                                             'label' => __('File'), | ||||
|                                             'initial' => '', | ||||
|                                             'max_size' => Pluf::f('max_upload_size', 2097152), | ||||
| @@ -80,6 +89,9 @@ class IDF_Form_Upload extends Pluf_Form | ||||
|     public function clean_file() | ||||
|     { | ||||
|         // FIXME: we do the same in IDF_Form_WikiResourceCreate and a couple of other places as well | ||||
|         if (empty($this->cleaned_data['file'])) { | ||||
|             return $this->cleaned_data['file']; | ||||
|         } | ||||
|         $extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext')))); | ||||
|         if (strlen($extra)) $extra .= '|'; | ||||
|         if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) { | ||||
| @@ -121,6 +133,9 @@ class IDF_Form_Upload extends Pluf_Form | ||||
|                 throw new Pluf_Form_Invalid(__('You provided an invalid label.')); | ||||
|             } | ||||
|         } | ||||
|         if (empty($this->cleaned_data["file"]) && empty($this->cleaned_data["ext_file"])) { | ||||
|             throw new Pluf_Form_Invalid(__("Must upload a file or specify an external file")); | ||||
|         } | ||||
|         return $this->cleaned_data; | ||||
|     } | ||||
|  | ||||
| @@ -162,14 +177,21 @@ class IDF_Form_Upload extends Pluf_Form | ||||
|                 $tags[] = IDF_Tag::add($name, $this->project, $class); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Create the upload | ||||
|         $upload = new IDF_Upload(); | ||||
|         $upload->project = $this->project; | ||||
|         $upload->submitter = $this->user; | ||||
|         $upload->summary = trim($this->cleaned_data['summary']); | ||||
|         $upload->changelog = trim($this->cleaned_data['changelog']); | ||||
|         $upload->file = $this->cleaned_data['file']; | ||||
|         $upload->filesize = filesize(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']); | ||||
|         if (!empty($this->cleaned_data["file"])) { | ||||
|             $upload->file = $this->cleaned_data['file']; | ||||
|             $upload->filesize = filesize(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']); | ||||
|         } else { | ||||
|             $upload->file = end(explode("/", $this->cleaned_data["ext_file"])); | ||||
|             $upload->ext_file = $this->cleaned_data['ext_file']; | ||||
|         } | ||||
|  | ||||
|         $upload->downloads = 0; | ||||
|         $upload->create(); | ||||
|         foreach ($tags as $tag) { | ||||
|   | ||||
							
								
								
									
										29
									
								
								indefero/src/IDF/Migrations/32ExternalFile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								indefero/src/IDF/Migrations/32ExternalFile.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| <?php | ||||
|  | ||||
| function IDF_Migrations_32ExternalFile_up() | ||||
| { | ||||
|     $table = Pluf::factory('IDF_Upload')->getSqlTable(); | ||||
|  | ||||
|     $sql = array(); | ||||
|  | ||||
|     $sql["MySQL"] = "ALTER TABLE " . $table . " ADD COLUMN `ext_file` VARCHAR(250) NULL AFTER `modif_dtime`;"; | ||||
|  | ||||
|     $db = Pluf::db(); | ||||
|     $engine = Pluf::f('db_engine'); | ||||
|  | ||||
|     $db->execute($sql[$engine]); | ||||
| } | ||||
|  | ||||
| function IDF_Migrations_32ExternalFile_down() | ||||
| { | ||||
|     $table = Pluf::factory('IDF_Upload')->getSqlTable(); | ||||
|  | ||||
|     $sql = array(); | ||||
|  | ||||
|     $sql["MySQL"] = "ALTER TABLE " . $table . " DROP COLUMN `ext_file`;"; | ||||
|  | ||||
|     $db = Pluf::db(); | ||||
|     $engine = Pluf::f('db_engine'); | ||||
|  | ||||
|     $db->execute($sql[$engine]); | ||||
| } | ||||
| @@ -56,6 +56,13 @@ class IDF_Upload extends Pluf_Model | ||||
|                                   'size' => 250, | ||||
|                                   'verbose' => __('summary'), | ||||
|                                   ), | ||||
|                             'ext_file' => | ||||
|                                 array( | ||||
|                                     'type' => 'Pluf_DB_Field_Varchar', | ||||
|                                     'blank' => false, | ||||
|                                     'size' => 250, | ||||
|                                     'verbose' => __('External File URL'), | ||||
|                                 ), | ||||
|                             'changelog' => | ||||
|                             array( | ||||
|                                   'type' => 'Pluf_DB_Field_Text', | ||||
| @@ -140,6 +147,54 @@ class IDF_Upload extends Pluf_Model | ||||
|         return $this->file; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      *  Get the file size of any remote resource (using get_headers()), | ||||
|      *  either in bytes or - default - as human-readable formatted string. | ||||
|      * | ||||
|      *  @author  Stephan Schmitz <eyecatchup@gmail.com> | ||||
|      *  @license MIT <http://eyecatchup.mit-license.org/> | ||||
|      *  @url     <https://gist.github.com/eyecatchup/f26300ffd7e50a92bc4d> | ||||
|      * | ||||
|      *  @param   string   $url          Takes the remote object's URL. | ||||
|      *  @param   boolean  $formatSize   Whether to return size in bytes or formatted. | ||||
|      *  @param   boolean  $useHead      Whether to use HEAD requests. If false, uses GET. | ||||
|      *  @return  string                 Returns human-readable formatted size | ||||
|      *                                  or size in bytes (default: formatted). | ||||
|      * | ||||
|      *  <code> | ||||
|      *  //example | ||||
|      *  echo getRemoteFilesize('https://github.com/eyecatchup/SEOstats/archive/master.zip'); | ||||
|      *  </code> | ||||
|      */ | ||||
|     private function getRemoteFilesize($url, $formatSize = true, $useHead = true) | ||||
|     { | ||||
|         if (false !== $useHead) { | ||||
|             stream_context_set_default(array('http' => array('method' => 'HEAD'))); | ||||
|         } | ||||
|         $head = array_change_key_case(get_headers($url, 1)); | ||||
|         // content-length of download (in bytes), read from Content-Length: field | ||||
|         $clen = isset($head['content-length']) ? $head['content-length'] : 0; | ||||
|         // cannot retrieve file size, return "-1" | ||||
|         if (!$clen) { | ||||
|             return -1; | ||||
|         } | ||||
|         if (!$formatSize) { | ||||
|             return $clen; // return size in bytes | ||||
|         } | ||||
|         $size = $clen; | ||||
|         switch ($clen) { | ||||
|             case $clen < 1024: | ||||
|                 $size = $clen .' B'; break; | ||||
|             case $clen < 1048576: | ||||
|                 $size = round($clen / 1024, 2) .' KiB'; break; | ||||
|             case $clen < 1073741824: | ||||
|                 $size = round($clen / 1048576, 2) . ' MiB'; break; | ||||
|             case $clen < 1099511627776: | ||||
|                 $size = round($clen / 1073741824, 2) . ' GiB'; break; | ||||
|         } | ||||
|         return $size; // return formatted size | ||||
|     } | ||||
|  | ||||
|     function _toIndex() | ||||
|     { | ||||
|         return ''; | ||||
| @@ -150,7 +205,11 @@ class IDF_Upload extends Pluf_Model | ||||
|         if ($this->id == '') { | ||||
|             $this->creation_dtime = gmdate('Y-m-d H:i:s'); | ||||
|             $this->modif_dtime = gmdate('Y-m-d H:i:s'); | ||||
|             $this->md5 = md5_file ($this->getFullPath()); | ||||
|             if ($this->ext_file == "") { | ||||
|                 $this->md5 = md5_file ($this->getFullPath()); | ||||
|             } else { | ||||
|                 $this->filesize = $this->getRemoteFilesize($this->ext_file, false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -204,11 +204,15 @@ class IDF_Views_Download | ||||
|         $prj->inOr404($upload); | ||||
|         $upload->downloads += 1; | ||||
|         $upload->update(); | ||||
|         $path = $upload->getFullPath(); | ||||
|         $mime = IDF_FileUtil::getMimeType($path); | ||||
|         $render = new Pluf_HTTP_Response_File($path, $mime[0]); | ||||
|         $render->headers['Content-MD5'] = $upload->md5; | ||||
|         $render->headers['Content-Disposition'] = 'attachment; filename="'.$upload->file.'"'; | ||||
|         if ($upload->ext_file == "") { | ||||
|             $path = $upload->getFullPath(); | ||||
|             $mime = IDF_FileUtil::getMimeType($path); | ||||
|             $render = new Pluf_HTTP_Response_File($path, $mime[0]); | ||||
|             $render->headers['Content-MD5'] = $upload->md5; | ||||
|             $render->headers['Content-Disposition'] = 'attachment; filename="'.$upload->file.'"'; | ||||
|         } else { | ||||
|             $render = new Pluf_HTTP_Response_Redirect($upload->ext_file); | ||||
|         } | ||||
|         return $render; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,12 @@ | ||||
| {$form.f.summary|unsafe} | ||||
| </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <th><strong>{$form.f.ext_file.labelTag}:</strong></th> | ||||
|     <td>{if $form.f.ext_file.errors}{$form.f.ext_file.fieldErrors}{/if} | ||||
|         {$form.f.ext_file|unsafe} | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
| <th>{$form.f.changelog.labelTag}:</th> | ||||
| <td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if} | ||||
|   | ||||
| @@ -4,9 +4,14 @@ | ||||
|  | ||||
| <div class="download-file"> | ||||
| {if $deprecated}<p class="smaller">{blocktrans}<strong>Attention!</strong> This file is marked as deprecated, download it only if you are sure you need this specific version.{/blocktrans}</p>{/if} | ||||
|  | ||||
| <a href="{url 'IDF_Views_Download::download', array($project.shortname, $file.file)}">{$file}</a> - {$file.filesize|size} | ||||
| {if !$file.ext_file} | ||||
| <br /> | ||||
| <span class="helptext">{trans 'md5:'} {$file.md5}</span> | ||||
| {/if} | ||||
|  | ||||
|  | ||||
| </div> | ||||
| {if $file.changelog} | ||||
| <h2 class="changes">{trans 'Changes'}</h2> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user