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