]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Bookmark/importdelicious.php
Web UI for importing delicious backup files
[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
52     function title()
53     {
54         return _("Import del.icio.us bookmarks");
55     }
56
57     /**
58      * For initializing members of the class.
59      *
60      * @param array $argarray misc. arguments
61      *
62      * @return boolean true
63      */
64
65     function prepare($argarray)
66     {
67         parent::prepare($argarray);
68
69         $cur = common_current_user();
70
71         if (empty($cur)) {
72             throw new ClientException(_('Only logged-in users can import del.icio.us backups.'), 403);
73         }
74
75         if (!$cur->hasRight(BookmarkPlugin::IMPORTDELICIOUS)) {
76             throw new ClientException(_('You may not restore your account.'), 403);
77         }
78
79         return true;
80     }
81
82     /**
83      * Handler method
84      *
85      * @param array $argarray is ignored since it's now passed in in prepare()
86      *
87      * @return void
88      */
89
90     function handle($argarray=null)
91     {
92         parent::handle($argarray);
93
94         if ($this->isPost()) {
95             $this->importDelicious();
96         } else {
97             $this->showPage();
98         }
99         return;
100     }
101
102     /**
103      * Queue a file for importation
104      * 
105      * Uses the DeliciousBackupImporter class; may take a long time!
106      *
107      * @return void
108      */
109
110     function importDelicious()
111     {
112         $this->checkSessionToken();
113
114         if (!isset($_FILES[ImportDeliciousForm::FILEINPUT]['error'])) {
115             throw new ClientException(_('No uploaded file.'));
116         }
117
118         switch ($_FILES[ImportDeliciousForm::FILEINPUT]['error']) {
119         case UPLOAD_ERR_OK: // success, jump out
120             break;
121         case UPLOAD_ERR_INI_SIZE:
122             // TRANS: Client exception thrown when an uploaded file is larger than set in php.ini.
123             throw new ClientException(_('The uploaded file exceeds the ' .
124                 'upload_max_filesize directive in php.ini.'));
125             return;
126         case UPLOAD_ERR_FORM_SIZE:
127             throw new ClientException(
128                 // TRANS: Client exception.
129                 _('The uploaded file exceeds the MAX_FILE_SIZE directive' .
130                 ' that was specified in the HTML form.'));
131             return;
132         case UPLOAD_ERR_PARTIAL:
133             @unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']);
134             // TRANS: Client exception.
135             throw new ClientException(_('The uploaded file was only' .
136                 ' partially uploaded.'));
137             return;
138         case UPLOAD_ERR_NO_FILE:
139             // No file; probably just a non-AJAX submission.
140             throw new ClientException(_('No uploaded file.'));
141             return;
142         case UPLOAD_ERR_NO_TMP_DIR:
143             // TRANS: Client exception thrown when a temporary folder is not present to store a file upload.
144             throw new ClientException(_('Missing a temporary folder.'));
145             return;
146         case UPLOAD_ERR_CANT_WRITE:
147             // TRANS: Client exception thrown when writing to disk is not possible during a file upload operation.
148             throw new ClientException(_('Failed to write file to disk.'));
149             return;
150         case UPLOAD_ERR_EXTENSION:
151             // TRANS: Client exception thrown when a file upload operation has been stopped by an extension.
152             throw new ClientException(_('File upload stopped by extension.'));
153             return;
154         default:
155             common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
156                 $_FILES[ImportDeliciousForm::FILEINPUT]['error']);
157             // TRANS: Client exception thrown when a file upload operation has failed with an unknown reason.
158             throw new ClientException(_('System error uploading file.'));
159             return;
160         }
161
162         $filename = $_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name'];
163
164         try {
165             if (!file_exists($filename)) {
166                 throw new ServerException("No such file '$filename'.");
167             }
168         
169             if (!is_file($filename)) {
170                 throw new ServerException("Not a regular file: '$filename'.");
171             }
172         
173             if (!is_readable($filename)) {
174                 throw new ServerException("File '$filename' not readable.");
175             }
176         
177             common_debug(sprintf(_("Getting backup from file '%s'."), $filename));
178
179             $html = file_get_contents($filename);
180
181             // Enqueue for processing.
182
183             $qm = QueueManager::get();
184             $qm->enqueue(array(common_current_user(), $html), 'dlcsback');
185
186             $this->success = true;
187
188             $this->showPage();
189
190         } catch (Exception $e) {
191             // Delete the file and re-throw
192             @unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']);
193             throw $e;
194         }
195     }
196
197     function showContent()
198     {
199         if ($this->success) {
200             $this->element('p', null,
201                            _('Feed will be restored. Please wait a few minutes for results.'));
202         } else {
203             $form = new ImportDeliciousForm($this);
204             $form->show();
205         }
206     }
207
208     /**
209      * Return true if read only.
210      *
211      * MAY override
212      *
213      * @param array $args other arguments
214      *
215      * @return boolean is read only action?
216      */
217
218     function isReadOnly($args)
219     {
220         return !$this->isPost();
221     }
222 }
223
224 /**
225  * A form for backing up the account.
226  *
227  * @category  Account
228  * @package   StatusNet
229  * @author    Evan Prodromou <evan@status.net>
230  * @copyright 2010 StatusNet, Inc.
231  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
232  * @link      http://status.net/
233  */
234
235 class ImportDeliciousForm extends Form
236 {
237     const FILEINPUT = 'deliciousbackupfile';
238
239     function __construct($out=null) {
240         parent::__construct($out);
241         $this->enctype = 'multipart/form-data';
242     }
243
244     /**
245      * Class of the form.
246      *
247      * @return string the form's class
248      */
249
250     function formClass()
251     {
252         return 'form_import_delicious';
253     }
254
255     /**
256      * URL the form posts to
257      *
258      * @return string the form's action URL
259      */
260
261     function action()
262     {
263         return common_local_url('importdelicious');
264     }
265
266     /**
267      * Output form data
268      * 
269      * Really, just instructions for doing a backup.
270      *
271      * @return void
272      */
273
274     function formData()
275     {
276         $this->out->elementStart('p', 'instructions');
277
278         $this->out->raw(_('You can upload a backed-up delicious.com bookmarks file.'));
279         
280         $this->out->elementEnd('p');
281
282         $this->out->elementStart('ul', 'form_data');
283
284         $this->out->elementStart('li', array ('id' => 'settings_attach'));
285         $this->out->element('input', array('name' => self::FILEINPUT,
286                                            'type' => 'file',
287                                            'id' => self::FILEINPUT));
288         $this->out->elementEnd('li');
289
290         $this->out->elementEnd('ul');
291     }
292
293     /**
294      * Buttons for the form
295      * 
296      * In this case, a single submit button
297      *
298      * @return void
299      */
300
301     function formActions()
302     {
303         $this->out->submit('submit',
304                            _m('BUTTON', 'Upload'),
305                            'submit',
306                            null,
307                            _('Upload the file'));
308     }
309 }