3
3
* This file implements the UI for file upload.
5
* This file is part of Quam Plures - {@link http://quamplures.net/}
6
* See also {@link https://launchpad.net/quam-plures}.
8
* @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}
9
* @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
10
* Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
12
* {@internal License choice
13
* - If you have received this file as part of a package, please find the license.txt file in
14
* the same folder or the closest folder above for complete license terms.
15
* - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
16
* then you must choose one of the following licenses before using the file:
17
* - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
18
* - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
21
* {@internal Open Source relicensing agreement:
22
* Daniel HAHLER grants Francois PLANQUE the right to license
23
* Daniel HAHLER's contributions to this file and the b2evolution project
24
* under any OSI approved OSS license (http://www.opensource.org/licenses/).
27
* {@internal Below is a list of authors who have contributed to design/coding of this file: }}
28
* @author blueyed: Daniel HAHLER.
29
* @author fplanque: Francois PLANQUE.
5
* @author {@link http://wonderwinds.com/ Ed Bennett}
6
* @author {@link http://daniel.hahler.de/ Daniel HAHLER}
7
* @author {@link http://fplanque.net/ Francois PLANQUE}
8
* @copyright (c) 2009 by {@link http://quamplures.net/ the Quam Plures project}
9
* @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
33
if( !defined('QP_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
12
if(!defined('QP_MAIN_INIT')) die('fail');
14
global $ads_list_path;
18
global $upload_quickmode;
19
global $uploadwithproperties;
40
20
global $UserSettings;
42
global $upload_quickmode, $failedFiles, $ads_list_path, $uploadwithproperties;
47
23
<script type="text/javascript">
50
* Mighty cool function to append an input or textarea element onto another element.
52
* @usedby addAnotherFileInput()
54
function appendLabelAndInputElements( appendTo, labelText, labelBr, inputOrTextarea, inputName,
55
inputSizeOrCols, inputMaxLengthOrRows, inputType, inputClass,
56
inputChecked, labelLast, addLabelFor )
58
if( typeof( labelLast ) === 'undefined' )
64
var fileInput = document.createElement( inputOrTextarea );
65
fileInput.name = inputName;
66
fileInput.id = inputName.replace( /[\[\]]/g, '_' );
67
if( inputOrTextarea == "input" )
69
fileInput.type = typeof( inputType ) !== 'undefined' ?
73
if( typeof( inputSizeOrCols ) !== 'undefined' )
75
fileInput.size = inputSizeOrCols;
78
if( typeof( inputMaxLengthOrRows ) !== 'undefined' )
80
fileInput.maxlength = inputMaxLengthOrRows;
26
* Mighty cool function to append an input or textarea element onto another element
28
function appendLabelAndInputElements( appendTo, labelText, labelBr, inputOrTextarea, inputName, inputSizeOrCols,
29
inputMaxLengthOrRows, inputType, inputClass, inputChecked, labelLast, addLabelFor )
31
if( typeof( labelLast ) === 'undefined' )
37
var fileInput = document.createElement( inputOrTextarea );
38
fileInput.name = inputName;
39
fileInput.id = inputName.replace( /[\[\]]/g, '_' );
40
if( inputOrTextarea == "input" )
42
fileInput.type = typeof( inputType ) !== 'undefined' ? inputType : "text";
43
if( typeof( inputSizeOrCols ) !== 'undefined' )
45
fileInput.size = inputSizeOrCols;
47
if( typeof( inputMaxLengthOrRows ) !== 'undefined' )
49
fileInput.maxlength = inputMaxLengthOrRows;
54
fileInput.cols = inputSizeOrCols;
55
fileInput.rows = inputMaxLengthOrRows;
57
fileInput.className = inputClass;
60
// We want the label to appear after the input element
61
appendTo.appendChild( fileInput );
62
appendTo.appendChild( document.createTextNode( ' ' ) );
66
var fileLabel = document.createElement('label');
67
var fileLabelText = document.createTextNode( labelText );
68
fileLabel.appendChild( fileLabelText );
69
if( typeof( addLabelFor ) !== 'undefined' && addLabelFor )
71
fileLabel.htmlFor = fileInput.id;
73
appendTo.appendChild( fileLabel );
76
// Label before input element
79
// We want a BR after the label
80
appendTo.appendChild( document.createElement('br') );
85
fileInput.cols = inputSizeOrCols;
86
fileInput.rows = inputMaxLengthOrRows;
89
fileInput.className = inputClass;
92
{ // We want the label to appear after the input element:
93
appendTo.appendChild( fileInput );
94
84
appendTo.appendChild( document.createTextNode( ' ' ) );
98
var fileLabel = document.createElement('label');
99
var fileLabelText = document.createTextNode( labelText );
101
fileLabel.appendChild( fileLabelText );
103
if( typeof( addLabelFor ) !== 'undefined' && addLabelFor )
105
fileLabel.htmlFor = fileInput.id;
108
appendTo.appendChild( fileLabel );
111
{ // Label before input element:
113
{ // We want a BR after the label:
114
appendTo.appendChild( document.createElement('br') );
118
appendTo.appendChild( document.createTextNode( ' ' ) );
121
appendTo.appendChild( fileInput );
124
appendTo.appendChild( document.createElement('br') );
126
if( typeof( inputChecked ) !== 'undefined' && inputChecked )
127
{ // Checkbox is checked:
128
fileInput.setAttribute( 'checked', 'checked' );
136
* Add a new fileinput area to the upload form.
138
function addAnotherFileInput()
140
var uploadfiles = document.getElementById("uploadfileinputs");
141
var newLI = document.createElement("li");
142
var closeLink = document.createElement("a");
143
var closeImage = document.createElement("img");
145
uploadfiles.appendChild( newLI );
146
newLI.appendChild( closeLink );
147
closeLink.appendChild( closeImage );
150
newLI.className = "clear";
152
closeImage.src = "<?php echo get_icon( 'close', 'url' ) ?>";
153
closeImage.alt = "<?php echo get_icon( 'close', 'alt' ) ?>";
156
$icon_class = get_icon( 'close', 'class' );
160
closeImage.className = '<?php echo $icon_class ?>';
164
if( get_icon( 'close', 'rollover' ) )
165
{ // handle rollover images ('close' by default is one).
167
closeLink.className = 'rollover';
168
if( typeof setupRollovers == 'function' )
175
closeImage.setAttribute( 'onclick', "document.getElementById('uploadfileinputs').removeChild(this.parentNode.parentNode);" ); // TODO: setting onclick this way DOES NOT work in IE. (try attachEvent then)
176
closeLink.style.cssFloat = 'right'; // standard (not working in IE)
177
closeLink.style.styleFloat = 'right'; // IE
179
appendLabelAndInputElements( newLI, '<?php echo TS_('Choose a file'); ?>:', false, 'input', 'uploadfile['+nextFileInputID+']', '70', '0', 'file', 'upload_file' );
181
if( $uploadwithproperties )
182
{ // We want file properties on the upload form:
86
appendTo.appendChild( fileInput );
88
appendTo.appendChild( document.createElement('br') );
90
if( typeof( inputChecked ) !== 'undefined' && inputChecked )
92
// Checkbox is checked
93
fileInput.setAttribute( 'checked', 'checked' );
100
* Add a new fileinput area to the upload form.
102
function addAnotherFileInput()
104
var uploadfiles = document.getElementById("uploadfileinputs");
105
var newLI = document.createElement("li");
106
var closeLink = document.createElement("a");
107
var closeImage = document.createElement("img");
108
uploadfiles.appendChild( newLI );
109
newLI.appendChild( closeLink );
110
closeLink.appendChild( closeImage );
112
newLI.className = "clear";
114
closeImage.src = "<?php echo get_icon( 'close', 'url' ) ?>";
115
closeImage.alt = "<?php echo get_icon( 'close', 'alt' ) ?>";
117
$icon_class = get_icon( 'close', 'class' );
121
closeImage.className = '<?php echo $icon_class ?>';
125
if( get_icon( 'close', 'rollover' ) )
127
// handle rollover images ('close' by default is one)
129
closeLink.className = 'rollover';
130
if( typeof setupRollovers == 'function' )
137
closeImage.setAttribute( 'onclick', "document.getElementById('uploadfileinputs').removeChild(this.parentNode.parentNode);" );
138
closeLink.style.cssFloat = 'right'; // standard (not working in IE)
139
closeLink.style.styleFloat = 'right'; // IE
141
appendLabelAndInputElements( newLI, '<?php echo TS_('Choose a file'); ?>:', false, 'input', 'uploadfile['+nextFileInputID+']', '70', '0', 'file', 'upload_file' );
143
if( $uploadwithproperties )
145
// We want file properties on the upload form:
184
147
appendLabelAndInputElements( newLI, '<?php echo TS_('Filename on server (optional)'); ?>:', false, 'input', 'uploadfile_name['+nextFileInputID+']', '50', '80', 'text', '' );
185
148
appendLabelAndInputElements( newLI, '<?php echo TS_('Long title'); ?>:', true, 'input', 'uploadfile_title['+nextFileInputID+']', '50', '255', 'text', 'large' );
186
149
appendLabelAndInputElements( newLI, '<?php echo TS_('Cascade file info (file name -> title -> alt -> description)?'); ?>', false, 'input', 'uploadfile_cascade['+nextFileInputID+']', undefined, undefined, 'checkbox', '', true, true, true );
187
150
appendLabelAndInputElements( newLI, '<?php echo TS_('Alternative text (useful for images)'); ?>:', true, 'input', 'uploadfile_alt['+nextFileInputID+']', '50', '255', 'text', 'large' );
188
151
appendLabelAndInputElements( newLI, '<?php echo TS_('Caption/Description of the file'); ?>:', true, 'textarea', 'uploadfile_desc['+nextFileInputID+']', '38', '3', '', 'large' );
194
157
// Pretend we want to cascade metadata:
195
158
var cascade_input = document.createElement( 'input' );
196
159
cascade_input.name = 'uploadfile_cascade['+nextFileInputID+']';
198
161
cascade_input.value = '1';
200
163
newLI.appendChild( cascade_input );
211
// Begin payload block:
212
$this->disp_payload_begin();
215
$Form = new Form( NULL, 'fm_upload_checkchanges', 'post', 'none', 'multipart/form-data' );
216
$Form->begin_form( 'fform' );
217
$Form->hidden_ctrl();
218
$Form->hidden( 'MAX_FILE_SIZE', $Settings->get( 'upload_maxkb' )*1024 ); // Just a hint for the browser.
219
$Form->hidden( 'upload_quickmode', $upload_quickmode );
220
$Form->hiddens_by_key( get_memorized() );
223
$Widget = new Widget( 'file_browser' );
225
$Widget->global_icon( T_('Quit upload mode!'), 'close', regenerate_url( 'ctrl,fm_mode', 'ctrl=files' ) );
227
$Widget->title = get_manual_link( 'file-upload' ).T_('File upload');
228
$Widget->disp_template_replaced( 'block_start' );
174
// Begin payload block
175
$this->disp_payload_begin();
177
$Form = new Form( NULL, 'fm_upload_checkchanges', 'post', 'none', 'multipart/form-data' );
178
$Form->begin_form( 'fform' );
179
$Form->hidden_ctrl();
180
$Form->hidden( 'MAX_FILE_SIZE', $Settings->get( 'upload_maxkb' )*1024 ); // Just a hint for the browser.
181
$Form->hidden( 'upload_quickmode', $upload_quickmode );
182
$Form->hiddens_by_key( get_memorized() );
184
$Widget = new Widget( 'file_browser' );
185
$Widget->global_icon( T_('Quit upload mode!'), 'close', regenerate_url( 'ctrl,fm_mode', 'ctrl=files' ), T_('cancel') );
186
$Widget->title = T_('File upload');
187
$Widget->disp_template_replaced( 'block_start' );
233
189
<table id="fm_browser" cellspacing="0" cellpadding="0">
236
<td colspan="2" id="fm_bar">
238
if( $uploadwithproperties )
240
echo '<a href="'.regenerate_url( 'uploadwithproperties', 'uploadwithproperties=0' ).'">'.T_('Hide advanced upload properties').'</a>';
244
echo '<a href="'.regenerate_url( 'uploadwithproperties', 'uploadwithproperties=1' ).'">'.T_('Show advanced upload properties').'</a>';
254
echo '<td id="fm_dirtree">';
256
// Version with all roots displayed
257
echo get_directory_tree( NULL, NULL, $ads_list_path, true );
259
// Version with only the current root displayed:
260
/* echo get_directory_tree( $fm_FileRoot, $fm_FileRoot->ads_path, $ads_list_path, true ); */
262
echo '<td id="fm_files">';
264
if( count( $failedFiles ) )
266
echo '<p class="error">'.T_('Some file uploads failed. Please check the errors below.').'</p>';
267
// Display failed files:
268
$displayFiles = & $failedFiles;
271
{ // No failed failes, display 5 empty input blocks:
272
$displayFiles = array( NULL, NULL, NULL, NULL, NULL );
276
<script type="text/javascript">
278
nextFileInputID = <?php echo max( array_keys( $displayFiles ) ) + 1; ?>;
282
<div class="upload_title"><?php echo T_('Files to upload') ?></div>
284
<ul id="uploadfileinputs">
286
foreach( $displayFiles as $lKey => $lMessage )
287
{ // For each file upload block to display:
289
if( $lMessage !== NULL )
290
{ // This is a failed upload:
291
echo '<li class="invalid" title="'
292
./* TRANS: will be displayed as title for failed file uploads */ T_('Invalid submission.').'">';
293
echo '<p class="error">'.$lMessage.'</p>';
296
{ // Not a failed upload, display normal block:
300
// fp> TODO: would be cool to add a close icon starting at the 2nd <li>
301
// dh> TODO: it may be useful to add the "accept" attrib to the INPUT elements to give the browser a hint about the accepted MIME types
304
<label><?php echo T_('Choose a file'); ?>:</label>
305
<input name="uploadfile[<?php echo $lKey; ?>]" size="70" type="file" class="upload_file" /><br />
308
if( $uploadwithproperties )
309
{ // We want file properties on the upload form:
311
<label><?php echo T_('Filename on server (optional)'); ?>:</label>
312
<input name="uploadfile_name[<?php echo $lKey; ?>]" type="text" size="50" maxlength="80"
313
value="<?php echo ( isset( $uploadfile_name[$lKey] ) ? format_to_output( $uploadfile_name[$lKey], 'formvalue' ) : '' ) ?>" /><br />
315
<input name="uploadfile_cascade[<?php echo $lKey; ?>]" id="uploadfile_cascade_<?php echo $lKey; ?>_" type="checkbox"
316
<?php echo isset( $uploadfile_cascade[$lKey] ) || $lMessage === NULL /* default: checked */ ? 'checked="checked"' : '' ?> />
317
<label for="uploadfile_cascade_<?php echo $lKey; ?>_"><?php echo T_('Cascade file info (file name -> title -> alt -> description)?'); ?></label><br />
319
<label><?php echo T_('Long title'); ?>:</label><br />
320
<input name="uploadfile_title[<?php echo $lKey; ?>]" type="text" size="50" maxlength="255" class="large"
321
value="<?php echo ( isset( $uploadfile_title[$lKey] ) ? format_to_output( $uploadfile_title[$lKey], 'formvalue' ) : '' );
324
<label><?php echo T_('Alternative text (useful for images)'); ?>:</label><br />
325
<input name="uploadfile_alt[<?php echo $lKey; ?>]" type="text" size="50" maxlength="255" class="large"
326
value="<?php echo ( isset( $uploadfile_alt[$lKey] ) ? format_to_output( $uploadfile_alt[$lKey], 'formvalue' ) : '' );
329
<label><?php echo T_('Caption/Description of the file'); /* TODO: maxlength (DB) */ ?>:</label><br />
330
<textarea name="uploadfile_desc[<?php echo $lKey; ?>]" rows="3" cols="38" class="large"><?php
331
echo ( isset( $uploadfile_desc[$lKey] ) ? $uploadfile_desc[$lKey] : '' )
336
{ // Pretend we want to cascade metadata:
338
<input name="uploadfile_cascade[<?php echo $lKey; ?>]" type="hidden" value="1" />
343
// no text after </li> or JS will bite you! (This is where additional blocks get inserted)
349
<p class="uploadfileinputs"><a href="#" onclick="addAnotherFileInput(); return false;" class="small"><?php echo T_('Add another file'); ?></a></p>
351
<div class="upload_foot">
352
<input type="submit" value="<?php echo format_to_output( T_('Upload to server now'), 'formvalue' ); ?>" class="ActionButton" >
353
<input type="reset" value="<?php echo format_to_output( T_('Reset'), 'formvalue' ); ?>" class="ResetButton">
357
$restrictNotes = array();
359
// Get list of recognized file types (others are not allowed to get uploaded)
360
// dh> because FiletypeCache/DataObjectCache has no interface for getting a list, this dirty query seems less dirty to me.
361
$allowed_extensions = $DB->get_col( 'SELECT ftyp_extensions FROM T_filetypes WHERE ftyp_allowed != 0' );
362
$allowed_extensions = implode( ' ', $allowed_extensions ); // implode with space, ftyp_extensions can hold many, separated by space
364
$allowed_extensions = preg_split( '~\s+~', $allowed_extensions, -1, PREG_SPLIT_NO_EMPTY );
366
$allowed_extensions = implode_with_and($allowed_extensions);
368
$restrictNotes[] = '<strong>'.T_('Allowed file extensions').'</strong>: '.$allowed_extensions;
370
if( $Settings->get( 'upload_maxkb' ) )
371
{ // We want to restrict on file size:
372
$restrictNotes[] = '<strong>'.T_('Maximum allowed file size').'</strong>: '.bytesreadable( $Settings->get( 'upload_maxkb' )*1024 );
375
echo implode( '<br />', $restrictNotes ).'<br />';
387
$Widget->disp_template_raw( 'block_end' );
391
// End payload block:
392
$this->disp_payload_end();
190
<thead><tr><td colspan="2" id="fm_bar">
192
if( $uploadwithproperties )
194
echo '<a href="'.regenerate_url( 'uploadwithproperties', 'uploadwithproperties=0' ).'">'.T_('Hide advanced upload properties').'</a>';
198
echo '<a href="'.regenerate_url( 'uploadwithproperties', 'uploadwithproperties=1' ).'">'.T_('Show advanced upload properties').'</a>';
206
echo '<td id="fm_dirtree">';
208
// Version with all roots displayed
209
echo get_directory_tree( NULL, NULL, $ads_list_path, true );
211
// Version with only the current root displayed
212
# echo get_directory_tree( $fm_FileRoot, $fm_FileRoot->ads_path, $ads_list_path, true );
214
echo '<td id="fm_files">';
216
if( count( $failedFiles ) )
218
echo '<p class="error">'.T_('Some file uploads failed. Please check the errors below.').'</p>';
219
// Display failed files
220
$displayFiles = & $failedFiles;
224
// No failed failes, display 5 empty input blocks
225
$displayFiles = array( NULL, NULL, NULL, NULL, NULL );
229
<script type="text/javascript">
231
nextFileInputID = <?php echo max( array_keys( $displayFiles ) ) + 1; ?>;
235
<div class="upload_title"><?php echo T_('Files to upload') ?></div>
236
<ul id="uploadfileinputs">
238
foreach( $displayFiles as $lKey => $lMessage )
240
// For each file upload block to display
241
if( $lMessage !== NULL )
243
// This is a failed upload
244
echo '<li class="invalid" title="'
245
./* TRANS: will be displayed as title for failed file uploads */ T_('Invalid submission.').'">';
246
echo '<p class="error">'.$lMessage.'</p>';
250
// Not a failed upload, display normal block
254
// @todo (0000) fp> would be cool to add a close icon starting at the 2nd <li>
255
// @todo (0000) dh> it may be useful to add the "accept" attrib to the INPUT
256
// elements to give the browser a hint about the accepted MIME types
259
<label><?php echo T_('Choose a file'); ?>:</label>
260
<input name="uploadfile[<?php echo $lKey; ?>]" size="70" type="file" class="upload_file" /><br />
263
if( $uploadwithproperties )
265
// We want file properties on the upload form
267
<label><?php echo T_('Filename on server (optional)'); ?>:</label>
268
<input name="uploadfile_name[<?php echo $lKey; ?>]" type="text" size="50" maxlength="80" value="<?php echo ( isset( $uploadfile_name[$lKey] ) ? format_to_output( $uploadfile_name[$lKey], 'formvalue' ) : '' ) ?>" /><br />
270
<input name="uploadfile_cascade[<?php echo $lKey; ?>]" id="uploadfile_cascade_<?php echo $lKey; ?>_" type="checkbox" <?php echo isset( $uploadfile_cascade[$lKey] ) || $lMessage === NULL /* default: checked */ ? 'checked="checked"' : '' ?>/>
271
<label for="uploadfile_cascade_<?php echo $lKey; ?>_"><?php echo T_('Cascade file info (file name -> title -> alt -> description)?'); ?></label><br />
273
<label><?php echo T_('Long title'); ?>:</label><br />
274
<input name="uploadfile_title[<?php echo $lKey; ?>]" type="text" size="50" maxlength="255" class="large" value="<?php echo ( isset( $uploadfile_title[$lKey] ) ? format_to_output( $uploadfile_title[$lKey], 'formvalue' ) : '' ); ?>" /><br />
276
<label><?php echo T_('Alternative text (useful for images)'); ?>:</label><br />
277
<input name="uploadfile_alt[<?php echo $lKey; ?>]" type="text" size="50" maxlength="255" class="large" value="<?php echo ( isset( $uploadfile_alt[$lKey] ) ? format_to_output( $uploadfile_alt[$lKey], 'formvalue' ) : '' ); ?>" /><br />
279
<label><?php echo T_('Caption/Description of the file'); ?>:</label><br />
280
<textarea name="uploadfile_desc[<?php echo $lKey; ?>]" rows="3" cols="38" class="large"><?php echo ( isset( $uploadfile_desc[$lKey] ) ? $uploadfile_desc[$lKey] : '' ); ?></textarea><br />
285
// Pretend we want to cascade metadata
287
<input name="uploadfile_cascade[<?php echo $lKey; ?>]" type="hidden" value="1" />
292
// no text after </li> or JS will bite you! (This is where additional blocks get inserted)
297
<p class="uploadfileinputs"><a href="#" onclick="addAnotherFileInput(); return false;" class="small"><?php echo T_('Add another file'); ?></a></p>
299
<div class="upload_foot">
300
<input type="submit" value="<?php echo format_to_output( T_('Upload to server now'), 'formvalue' ); ?>" class="ActionButton" >
301
<input type="reset" value="<?php echo format_to_output( T_('Reset'), 'formvalue' ); ?>" class="ResetButton">
304
$restrictNotes = array();
305
// Get list of recognized file types (others are not allowed to get uploaded)
306
// dh> because FiletypeCache/DataObjectCache has no interface for getting a list,
307
// this dirty query seems less dirty to me.
308
$allowed_extensions = $DB->get_col( 'SELECT ftyp_extensions FROM T_filetypes WHERE ftyp_allowed != 0' );
309
// implode with space, ftyp_extensions can hold many, separated by space
310
$allowed_extensions = implode( ' ', $allowed_extensions );
312
$allowed_extensions = preg_split( '~\s+~', $allowed_extensions, -1, PREG_SPLIT_NO_EMPTY );
314
$allowed_extensions = implode_with_and( $allowed_extensions );
316
$restrictNotes[] = '<strong>'.T_('Allowed file extensions').'</strong>: '.$allowed_extensions;
318
if( $Settings->get( 'upload_maxkb' ) )
320
// We want to restrict on file size
321
$restrictNotes[] = '<strong>'.T_('Maximum allowed file size').'</strong>: '.bytesreadable( $Settings->get( 'upload_maxkb' )*1024 );
323
echo implode( '<br />', $restrictNotes ).'<br />';
327
</td></tr></tbody></table>
330
$Widget->disp_template_raw( 'block_end' );
333
$this->disp_payload_end();