1<?php 2require_once($CFG->libdir.'/portfolio/plugin.php'); 3require_once($CFG->libdir.'/filelib.php'); 4require_once($CFG->libdir.'/boxlib.php'); 5 6class portfolio_plugin_boxnet extends portfolio_plugin_push_base { 7 8 public $boxclient; 9 private $ticket; 10 private $authtoken; 11 private $folders; 12 private $accounttree; 13 14 public static function get_name() { 15 return get_string('pluginname', 'portfolio_boxnet'); 16 } 17 18 public function prepare_package() { 19 // don't do anything for this plugin, we want to send all files as they are. 20 } 21 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 } 44 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 } 58 59 public function get_interactive_continue_url() { 60 return 'https://app.box.net/files/0/f/' . $this->get_export_config('folder') . '/'; 61 } 62 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 } 68 69 public static function has_admin_config() { 70 return true; 71 } 72 73 public static function get_allowed_config() { 74 return array('clientid', 'clientsecret'); 75 } 76 77 public function has_export_config() { 78 return true; 79 } 80 81 public function get_allowed_export_config() { 82 return array('folder', 'newfolder'); 83 } 84 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 } 93 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 } 100 101 public static function admin_config_form(&$mform) { 102 global $CFG; 103 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); 107 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); 111 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)); 116 117 if (!is_https()) { 118 $mform->addElement('static', 'warninghttps', '', get_string('warninghttps', 'portfolio_boxnet')); 119 } 120 } 121 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 } 136 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 } 145 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 } 170 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 } 205 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 } 214 215 public static function allows_multiple_instances() { 216 return false; 217 } 218 219 public function supported_formats() { 220 return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML); 221 } 222 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 } 230} 231