]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Bookmark/importdelicious.php
Merge branch 'master' of gitorious.org:statusnet/mainline into 0.9.x
[quix0rs-gnu-social.git] / plugins / Bookmark / importdelicious.php
1 <?php
2 /**
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2010, StatusNet, Inc.
5  *
6  * Import del.icio.us bookmarks backups
7  * 
8  * PHP version 5
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Affero General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * @category  Bookmark
24  * @package   StatusNet
25  * @author    Evan Prodromou <evan@status.net>
26  * @copyright 2010 StatusNet, Inc.
27  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28  * @link      http://status.net/
29  */
30
31 if (!defined('STATUSNET')) {
32     // This check helps protect against security problems;
33     // your code file can't be executed directly from the web.
34     exit(1);
35 }
36
37 /**
38  * UI for importing del.icio.us bookmark backups
39  *
40  * @category  Bookmark
41  * @package   StatusNet
42  * @author    Evan Prodromou <evan@status.net>
43  * @copyright 2010 StatusNet, Inc.
44  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
45  * @link      http://status.net/
46  */
47
48 class ImportdeliciousAction extends Action
49 {
50     protected $success = false;
51     private $inprogress = false;
52
53     /**
54      * Return the title of the page
55      *
56      * @return string page title
57      */
58
59     function title()
60     {
61         return _("Import del.icio.us bookmarks");
62     }
63
64     /**
65      * For initializing members of the class.
66      *
67      * @param array $argarray misc. arguments
68      *
69      * @return boolean true
70      */
71
72     function prepare($argarray)
73     {
74         parent::prepare($argarray);
75
76         $cur = common_current_user();
77
78         if (empty($cur)) {
79             throw new ClientException(_('Only logged-in users can '.
80                                         'import del.icio.us backups.'),
81                                       403);
82         }
83
84         if (!$cur->hasRight(BookmarkPlugin::IMPORTDELICIOUS)) {
85             throw new ClientException(_('You may not restore your account.'), 403);
86         }
87
88         return true;
89     }
90
91     /**
92      * Handler method
93      *
94      * @param array $argarray is ignored since it's now passed in in prepare()
95      *
96      * @return void
97      */
98
99     function handle($argarray=null)
100     {
101         parent::handle($argarray);
102
103         if ($this->isPost()) {
104             $this->importDelicious();
105         } else {
106             $this->showPage();
107         }
108         return;
109     }
110
111     /**
112      * Queue a file for importation
113      * 
114      * Uses the DeliciousBackupImporter class; may take a long time!
115      *
116      * @return void
117      */
118
119     function importDelicious()
120     {
121         $this->checkSessionToken();
122
123         if (!isset($_FILES[ImportDeliciousForm::FILEINPUT]['error'])) {
124             throw new ClientException(_('No uploaded file.'));
125         }
126
127         switch ($_FILES[ImportDeliciousForm::FILEINPUT]['error']) {
128         case UPLOAD_ERR_OK: // success, jump out
129             break;
130         case UPLOAD_ERR_INI_SIZE:
131             // TRANS: Client exception thrown when an uploaded file is too large.
132             throw new ClientException(_('The uploaded file exceeds the ' .
133                 'upload_max_filesize directive in php.ini.'));
134             return;
135         case UPLOAD_ERR_FORM_SIZE:
136             throw new ClientException(
137                 // TRANS: Client exception.
138                 _('The uploaded file exceeds the MAX_FILE_SIZE directive' .
139                 ' that was specified in the HTML form.'));
140             return;
141         case UPLOAD_ERR_PARTIAL:
142             @unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']);
143             // TRANS: Client exception.
144             throw new ClientException(_('The uploaded file was only' .
145                 ' partially uploaded.'));
146             return;
147         case UPLOAD_ERR_NO_FILE:
148             // No file; probably just a non-AJAX submission.
149             throw new ClientException(_('No uploaded file.'));
150             return;
151         case UPLOAD_ERR_NO_TMP_DIR:
152             // TRANS: Client exception thrown when a temporary folder is not present
153             throw new ClientException(_('Missing a temporary folder.'));
154             return;
155         case UPLOAD_ERR_CANT_WRITE:
156             // TRANS: Client exception thrown when writing to disk is not possible
157             throw new ClientException(_('Failed to write file to disk.'));
158             return;
159         case UPLOAD_ERR_EXTENSION:
160             // TRANS: Client exception thrown when a file upload has been stopped
161             throw new ClientException(_('File upload stopped by extension.'));
162             return;
163         default:
164             common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
165                 $_FILES[ImportDeliciousForm::FILEINPUT]['error']);
166             // TRANS: Client exception thrown when a file upload operation has failed
167             throw new ClientException(_('System error uploading file.'));
168             return;
169         }
170
171         $filename = $_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name'];
172
173         try {
174             if (!file_exists($filename)) {
175                 throw new ServerException("No such file '$filename'.");
176             }
177         
178             if (!is_file($filename)) {
179                 throw new ServerException("Not a regular file: '$filename'.");
180             }
181         
182             if (!is_readable($filename)) {
183                 throw new ServerException("File '$filename' not readable.");
184             }
185         
186             common_debug(sprintf(_("Getting backup from file '%s'."), $filename));
187
188             $html = file_get_contents($filename);
189
190             // Enqueue for processing.
191
192             $qm = QueueManager::get();
193             $qm->enqueue(array(common_current_user(), $html), 'dlcsback');
194
195             if ($qm instanceof UnQueueManager) {
196                 // No active queuing means we've actually just completed the job!
197                 $this->success = true;
198             } else {
199                 // We've fed data into background queues, and it's probably still running.
200                 $this->inprogress = true;
201             }
202
203             $this->showPage();
204
205         } catch (Exception $e) {
206             // Delete the file and re-throw
207             @unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']);
208             throw $e;
209         }
210     }
211
212     /**
213      * Show the content of the page
214      *
215      * @return void
216      */
217
218     function showContent()
219     {
220         if ($this->success) {
221             $this->element('p', null,
222                            _('Bookmarks have been imported. Your bookmarks should now appear in search and your profile page.'));
223         } else if ($this->inprogress) {
224             $this->element('p', null,
225                            _('Bookmarks are being imported. Please wait a few minutes for results.'));
226         } else {
227             $form = new ImportDeliciousForm($this);
228             $form->show();
229         }
230     }
231
232     /**
233      * Return true if read only.
234      *
235      * MAY override
236      *
237      * @param array $args other arguments
238      *
239      * @return boolean is read only action?
240      */
241
242     function isReadOnly($args)
243     {
244         return !$this->isPost();
245     }
246 }
247
248 /**
249  * A form for backing up the account.
250  *
251  * @category  Account
252  * @package   StatusNet
253  * @author    Evan Prodromou <evan@status.net>
254  * @copyright 2010 StatusNet, Inc.
255  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
256  * @link      http://status.net/
257  */
258
259 class ImportDeliciousForm extends Form
260 {
261     const FILEINPUT = 'deliciousbackupfile';
262
263     /**
264      * Constructor
265      * 
266      * Set the encoding type, since this is a file upload.
267      *
268      * @param HTMLOutputter $out output channel
269      *
270      * @return ImportDeliciousForm this
271      */
272
273     function __construct($out=null)
274     {
275         parent::__construct($out);
276         $this->enctype = 'multipart/form-data';
277     }
278
279     /**
280      * Class of the form.
281      *
282      * @return string the form's class
283      */
284
285     function formClass()
286     {
287         return 'form_import_delicious';
288     }
289
290     /**
291      * URL the form posts to
292      *
293      * @return string the form's action URL
294      */
295
296     function action()
297     {
298         return common_local_url('importdelicious');
299     }
300
301     /**
302      * Output form data
303      * 
304      * Really, just instructions for doing a backup.
305      *
306      * @return void
307      */
308
309     function formData()
310     {
311         $this->out->elementStart('p', 'instructions');
312
313         $this->out->raw(_('You can upload a backed-up '.
314                           'delicious.com bookmarks file.'));
315         
316         $this->out->elementEnd('p');
317
318         $this->out->elementStart('ul', 'form_data');
319
320         $this->out->elementStart('li', array ('id' => 'settings_attach'));
321         $this->out->element('input', array('name' => self::FILEINPUT,
322                                            'type' => 'file',
323                                            'id' => self::FILEINPUT));
324         $this->out->elementEnd('li');
325
326         $this->out->elementEnd('ul');
327     }
328
329     /**
330      * Buttons for the form
331      * 
332      * In this case, a single submit button
333      *
334      * @return void
335      */
336
337     function formActions()
338     {
339         $this->out->submit('submit',
340                            _m('BUTTON', 'Upload'),
341                            'submit',
342                            null,
343                            _('Upload the file'));
344     }
345 }