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