]> git.mxchange.org Git - friendica.git/blob - addon/js_upload/js_upload.php
Update info comments in all plugins
[friendica.git] / addon / js_upload / js_upload.php
1 <?php
2
3 /**
4  * Name: JS Uploader
5  * Description: JavaScript photo/image uploader. Uses Valum 'qq' Uploader.
6  * Version: 1.0
7  * Author: Chris Case <http://friendika.openmindspace.org/profile/chris_case>
8  */
9
10 /**
11  *
12  * JavaScript Photo/Image Uploader
13  *
14  * Uses Valum 'qq' Uploader. 
15  * Module Author: Chris Case
16  *
17  * Prior to enabling, ensure that you have a directory 'uploads'
18  * which is writable by the web server.
19  *
20  */
21
22
23 function js_upload_install() {
24         register_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
25         register_hook('photo_post_init',   'addon/js_upload/js_upload.php', 'js_upload_post_init');
26         register_hook('photo_post_file',   'addon/js_upload/js_upload.php', 'js_upload_post_file');
27         register_hook('photo_post_end',    'addon/js_upload/js_upload.php', 'js_upload_post_end');
28 }
29
30
31 function js_upload_uninstall() {
32         unregister_hook('photo_upload_form', 'addon/js_upload/js_upload.php', 'js_upload_form');
33         unregister_hook('photo_post_init',   'addon/js_upload/js_upload.php', 'js_upload_post_init');
34         unregister_hook('photo_post_file',   'addon/js_upload/js_upload.php', 'js_upload_post_file');
35         unregister_hook('photo_post_end',    'addon/js_upload/js_upload.php', 'js_upload_post_end');
36 }
37
38
39 function js_upload_form(&$a,&$b) {
40
41         $b['default_upload'] = false;
42
43         $b['addon_text'] .= '<link href="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.css" rel="stylesheet" type="text/css">';
44         $b['addon_text'] .= '<script src="' . $a->get_baseurl() . '/addon/js_upload/file-uploader/client/fileuploader.js" type="text/javascript"></script>';
45    
46         $upload_msg = t('Upload a file');
47         $drop_msg = t('Drop files here to upload');
48         $cancel = t('Cancel');
49         $failed = t('Failed');
50
51         $b['addon_text'] .= <<< EOT
52         
53  <div id="file-uploader-demo1">         
54   <noscript>                    
55    <p>Please enable JavaScript to use file uploader.</p>
56    <!-- or put a simple form for upload here -->
57   </noscript> 
58  </div>
59
60 <script type="text/javascript">
61 var uploader = null;       
62 function getSelected(opt) {
63             var selected = new Array();
64             var index = 0;
65             for (var intLoop = 0; intLoop < opt.length; intLoop++) {
66                if ((opt[intLoop].selected) ||
67                    (opt[intLoop].checked)) {
68                   index = selected.length;
69                   //selected[index] = new Object;
70                   selected[index] = opt[intLoop].value;
71                   //selected[index] = intLoop;
72                }
73             }
74             return selected;
75          } 
76 function createUploader() {
77         uploader = new qq.FileUploader({
78                 element: document.getElementById('file-uploader-demo1'),
79                 action: '{$b['post_url']}',
80
81         template: '<div class="qq-uploader">' + 
82                 '<div class="qq-upload-drop-area"><span>$drop_msg</span></div>' +
83                 '<div class="qq-upload-button">$upload_msg</div>' +
84                 '<ul class="qq-upload-list"></ul>' + 
85              '</div>',
86
87         // template for one item in file list
88         fileTemplate: '<li>' +
89                 '<span class="qq-upload-file"></span>' +
90                 '<span class="qq-upload-spinner"></span>' +
91                 '<span class="qq-upload-size"></span>' +
92                 '<a class="qq-upload-cancel" href="#">$cancel</a>' +
93                 '<span class="qq-upload-failed-text">$failed</span>' +
94             '</li>',        
95
96                 debug: true,
97                 onSubmit: function(id,filename) {
98
99                         uploader.setParams( {
100                                 newalbum                :       document.getElementById('photos-upload-newalbum').value,
101                                 album                   :       document.getElementById('photos-upload-album-select').value,
102                                 group_allow             :       getSelected(document.getElementById('group_allow')).join(','),
103                                 contact_allow   :       getSelected(document.getElementById('contact_allow')).join(','),
104                                 group_deny              :       getSelected(document.getElementById('group_deny')).join(','),
105                                 contact_deny    :       getSelected(document.getElementById('contact_deny')).join(',')
106                         });
107                 }
108         });           
109 }
110
111
112 // in your app create uploader as soon as the DOM is ready
113 // don't wait for the window to load  
114 window.onload = createUploader;     
115
116
117 </script>
118  
119 EOT;
120
121
122 }
123
124 function js_upload_post_init(&$a,&$b) {
125
126         // list of valid extensions, ex. array("jpeg", "xml", "bmp")
127
128         $allowedExtensions = array("jpeg","gif","png","jpg");
129
130         // max file size in bytes
131
132         $sizeLimit = 6 * 1024 * 1024;
133
134         $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
135
136         $result = $uploader->handleUpload();
137
138
139         // to pass data through iframe you will need to encode all html tags
140         $a->data['upload_jsonresponse'] =  htmlspecialchars(json_encode($result), ENT_NOQUOTES);
141
142         if(isset($result['error'])) {
143                 logger('mod/photos.php: photos_post(): error uploading photo: ' . $result['error'] , 'LOGGER_DEBUG');
144                 killme();
145         }
146
147         $a->data['upload_result'] = $result;
148
149 }
150
151 function js_upload_post_file(&$a,&$b) {
152
153         $result = $a->data['upload_result'];
154
155         $b['src']               = $result['path'];
156         $b['filename']  = $result['filename'];
157         $b['filesize']  = filesize($b['src']);
158
159 }
160
161
162 function js_upload_post_end(&$a,&$b) {
163
164 logger('upload_post_end');
165         if(x($a->data,'upload_jsonresponse')) {
166                 echo $a->data['upload_jsonresponse'];
167                 killme();
168         }
169
170 }
171
172
173 /**
174  * Handle file uploads via XMLHttpRequest
175  */
176 class qqUploadedFileXhr {
177
178         private $pathnm = '';
179
180     /**
181      * Save the file in the temp dir.
182      * @return boolean TRUE on success
183      */
184     function save() {    
185         $input = fopen("php://input", "r");
186         $this->pathnm = tempnam(sys_get_temp_dir(),'frn');
187                 $temp = fopen($this->pathnm,"w");
188         $realSize = stream_copy_to_stream($input, $temp);
189
190         fclose($input);
191                 fclose($temp);
192         
193         if ($realSize != $this->getSize()){            
194             return false;
195         }
196         return true;
197     }
198
199         function getPath() {
200                 return $this->pathnm;
201         }
202
203     function getName() {
204         return $_GET['qqfile'];
205     }
206
207     function getSize() {
208         if (isset($_SERVER["CONTENT_LENGTH"])){
209             return (int)$_SERVER["CONTENT_LENGTH"];            
210         } else {
211             throw new Exception('Getting content length is not supported.');
212         }      
213     }   
214 }
215
216 /**
217  * Handle file uploads via regular form post (uses the $_FILES array)
218  */
219
220 class qqUploadedFileForm {  
221
222
223     /**
224      * Save the file to the specified path
225      * @return boolean TRUE on success
226      */
227
228
229     function save() {
230         return true;
231     }
232
233         function getPath() {
234                 return $_FILES['qqfile']['tmp_name'];
235         }
236
237     function getName() {
238         return $_FILES['qqfile']['name'];
239     }
240     function getSize() {
241         return $_FILES['qqfile']['size'];
242     }
243 }
244
245 class qqFileUploader {
246     private $allowedExtensions = array();
247     private $sizeLimit = 10485760;
248     private $file;
249
250     function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){        
251         $allowedExtensions = array_map("strtolower", $allowedExtensions);
252             
253         $this->allowedExtensions = $allowedExtensions;        
254         $this->sizeLimit = $sizeLimit;
255         
256         $this->checkServerSettings();       
257
258         if (isset($_GET['qqfile'])) {
259             $this->file = new qqUploadedFileXhr();
260         } elseif (isset($_FILES['qqfile'])) {
261             $this->file = new qqUploadedFileForm();
262         } else {
263             $this->file = false; 
264         }
265
266     }
267     
268     private function checkServerSettings(){        
269         $postSize = $this->toBytes(ini_get('post_max_size'));
270         $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));        
271                 logger('mod/photos.php: qqFileUploader(): upload_max_filesize=' . $uploadSize , 'LOGGER_DEBUG');
272         if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
273             $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';             
274             die("{'error':'increase post_max_size and upload_max_filesize to $size'}");    
275         }        
276     }
277     
278     private function toBytes($str){
279         $val = trim($str);
280         $last = strtolower($str[strlen($str)-1]);
281         switch($last) {
282             case 'g': $val *= 1024;
283             case 'm': $val *= 1024;
284             case 'k': $val *= 1024;        
285         }
286         return $val;
287     }
288     
289     /**
290      * Returns array('success'=>true) or array('error'=>'error message')
291      */
292     function handleUpload(){
293         
294         if (!$this->file){
295             return array('error' => t('No files were uploaded.'));
296         }
297         
298         $size = $this->file->getSize();
299         
300         if ($size == 0) {
301             return array('error' => t('Uploaded file is empty'));
302         }
303         
304         if ($size > $this->sizeLimit) {
305
306             return array('error' => t('Uploaded file is too large'));
307         }
308         
309
310                 $maximagesize = get_config('system','maximagesize');
311
312                 if(($maximagesize) && ($size > $maximagesize)) {
313                         return array('error' => t('Image exceeds size limit of ') . $maximagesize );
314
315                 }
316
317         $pathinfo = pathinfo($this->file->getName());
318         $filename = $pathinfo['filename'];
319
320         $ext = $pathinfo['extension'];
321
322         if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
323             $these = implode(', ', $this->allowedExtensions);
324             return array('error' => t('File has an invalid extension, it should be one of ') . $these . '.');
325         }
326         
327         if ($this->file->save()){
328             return array(
329                                 'success'=>true,
330                                 'path' => $this->file->getPath(), 
331                                 'filename' => $filename . '.' . $ext
332                         );
333         } else {
334             return array(
335                                 'error'=> t('Upload was cancelled, or server error encountered'),
336                                 'path' => $this->file->getPath(), 
337                                 'filename' => $filename . '.' . $ext
338                         );
339         }
340         
341     }    
342 }