Merge branch 'MDL-61970-master' of git://github.com/FMCorz/moodle
[moodle.git] / portfolio / boxnet / lib.php
1 <?php
2 require_once($CFG->libdir.'/portfolio/plugin.php');
3 require_once($CFG->libdir.'/filelib.php');
4 require_once($CFG->libdir.'/boxlib.php');
6 class portfolio_plugin_boxnet extends portfolio_plugin_push_base {
8     public $boxclient;
9     private $ticket;
10     private $authtoken;
11     private $folders;
12     private $accounttree;
14     public static function get_name() {
15         return get_string('pluginname', 'portfolio_boxnet');
16     }
18     public function prepare_package() {
19         // don't do anything for this plugin, we want to send all files as they are.
20     }
22     public function send_package() {
23         // if we need to create the folder, do it now
24         if ($newfolder = $this->get_export_config('newfolder')) {
25             $created = $this->boxclient->create_folder($newfolder);
26             if (empty($created->id)) {
27                 throw new portfolio_plugin_exception('foldercreatefailed', 'portfolio_boxnet');
28             }
29             $this->folders[$created->id] = $created->name;
30             $this->set_export_config(array('folder' => $created->id));
31         }
32         foreach ($this->exporter->get_tempfiles() as $file) {
33             $return = $this->boxclient->upload_file($file, $this->get_export_config('folder'));
34             if (!empty($result->type) && $result->type == 'error') {
35                 throw new portfolio_plugin_exception('sendfailed', 'portfolio_boxnet', $result->message);
36             }
37             $createdfile = reset($return->entries);
38             if (!empty($createdfile->id)) {
39                 $result = $this->rename_file($createdfile->id, $file->get_filename());
40                 // If this fails, the file was sent but not renamed.
41             }
42         }
43     }
45     public function get_export_summary() {
46         $allfolders = $this->get_folder_list();
47         if ($newfolder = $this->get_export_config('newfolder')) {
48             $foldername = $newfolder . ' (' . get_string('tobecreated', 'portfolio_boxnet') . ')';
49         } else if ($this->get_export_config('folder')) {
50             $foldername = $allfolders[$this->get_export_config('folder')];
51         } else {
52             $foldername = '/';
53         }
54         return array(
55             get_string('targetfolder', 'portfolio_boxnet') => s($foldername)
56         );
57     }
59     public function get_interactive_continue_url() {
60         return 'https://app.box.net/files/0/f/' . $this->get_export_config('folder') . '/';
61     }
63     public function expected_time($callertime) {
64         // We're forcing this to be run 'interactively' because the plugin
65         // does not support running in cron.
66         return PORTFOLIO_TIME_LOW;
67     }
69     public static function has_admin_config() {
70         return true;
71     }
73     public static function get_allowed_config() {
74         return array('clientid', 'clientsecret');
75     }
77     public function has_export_config() {
78         return true;
79     }
81     public function get_allowed_export_config() {
82         return array('folder', 'newfolder');
83     }
85     public function export_config_form(&$mform) {
86         $folders = $this->get_folder_list();
87         $mform->addElement('text', 'plugin_newfolder', get_string('newfolder', 'portfolio_boxnet'));
88         $mform->setType('plugin_newfolder', PARAM_RAW);
89         $folders[0] = '/';
90         ksort($folders);
91         $mform->addElement('select', 'plugin_folder', get_string('existingfolder', 'portfolio_boxnet'), $folders);
92     }
94     public function export_config_validation(array $data) {
95         $allfolders = $this->get_folder_list();
96         if (in_array($data['plugin_newfolder'], $allfolders)) {
97             return array('plugin_newfolder' => get_string('folderclash', 'portfolio_boxnet'));
98         }
99     }
101     public static function admin_config_form(&$mform) {
102         global $CFG;
104         $mform->addElement('text', 'clientid', get_string('clientid', 'portfolio_boxnet'));
105         $mform->addRule('clientid', get_string('required'), 'required', null, 'client');
106         $mform->setType('clientid', PARAM_RAW_TRIMMED);
108         $mform->addElement('text', 'clientsecret', get_string('clientsecret', 'portfolio_boxnet'));
109         $mform->addRule('clientsecret', get_string('required'), 'required', null, 'client');
110         $mform->setType('clientsecret', PARAM_RAW_TRIMMED);
112         $a = new stdClass();
113         $a->servicesurl = 'https://app.box.com/developers/services';
114         $mform->addElement('static', 'setupinfo', get_string('setupinfo', 'portfolio_boxnet'),
115             get_string('setupinfodetails', 'portfolio_boxnet', $a));
117         if (!is_https()) {
118             $mform->addElement('static', 'warninghttps', '', get_string('warninghttps', 'portfolio_boxnet'));
119         }
120     }
122     public function steal_control($stage) {
123         if ($stage != PORTFOLIO_STAGE_CONFIG) {
124             return false;
125         }
126         if (empty($this->boxclient)) {
127             $returnurl = new moodle_url('/portfolio/add.php', array('postcontrol' => 1, 'type' => 'boxnet',
128                 'sesskey' => sesskey()));
129             $this->boxclient = new boxnet_client($this->get_config('clientid'), $this->get_config('clientsecret'), $returnurl, '');
130         }
131         if ($this->boxclient->is_logged_in()) {
132             return false;
133         }
134         return $this->boxclient->get_login_url();
135     }
137     public function post_control($stage, $params) {
138         if ($stage != PORTFOLIO_STAGE_CONFIG) {
139             return;
140         }
141         if (!$this->boxclient->is_logged_in()) {
142             throw new portfolio_plugin_exception('noauthtoken', 'portfolio_boxnet');
143         }
144     }
146     /**
147      * Get the folder list.
148      *
149      * This is limited to the folders in the root folder.
150      *
151      * @return array of folders.
152      */
153     protected function get_folder_list() {
154         if (empty($this->folders)) {
155             $folders = array();
156             $result = $this->boxclient->get_folder_items();
157             foreach ($result->entries as $item) {
158                 if ($item->type != 'folder') {
159                     continue;
160                 }
161                 $folders[$item->id] = $item->name;
162                 if (!empty($item->shared)) {
163                     $folders[$item->id] .= ' (' . get_string('sharedfolder', 'portfolio_boxnet') . ')';
164                 }
165             }
166             $this->folders = $folders;
167         }
168         return $this->folders;
169     }
171     /**
172      * Rename a file.
173      *
174      * If the name is already taken, we append the current date to the file
175      * to prevent name conflicts.
176      *
177      * @param int $fileid The file ID.
178      * @param string $newname The new name.
179      * @return bool Whether it succeeded or not.
180      */
181     protected function rename_file($fileid, $newname) {
182         $result = $this->boxclient->rename_file($fileid, $newname);
183         if (!empty($result->type) && $result->type == 'error') {
184             $bits = explode('.', $newname);
185             $suffix = '';
186             if (count($bits) == 1) {
187                 $prefix = $newname;
188             } else {
189                 $suffix = '.' . array_pop($bits);
190                 $prefix = implode('.', $bits);
191             }
192             $newname = $prefix . ' (' . date('Y-m-d H-i-s') . ')' . $suffix;
193             $result = $this->boxclient->rename_file($fileid, $newname);
194             if (empty($result->type) || $result->type != 'error') {
195                 return true;
196             } else {
197                 // We could not rename the file for some reason...
198                 debugging('Error while renaming the file on Box.net', DEBUG_DEVELOPER);
199             }
200         } else {
201             return true;
202         }
203         return false;
204     }
206     public function instance_sanity_check() {
207         global $CFG;
208         if (!$this->get_config('clientid') || !$this->get_config('clientsecret')) {
209             return 'missingoauthkeys';
210         } else if (!is_https()) {
211             return 'missinghttps';
212         }
213     }
215     public static function allows_multiple_instances() {
216         return false;
217     }
219     public function supported_formats() {
220         return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML);
221     }
223     /*
224      * for now , boxnet doesn't support this,
225      * because we can't dynamically construct return urls.
226      */
227     public static function allows_multiple_exports() {
228         return false;
229     }