MDL-16007 - add new $dontdie parameter to the send_ file functions
[moodle.git] / portfolio / type / boxnet / lib.php
1 <?php
2 require_once($CFG->libdir.'/filelib.php');
3 require_once($CFG->dirroot.'/repository/boxnet/boxlibphp5.php');
5 class portfolio_plugin_boxnet extends portfolio_plugin_base {
7     private $boxclient;
8     private $ticket;
9     private $authtoken;
10     private $folders;
11     private $accounttree;
13     public function prepare_package() {
14         return true; // don't do anything else for this plugin, we want to send all files as they are.
15     }
17     public function send_package() {
18         $ret = array();
19         foreach ($this->exporter->get_tempfiles() as $file) {
20             $return = $this->boxclient->uploadFile(
21                 array(
22                     'file'      => $file,
23                     'folder_id' => $this->get_export_config('folder')
24                 )
25             );
26             if (array_key_exists('status', $return) && $return['status'] == 'upload_ok'
27                 && array_key_exists('id', $return) && count($return['id']) == 1) {
28                 $return['rename'] = $this->rename_file($return['id'][array_pop(array_keys($return['id']))], $file->get_filename());
29                 $ret[] = $return;
30             }
31         }
32         if ($this->boxclient->isError()) {
33             return false;
34         }
35         return is_array($ret) && !empty($ret);
36     }
38     public function set_export_config($config) {
39         parent::set_export_config($config);
40         if (array_key_exists('newfolder', $config) && !empty($config['newfolder'])) {
41             if (!$created = $this->boxclient->createFolder($config['newfolder'])) {
42                 portfolio_exporter::raise_error('foldercreatefailed', 'portfolio_boxnet');
43             }
44             $this->folders[$created['folder_id']] = $created['folder_type'];
45             parent::set_export_config(array('folder' => $created['folder_id']));
46         }
47     }
49     public function get_export_summary() {
50         $allfolders = $this->get_folder_list();
51         return array(
52             get_string('targetfolder', 'portfolio_boxnet') => $allfolders[$this->get_export_config('folder')]
53         );
54     }
56     public function get_continue_url() {
57         // @todo this was a *guess* based on what urls I got clicking around the interface.
58         // the #0:f:<folderid> part seems fragile...
59         // but I couldn't find a documented permalink scheme.
60         return 'http://box.net/files#0:f:' . $this->get_export_config('folder');
61     }
63     public function expected_time($callertime) {
64         return $callertime;
65     }
67     public static function has_admin_config() {
68         return true;
69     }
71     public static function get_allowed_config() {
72         return array('apikey');
73     }
75     public function has_export_config() {
76         return true;
77     }
79     public function get_allowed_user_config() {
80         return array('authtoken', 'authtokenctime');
81     }
83     public function get_allowed_export_config() {
84         return array('folder', 'newfolder');
85     }
87     public function export_config_form(&$mform) {
88         $folders = $this->get_folder_list();
89         $strrequired = get_string('required');
90         $mform->addElement('text', 'plugin_newfolder', get_string('newfolder', 'portfolio_boxnet'));
91         if (empty($folders)) {
92             $mform->addRule('plugin_newfolder', $strrequired, 'required', null, 'client');
93         }
94         else {
95             $mform->addElement('select', 'plugin_folder', get_string('existingfolder', 'portfolio_boxnet'), $folders);
96         }
97     }
99     public function export_config_validation($data) {
100         if ((!array_key_exists('plugin_folder', $data) || empty($data['plugin_folder']))
101             && (!array_key_exists('plugin_newfolder', $data) || empty($data['plugin_newfolder']))) {
102             return array(
103                 'plugin_folder' => get_string('notarget', 'portfolio_boxnet'),
104                 'plugin_newfolder' => get_string('notarget', 'portfolio_boxnet'));
105         }
106         $allfolders = $this->get_folder_list();
107         if (in_array($data['plugin_newfolder'], $allfolders)) {
108             return array('plugin_newfolder' => get_string('folderclash', 'portfolio_boxnet'));
109         }
110     }
112     public function admin_config_form(&$mform) {
113         $strrequired = get_string('required');
114         $mform->addElement('text', 'apikey', get_string('apikey', 'portfolio_boxnet'));
115         $mform->addRule('apikey', $strrequired, 'required', null, 'client');
116     }
118     public function steal_control($stage) {
119         if ($stage != PORTFOLIO_STAGE_CONFIG) {
120             return false;
121         }
122         if ($this->authtoken) {
123             return false;
124         }
125         if (!$this->ensure_ticket()) {
126             portfolio_exporter::raise_error('noticket', 'portfolio_boxnet');
127         }
128         $token = $this->get_user_config('authtoken', $this->get('user')->id);
129         $ctime= $this->get_user_config('authtokenctime', $this->get('user')->id);
130         if (!empty($token) && (($ctime + 60*60*20) > time())) {
131             $this->authtoken = $token;
132             $this->boxclient->auth_token = $token;
133             return false;
134         }
135         return 'http://www.box.net/api/1.0/auth/'.$this->ticket;
136     }
138     public function post_control($stage, $params) {
139         if ($stage != PORTFOLIO_STAGE_CONFIG) {
140             return;
141         }
142         if (!array_key_exists('auth_token', $params) || empty($params['auth_token'])) {
143             portfolio_exporter::raise_error('noauthtoken', 'portfolio_boxnet');
144         }
145         $this->authtoken = $params['auth_token'];
146         $this->boxclient->auth_token = $this->authtoken;
147         $this->set_user_config(array('authtoken' => $this->authtoken, 'authtokenctime' => time()), $this->get('user')->id);
148     }
150     private function ensure_ticket() {
151         if (!empty($this->boxclient)) {
152             return true;
153         }
154         $this->boxclient = new boxclient($this->get_config('apikey'), '');
155         $ticket_return = $this->boxclient->getTicket();
156         if ($this->boxclient->isError() || empty($ticket_return)) {
157             portfolio_exporter::raise_error('noticket', 'portfolio_boxnet');
158         }
159         $this->ticket = $ticket_return['ticket'];
160         return $this->ticket;
161     }
163     private function ensure_account_tree() {
164         if (!empty($this->accounttree)) {
165             return;
166         }
167         if (empty($this->ticket)
168             || empty($this->authtoken)
169             || empty($this->boxclient)) {
170             // if we don't have these we're pretty much screwed
171             portfolio_exporter::raise_error('folderlistfailed', 'portfolio_boxnet');
172             return false;
173         }
174         $this->accounttree = $this->boxclient->getAccountTree();
175         if ($this->boxclient->isError()) {
176             portfolio_exporter::raise_error('folderlistfailed', 'portfolio_boxnet');
177         }
178         if (!is_array($this->accounttree)) {
179             return false;
180         }
183     }
185     private function get_folder_list() {
186         if (!empty($this->folders)) {
187             return $this->folders;
188         }
189         $this->ensure_account_tree();
190         $folders = array();
191         foreach ($this->accounttree['folder_id'] as $key => $id) {
192             if (empty($id)) {
193                 continue;
194             }
195             $name = $this->accounttree['folder_name'][$key];
196             if (!empty($this->accounttree['shared'][$key])) {
197                 $name .= ' (' . get_string('sharedfolder', 'portfolio_boxnet') . ')';
198             }
199             $folders[$id] = $name;
200         }
201         $this->folders = $folders;
202         return $folders;
203     }
205     private function rename_file($fileid, $newname) {
206         // look at moving this to the boxnet client class
207         $this->ensure_account_tree();
208         $count = 1;
209         $bits = explode('.', $newname);
210         $suffix = '';
211         if (count($bits) == 1) {
212             $prefix = $newname;
213         } else {
214             $suffix = '.' . array_pop($bits);
215             $prefix = implode('.', $bits);
216         }
217         while (true) {
218             if (!in_array($newname, $this->accounttree['file_name'])) {
219                 return $this->boxclient->renameFile($fileid, $newname);
220             }
221             $newname = $prefix . '(' . $count . ')' . $suffix;
222             $count++;
223         }
224         return false;
225     }
227     public function instance_sanity_check() {
228         if (!$this->get_config('apikey')) {
229             return 'err_noapikey';
230         }
231     //@TODO see if we can verify the api key without actually getting an authentication token
232     }
234     public static function allows_multiple() {
235         return false;
236     }