Merge branch 'MDL-42666-master-fixup' of git://github.com/FMCorz/moodle
[moodle.git] / portfolio / boxnet / lib.php
CommitLineData
b3abd2c6 1<?php
f675815e 2require_once($CFG->libdir.'/portfolio/plugin.php');
67a87e7d 3require_once($CFG->libdir.'/filelib.php');
615a2859 4require_once($CFG->libdir.'/boxlib.php');
67a87e7d 5
d96a1acc 6class portfolio_plugin_boxnet extends portfolio_plugin_push_base {
67a87e7d 7
7e95408b 8 public $boxclient;
67a87e7d 9 private $ticket;
10 private $authtoken;
67a87e7d 11 private $folders;
a226b58d 12 private $accounttree;
67a87e7d 13
0f71f48b 14 public static function get_name() {
15 return get_string('pluginname', 'portfolio_boxnet');
16 }
17
d67bfc32 18 public function prepare_package() {
13e7e765 19 // don't do anything for this plugin, we want to send all files as they are.
20 }
21
22 public function send_package() {
53aa4841 23 // if we need to create the folder, do it now
24 if ($newfolder = $this->get_export_config('newfolder')) {
5d37f13c 25 if (!$created = $this->boxclient->createFolder($newfolder, array('share' => (int)$this->get_export_config('sharefolder')))) {
53aa4841 26 throw new portfolio_plugin_exception('foldercreatefailed', 'portfolio_boxnet');
27 }
2e6a355d 28 $this->folders[$created['folder_id']] = $created['folder_name'];
53aa4841 29 $this->set_export_config(array('folder' => $created['folder_id']));
30 }
d67bfc32 31 foreach ($this->exporter->get_tempfiles() as $file) {
32 $return = $this->boxclient->uploadFile(
67a87e7d 33 array(
34 'file' => $file,
53aa4841 35 'folder_id' => $this->get_export_config('folder'),
fd64f098 36 'share' => $this->get_export_config('sharefile'),
67a87e7d 37 )
38 );
d67bfc32 39 if (array_key_exists('status', $return) && $return['status'] == 'upload_ok'
c31dc0b6
FM
40 && array_key_exists('id', $return) && count($return['id']) == 1) {
41 $returnid = array_keys($return['id']);
42 $this->rename_file($return['id'][array_pop($returnid)], $file->get_filename());
37f03ea0 43 // if this fails, the file was sent but not renamed - this triggers a warning but is not fatal.
d67bfc32 44 }
67a87e7d 45 }
46 if ($this->boxclient->isError()) {
37f03ea0 47 throw new portfolio_plugin_exception('sendfailed', 'portfolio_boxnet', $this->boxclient->getErrorMsg());
67a87e7d 48 }
67a87e7d 49 }
50
67a87e7d 51 public function get_export_summary() {
52 $allfolders = $this->get_folder_list();
53aa4841 53 if ($newfolder = $this->get_export_config('newfolder')) {
54 $foldername = $newfolder . ' (' . get_string('tobecreated', 'portfolio_boxnet') . ')';
447192d3 55 } elseif ($this->get_export_config('folder')) {
53aa4841 56 $foldername = $allfolders[$this->get_export_config('folder')];
447192d3 57 } else {
58 $foldername = '';
53aa4841 59 }
67a87e7d 60 return array(
53aa4841 61 get_string('targetfolder', 'portfolio_boxnet') => $foldername
67a87e7d 62 );
63 }
64
5d0dbf13 65 public function get_interactive_continue_url() {
67a87e7d 66 return 'http://box.net/files#0:f:' . $this->get_export_config('folder');
67 }
68
69 public function expected_time($callertime) {
70 return $callertime;
71 }
72
73 public static function has_admin_config() {
74 return true;
75 }
76
77 public static function get_allowed_config() {
78 return array('apikey');
79 }
80
81 public function has_export_config() {
82 return true;
83 }
84
85 public function get_allowed_user_config() {
86 return array('authtoken', 'authtokenctime');
87 }
88
89 public function get_allowed_export_config() {
fd64f098 90 return array('folder', 'newfolder', 'sharefile', 'sharefolder');
67a87e7d 91 }
92
93 public function export_config_form(&$mform) {
94 $folders = $this->get_folder_list();
fd64f098 95 $mform->addElement('checkbox', 'plugin_sharefile', get_string('sharefile', 'portfolio_boxnet'));
67a87e7d 96 $mform->addElement('text', 'plugin_newfolder', get_string('newfolder', 'portfolio_boxnet'));
22138937 97 $mform->setType('plugin_newfolder', PARAM_RAW);
fd64f098 98 $mform->addElement('checkbox', 'plugin_sharefolder', get_string('sharefolder', 'portfolio_boxnet'));
447192d3 99 $folders[0] = '----';
100 ksort($folders);
101 $mform->addElement('select', 'plugin_folder', get_string('existingfolder', 'portfolio_boxnet'), $folders);
67a87e7d 102 }
103
caee6e6c 104 public function export_config_validation(array $data) {
67a87e7d 105 $allfolders = $this->get_folder_list();
106 if (in_array($data['plugin_newfolder'], $allfolders)) {
107 return array('plugin_newfolder' => get_string('folderclash', 'portfolio_boxnet'));
108 }
109 }
110
c17ec774 111 public static function admin_config_form(&$mform) {
89e12bd5 112 global $CFG;
ff347f99 113
eefb011d
DM
114 $mform->addElement('text', 'apikey', get_string('apikey', 'portfolio_boxnet'));
115 $mform->addRule('apikey', get_string('required'), 'required', null, 'client');
962b1baf 116 $mform->setType('apikey', PARAM_RAW_TRIMMED);
eefb011d
DM
117 $a = new stdClass();
118 $a->servicesurl = 'http://www.box.net/developers/services';
119 $a->callbackurl = $CFG->wwwroot . '/portfolio/add.php?postcontrol=1&type=boxnet';
120 $mform->addElement('static', 'setupinfo', get_string('setupinfo', 'portfolio_boxnet'),
121 get_string('setupinfodetails', 'portfolio_boxnet', $a));
67a87e7d 122 }
123
124 public function steal_control($stage) {
125 if ($stage != PORTFOLIO_STAGE_CONFIG) {
126 return false;
127 }
128 if ($this->authtoken) {
129 return false;
130 }
131 if (!$this->ensure_ticket()) {
34035201 132 throw new portfolio_plugin_exception('noticket', 'portfolio_boxnet');
67a87e7d 133 }
134 $token = $this->get_user_config('authtoken', $this->get('user')->id);
135 $ctime= $this->get_user_config('authtokenctime', $this->get('user')->id);
136 if (!empty($token) && (($ctime + 60*60*20) > time())) {
137 $this->authtoken = $token;
138 $this->boxclient->auth_token = $token;
139 return false;
140 }
141 return 'http://www.box.net/api/1.0/auth/'.$this->ticket;
142 }
143
144 public function post_control($stage, $params) {
145 if ($stage != PORTFOLIO_STAGE_CONFIG) {
146 return;
147 }
148 if (!array_key_exists('auth_token', $params) || empty($params['auth_token'])) {
34035201 149 throw new portfolio_plugin_exception('noauthtoken', 'portfolio_boxnet');
67a87e7d 150 }
151 $this->authtoken = $params['auth_token'];
152 $this->boxclient->auth_token = $this->authtoken;
153 $this->set_user_config(array('authtoken' => $this->authtoken, 'authtokenctime' => time()), $this->get('user')->id);
154 }
155
156 private function ensure_ticket() {
157 if (!empty($this->boxclient)) {
158 return true;
159 }
160 $this->boxclient = new boxclient($this->get_config('apikey'), '');
161 $ticket_return = $this->boxclient->getTicket();
162 if ($this->boxclient->isError() || empty($ticket_return)) {
34035201 163 throw new portfolio_plugin_exception('noticket', 'portfolio_boxnet');
67a87e7d 164 }
165 $this->ticket = $ticket_return['ticket'];
8801ab06 166 return $this->ticket;
67a87e7d 167 }
168
a226b58d 169 private function ensure_account_tree() {
170 if (!empty($this->accounttree)) {
171 return;
67a87e7d 172 }
173 if (empty($this->ticket)
174 || empty($this->authtoken)
175 || empty($this->boxclient)) {
176 // if we don't have these we're pretty much screwed
34035201 177 throw new portfolio_plugin_exception('folderlistfailed', 'portfolio_boxnet');
67a87e7d 178 return false;
179 }
a226b58d 180 $this->accounttree = $this->boxclient->getAccountTree();
67a87e7d 181 if ($this->boxclient->isError()) {
34035201 182 throw new portfolio_plugin_exception('folderlistfailed', 'portfolio_boxnet');
67a87e7d 183 }
a226b58d 184 if (!is_array($this->accounttree)) {
67a87e7d 185 return false;
186 }
a226b58d 187 }
188
189 private function get_folder_list() {
190 if (!empty($this->folders)) {
191 return $this->folders;
192 }
193 $this->ensure_account_tree();
67a87e7d 194 $folders = array();
a226b58d 195 foreach ($this->accounttree['folder_id'] as $key => $id) {
67a87e7d 196 if (empty($id)) {
197 continue;
198 }
a226b58d 199 $name = $this->accounttree['folder_name'][$key];
200 if (!empty($this->accounttree['shared'][$key])) {
67a87e7d 201 $name .= ' (' . get_string('sharedfolder', 'portfolio_boxnet') . ')';
202 }
203 $folders[$id] = $name;
204 }
205 $this->folders = $folders;
206 return $folders;
207 }
208
a226b58d 209 private function rename_file($fileid, $newname) {
210 // look at moving this to the boxnet client class
211 $this->ensure_account_tree();
212 $count = 1;
213 $bits = explode('.', $newname);
214 $suffix = '';
215 if (count($bits) == 1) {
68b7eed0 216 $prefix = $newname;
a226b58d 217 } else {
218 $suffix = '.' . array_pop($bits);
219 $prefix = implode('.', $bits);
220 }
221 while (true) {
899ffdfb 222 if (!array_key_exists('file_name', $this->accounttree) || !in_array($newname, $this->accounttree['file_name'])) {
9b69a0ce 223 for ($i = 0; $i < 2; $i++) {
224 if ($this->boxclient->renameFile($fileid, $newname)) {
225 return true;
226 }
227 }
228 debugging("tried three times to rename file and failed");
229 return false;
a226b58d 230 }
231 $newname = $prefix . '(' . $count . ')' . $suffix;
232 $count++;
233 }
234 return false;
235 }
236
67a87e7d 237 public function instance_sanity_check() {
238 if (!$this->get_config('apikey')) {
239 return 'err_noapikey';
240 }
241 //@TODO see if we can verify the api key without actually getting an authentication token
242 }
2f68e760 243
384ba38a 244 public static function allows_multiple_instances() {
2f68e760 245 return false;
246 }
62e71954 247
38652d90 248 public function supported_formats() {
24b69846 249 return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML);
62e71954 250 }
bd39808b
PL
251
252 /*
253 * for now , boxnet doesn't support this,
254 * because we can't dynamically construct return urls.
255 */
256 public static function allows_multiple_exports() {
257 return false;
258 }
67a87e7d 259}