Issue 81: Allow users to create downloads that point offsite
This commit is contained in:
parent
4421b6d4a1
commit
75986bb272
@ -44,6 +44,15 @@ class IDF_Form_Upload extends Pluf_Form
|
|||||||
'size' => 67,
|
'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(
|
$this->fields['changelog'] = new Pluf_Form_Field_Varchar(
|
||||||
array('required' => false,
|
array('required' => false,
|
||||||
'label' => __('Description'),
|
'label' => __('Description'),
|
||||||
@ -55,7 +64,7 @@ class IDF_Form_Upload extends Pluf_Form
|
|||||||
),
|
),
|
||||||
));
|
));
|
||||||
$this->fields['file'] = new Pluf_Form_Field_File(
|
$this->fields['file'] = new Pluf_Form_Field_File(
|
||||||
array('required' => true,
|
array('required' => false,
|
||||||
'label' => __('File'),
|
'label' => __('File'),
|
||||||
'initial' => '',
|
'initial' => '',
|
||||||
'max_size' => Pluf::f('max_upload_size', 2097152),
|
'max_size' => Pluf::f('max_upload_size', 2097152),
|
||||||
@ -80,6 +89,9 @@ class IDF_Form_Upload extends Pluf_Form
|
|||||||
public function clean_file()
|
public function clean_file()
|
||||||
{
|
{
|
||||||
// FIXME: we do the same in IDF_Form_WikiResourceCreate and a couple of other places as well
|
// 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'))));
|
$extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext'))));
|
||||||
if (strlen($extra)) $extra .= '|';
|
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'])) {
|
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.'));
|
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;
|
return $this->cleaned_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,14 +177,21 @@ class IDF_Form_Upload extends Pluf_Form
|
|||||||
$tags[] = IDF_Tag::add($name, $this->project, $class);
|
$tags[] = IDF_Tag::add($name, $this->project, $class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the upload
|
// Create the upload
|
||||||
$upload = new IDF_Upload();
|
$upload = new IDF_Upload();
|
||||||
$upload->project = $this->project;
|
$upload->project = $this->project;
|
||||||
$upload->submitter = $this->user;
|
$upload->submitter = $this->user;
|
||||||
$upload->summary = trim($this->cleaned_data['summary']);
|
$upload->summary = trim($this->cleaned_data['summary']);
|
||||||
$upload->changelog = trim($this->cleaned_data['changelog']);
|
$upload->changelog = trim($this->cleaned_data['changelog']);
|
||||||
|
if (!empty($this->cleaned_data["file"])) {
|
||||||
$upload->file = $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']);
|
$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->downloads = 0;
|
||||||
$upload->create();
|
$upload->create();
|
||||||
foreach ($tags as $tag) {
|
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,
|
'size' => 250,
|
||||||
'verbose' => __('summary'),
|
'verbose' => __('summary'),
|
||||||
),
|
),
|
||||||
|
'ext_file' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Varchar',
|
||||||
|
'blank' => false,
|
||||||
|
'size' => 250,
|
||||||
|
'verbose' => __('External File URL'),
|
||||||
|
),
|
||||||
'changelog' =>
|
'changelog' =>
|
||||||
array(
|
array(
|
||||||
'type' => 'Pluf_DB_Field_Text',
|
'type' => 'Pluf_DB_Field_Text',
|
||||||
@ -140,6 +147,54 @@ class IDF_Upload extends Pluf_Model
|
|||||||
return $this->file;
|
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()
|
function _toIndex()
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
@ -150,7 +205,11 @@ class IDF_Upload extends Pluf_Model
|
|||||||
if ($this->id == '') {
|
if ($this->id == '') {
|
||||||
$this->creation_dtime = gmdate('Y-m-d H:i:s');
|
$this->creation_dtime = gmdate('Y-m-d H:i:s');
|
||||||
$this->modif_dtime = gmdate('Y-m-d H:i:s');
|
$this->modif_dtime = gmdate('Y-m-d H:i:s');
|
||||||
|
if ($this->ext_file == "") {
|
||||||
$this->md5 = md5_file ($this->getFullPath());
|
$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);
|
$prj->inOr404($upload);
|
||||||
$upload->downloads += 1;
|
$upload->downloads += 1;
|
||||||
$upload->update();
|
$upload->update();
|
||||||
|
if ($upload->ext_file == "") {
|
||||||
$path = $upload->getFullPath();
|
$path = $upload->getFullPath();
|
||||||
$mime = IDF_FileUtil::getMimeType($path);
|
$mime = IDF_FileUtil::getMimeType($path);
|
||||||
$render = new Pluf_HTTP_Response_File($path, $mime[0]);
|
$render = new Pluf_HTTP_Response_File($path, $mime[0]);
|
||||||
$render->headers['Content-MD5'] = $upload->md5;
|
$render->headers['Content-MD5'] = $upload->md5;
|
||||||
$render->headers['Content-Disposition'] = 'attachment; filename="'.$upload->file.'"';
|
$render->headers['Content-Disposition'] = 'attachment; filename="'.$upload->file.'"';
|
||||||
|
} else {
|
||||||
|
$render = new Pluf_HTTP_Response_Redirect($upload->ext_file);
|
||||||
|
}
|
||||||
return $render;
|
return $render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
{$form.f.summary|unsafe}
|
{$form.f.summary|unsafe}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<tr>
|
||||||
<th>{$form.f.changelog.labelTag}:</th>
|
<th>{$form.f.changelog.labelTag}:</th>
|
||||||
<td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if}
|
<td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if}
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
|
|
||||||
<div class="download-file">
|
<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}
|
{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}
|
<a href="{url 'IDF_Views_Download::download', array($project.shortname, $file.file)}">{$file}</a> - {$file.filesize|size}
|
||||||
|
{if !$file.ext_file}
|
||||||
<br />
|
<br />
|
||||||
<span class="helptext">{trans 'md5:'} {$file.md5}</span>
|
<span class="helptext">{trans 'md5:'} {$file.md5}</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{if $file.changelog}
|
{if $file.changelog}
|
||||||
<h2 class="changes">{trans 'Changes'}</h2>
|
<h2 class="changes">{trans 'Changes'}</h2>
|
||||||
|
Loading…
Reference in New Issue
Block a user