1<?php
2/*
3* Copyright e107 Inc e107.org, Licensed under GNU GPL (http://www.gnu.org/licenses/gpl.txt)
4* $Id$
5*
6* Upload file shortcode
7*/
8
9/**
10 * @package e107
11 * @subpackage shortcodes
12 * @version $Revision$
13 * @todo uploadfile shortcode - JS/Flash upload, optional allow image resize (see news administration), optional move by filetype (processing) - similar to Media Manager
14 *
15 * Print out upload form elements and/or process submitted uploads.
16 */
17
18/**
19 * Print out upload form elements and/or process submitted uploads.
20 * Your <form> tag must include: enctype='multipart/form-data' - in order to work.
21 *
22 * Example usage:
23 * <code>
24 * // Process uploaded file (sent by the form below), it'll print out message (if any)
25 * if(isset($_POST['etrigger_uploadfiles']))
26 * {
27 * 		// NOTE: chmod permissions after upload are set to 0755
28 * 		echo e107::getParser()->parseTemplate('{UPLOADFILE='.e_MEDIA.'public|process=1&upload_file_mask=jpg,jpeg,png,gif&upload_final_chmod=493}');
29 * }
30 *
31 * // Render upload form
32 * echo '<form action="'.e_SELF.'" enctype="multipart/form-data" method="post">';
33 * echo e107::getParser()->parseTemplate('{UPLOADFILE='.e_MEDIA.'public|nowarn&trigger=etrigger_uploadfiles}');
34 * echo '</form>';
35 * </code>
36 *
37 * @todo Human readable *nix like permissions option (upload_final_chmod) e.g. 'rw-rw-r--' --> 0664, 'rwxrwxrwx' --> 0777
38 *
39 * @param string $parm upload_path|parameters (GET query format)
40 * 	Available parameters:
41 * 	- trigger [render] (string): name attribute of upload trigger button, default 'uploadfiles'
42 * 	- name [render|processing] (string): name of upload (file) field, without array brackets ([]), default 'file_userfile'
43 * 	- up_container [render] (string): the id attribute of upload container (containing upload field(s)), default 'up_container'
44 * 	- up_row [render] (string): the id attribute of upload added fields (diuplicates), default 'upline'
45 * 	- process [render|processing] ('0'|'1' boolean): main shortcode action, 0 - render markup, 1 - process uploaded files, default '0'
46 *  - upload_file_mask [processing] (string): 'file_mask' parameter of process_uploaded_files() - comma-separated list of file types which if defined limits the allowed file types to those which are
47 *  in both this list and the file specified by the 'filetypes' option. Enables restriction to, for example, image files. {@link process_uploaded_files()),
48 *  default is empty string
49 *  - upload_filetypes [processing] (string): 'filetypes' parameter of process_uploaded_files() - name of file containing list of valid file types, default is empty string
50 * 	- upload_extra_file_types [processing] (string): 'extra_file_types' parameter of process_uploaded_files() - '0' (default) rejects totally unknown file extensions;
51 *  '1' accepts totally unknown file extensions which are in $options['filetypes'] file; comma-separated list of additional permitted file extensions
52 *	- upload_final_chmod [processing] (string): 'final_chmod' parameter of process_uploaded_files() - chmod() to be applied to uploaded files (0644 default).
53 *	NOTE: you need to provide number with numerci base of decimal (as a string) which will be auto-converted to octal number
54 *	Example: '493' --> 0755; '511' --> 0777
55 *	- upload_max_upload_size [processing] (string): 'max_upload_size' parameter of process_uploaded_files() - maximum size of uploaded files in bytes,
56 *	or as a string with a 'multiplier' letter (e.g. 16M) at the end, default is empty string
57 *	- upload_overwrite [processing] ('0'|'1' boolean): 'overwrite' parameter of process_uploaded_files() - maximum number of files which can be uploaded - default is '0' (unlimited)
58 *	- return_type [processing] ('0'|'message'|'result'): 'message' (default) - return messages (eMessage::render() method);
59 *	'result' - return array generated by process_uploaded_files();
60 *	'0' - return empty string;
61 *	NOTE: upload messages are added to 'upload_shortcode' message namespace
62 *	<code>
63 *	// render messages manually (return_type=0)
64 *	echo e107::getMessage()->render('upload_shortcode');
65 *	// OR copy them to the default message namespace
66 *	e107::getMessage()->moveStack('upload_shortcode', 'default');
67 *	// Do something... and render all messages
68 *	echo e107::getMessage()->render();
69 *	<code>
70 * @return mixed Based on 'return_type' parameter - string or uploaded array result
71 */
72function uploadfile_shortcode($parm)
73{
74	if(!FILE_UPLOADS)
75	{
76		return LAN_UPLOAD_SERVEROFF;
77	}
78	if(USER_AREA === TRUE && !check_class(e107::getPref('upload_class')))
79	{
80		return LAN_DISABLED;
81	}
82
83	$parm = explode('|', $parm, 2);
84
85	$path = $parm[0];
86	if($path && !is_writable($path))
87	{
88		return LAN_UPLOAD_777." <b>".str_replace("../","",$path)."</b>";
89	}
90
91	$parms = array();
92	parse_str(varset($parm[1], ''), $parms);
93
94	$parms = array_merge(array(
95		'trigger'		=> 'uploadfiles',
96		'name'			=> 'file_userfile',
97		'up_container' 	=> 'up_container',
98		'up_row' 		=> 'upline',
99		'process' 		=> '0',
100		'upload_file_mask' 	=> '',
101		'upload_filetypes' 	=> '',
102		'upload_extra_file_types' => '0',
103		'upload_final_chmod' => '',
104		'upload_max_upload_size' => '0',
105		'upload_max_file_count' => '0',
106		'upload_overwrite'	=> '0',
107		'return_type'	=> 'message',
108		'disable_button' => '0',
109	), $parms);
110
111
112	// PROCESS UPLOADED FILES, optional usage by external code
113	if($parms['process'])
114	{
115		e107_require_once(e_HANDLER.'upload_handler.php');
116		$options = array(
117			'file_mask' => $parms['upload_file_mask'],
118			'filetypes' => $parms['upload_filetypes'],
119			'extra_file_types' => $parms['upload_extra_file_types'] ? true : false,
120			'final_chmod' => $parms['upload_final_chmod'] ? intval(intval($parms['upload_final_chmod']), 8) : 0644,
121			'max_upload_size' => $parms['upload_max_upload_size'],
122			'file_array_name' => $parms['name'],
123			'max_file_count' => $parms['upload_max_file_count'],
124			'overwrite' => $parms['upload_overwrite'] ? true : false,
125		);
126
127		$uploaded = process_uploaded_files($path, false, $options);
128		if($uploaded)
129		{
130			$emessage = e107::getMessage();
131			foreach ($uploaded as $finfo)
132			{
133				$emessage->addStack($finfo['message'], 'upload_shortcode', $finfo['error'] ? E_MESSAGE_ERROR : E_MESSAGE_SUCCESS);
134			}
135			if($parms['return_type'] == 'message') return $emessage->render('upload_shortcode');
136		}
137		return($parms['return_type'] == 'result' ? $uploaded : '');
138	}
139
140	// RENDER FORM
141	$onclickt = !isset($parms['nowarn']) ? " onclick=\"return jsconfirm('".LAN_UPLOAD_CONFIRM."')\"" : '';
142	$onclickd = " onclick=\"duplicateHTML('{$parms['up_row']}','{$parms['up_container']}');\"";
143	$name = $parms['name'].'[]';
144
145	$text .="
146	        <!-- Upload Shortcode -->
147			<div>
148				<div class='field-spacer'>
149					<button class='action duplicate' type='button' value='no-value'{$onclickd}><span>".LAN_UPLOAD_ADDFILE."</span></button>";
150
151	// Media Manager does the submit, not the shortcode.
152	if(!$parms['disable_button'])
153		$text .= "<button class='upload' type='submit' name='{$parms['trigger']}' value='no-value'{$onclickt}><span>".LAN_UPLOAD_FILES."</span></button>";
154
155	$text .= "
156				</div>
157				<div id='{$parms['up_container']}'>
158					<div id='{$parms['up_row']}' class='nowrap'>
159						<input class='tbox file' type='file' name='{$name}' />
160			        </div>
161				</div>
162				<div class='field-help'>Upload to: <strong>".str_replace('../', '', $path)."</strong></div>
163			</div>
164			<!-- End Upload Shortcode -->
165		";
166
167	return $text;
168}