Commit 0a5d3873 authored by cescobedo's avatar cescobedo
Browse files

MDL-72615 core: Remove boxnet portfolio and repository

parent 2b2897bf
......@@ -5378,7 +5378,7 @@ class restore_process_file_aliases_queue extends restore_execution_step {
}
} else {
// This is a reference to some external file such as in boxnet or dropbox.
// This is a reference to some external file such as dropbox.
// If we are restoring to the same site, keep the reference untouched and
// restore the alias as is.
if ($this->task->is_samesite()) {
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Box.net client.
*
* @package core
* @author James Levy <james@box.net>
* @link http://enabled.box.net
* @access public
* @version 1.0
* @copyright copyright Box.net 2007
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/oauthlib.php');
/**
* Box.net client class.
*
* @package core
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class boxnet_client extends oauth2_client {
/** @const API URL */
const API = 'https://api.box.com/2.0';
/** @const UPLOAD_API URL */
const UPLOAD_API = 'https://upload.box.com/api/2.0';
/**
* Return authorize URL.
*
* @return string
*/
protected function auth_url() {
return 'https://www.box.com/api/oauth2/authorize';
}
/**
* Create a folder.
*
* @param string $foldername The folder name.
* @param int $parentid The ID of the parent folder.
* @return array Information about the new folder.
*/
public function create_folder($foldername, $parentid = 0) {
$params = array('name' => $foldername, 'parent' => array('id' => (string) $parentid));
$this->reset_state();
$result = $this->post($this->make_url("/folders"), json_encode($params));
$result = json_decode($result);
return $result;
}
/**
* Download the file.
*
* @param int $fileid File ID.
* @param string $path Path to download the file to.
* @return bool Success or not.
*/
public function download_file($fileid, $path) {
$this->reset_state();
$result = $this->download_one($this->make_url("/files/$fileid/content"), array(),
array('filepath' => $path, 'CURLOPT_FOLLOWLOCATION' => true));
return ($result === true && $this->info['http_code'] === 200);
}
/**
* Get info of a file.
*
* @param int $fileid File ID.
* @return object
*/
public function get_file_info($fileid) {
$this->reset_state();
$result = $this->request($this->make_url("/files/$fileid"));
return json_decode($result);
}
/**
* Get a folder content.
*
* @param int $folderid Folder ID.
* @return object
*/
public function get_folder_items($folderid = 0) {
$this->reset_state();
$result = $this->request($this->make_url("/folders/$folderid/items",
array('fields' => 'id,name,type,modified_at,size,owned_by')));
return json_decode($result);
}
/**
* Log out.
*
* @return void
*/
public function log_out() {
if ($accesstoken = $this->get_accesstoken()) {
$params = array(
'client_id' => $this->get_clientid(),
'client_secret' => $this->get_clientsecret(),
'token' => $accesstoken->token
);
$this->reset_state();
$this->post($this->revoke_url(), $params);
}
parent::log_out();
}
/**
* Build a request URL.
*
* @param string $uri The URI to request.
* @param array $params Query string parameters.
* @param bool $uploadapi Whether this works with the upload API or not.
* @return string
*/
protected function make_url($uri, $params = array(), $uploadapi = false) {
$api = $uploadapi ? self::UPLOAD_API : self::API;
$url = new moodle_url($api . '/' . ltrim($uri, '/'), $params);
return $url->out(false);
}
/**
* Rename a file.
*
* @param int $fileid The file ID.
* @param string $newname The new file name.
* @return object Box.net file object.
*/
public function rename_file($fileid, $newname) {
// This requires a PUT request with data within it. We cannot use
// the standard PUT request 'CURLOPT_PUT' because it expects a file.
$data = array('name' => $newname);
$options = array(
'CURLOPT_CUSTOMREQUEST' => 'PUT',
'CURLOPT_POSTFIELDS' => json_encode($data)
);
$url = $this->make_url("/files/$fileid");
$this->reset_state();
$result = $this->request($url, $options);
$result = json_decode($result);
return $result;
}
/**
* Resets curl for multiple requests.
*
* @return void
*/
public function reset_state() {
$this->cleanopt();
$this->resetHeader();
}
/**
* Return the revoke URL.
*
* @return string
*/
protected function revoke_url() {
return 'https://www.box.com/api/oauth2/revoke';
}
/**
* Share a file and return the link to it.
*
* @param string $fileid The file ID.
* @param bool $businesscheck Whether or not to check if the user can share files, has a business account.
* @return object
*/
public function share_file($fileid, $businesscheck = true) {
// Sharing the file, this requires a PUT request with data within it. We cannot use
// the standard PUT request 'CURLOPT_PUT' because it expects a file.
$data = array('shared_link' => array('access' => 'open', 'permissions' =>
array('can_download' => true, 'can_preview' => true)));
$options = array(
'CURLOPT_CUSTOMREQUEST' => 'PUT',
'CURLOPT_POSTFIELDS' => json_encode($data)
);
$this->reset_state();
$result = $this->request($this->make_url("/files/$fileid"), $options);
$result = json_decode($result);
if ($businesscheck) {
// Checks that the user has the right to share the file. If not, throw an exception.
$this->reset_state();
$this->head($result->shared_link->download_url);
$info = $this->get_info();
if ($info['http_code'] == 403) {
throw new moodle_exception('No permission to share the file');
}
}
return $result->shared_link;
}
/**
* Search.
*
* @return object
*/
public function search($query) {
$this->reset_state();
$result = $this->request($this->make_url('/search', array('query' => $query, 'limit' => 50, 'offset' => 0)));
return json_decode($result);
}
/**
* Return token URL.
*
* @return string
*/
protected function token_url() {
return 'https://www.box.com/api/oauth2/token';
}
/**
* Upload a file.
*
* Please note that the file is named on Box.net using the path we are providing, and so
* the file has the name of the stored_file hash.
*
* @param stored_file $storedfile A stored_file.
* @param integer $parentid The ID of the parent folder.
* @return object Box.net file object.
*/
public function upload_file(stored_file $storedfile, $parentid = 0) {
$url = $this->make_url('/files/content', array(), true);
$options = array(
'filename' => $storedfile,
'parent_id' => $parentid
);
$this->reset_state();
$result = $this->post($url, $options);
$result = json_decode($result);
return $result;
}
}
/**
* @deprecated since 2.6, 2.5.3, 2.4.7
*/
class boxclient {
public function __construct() {
throw new coding_exception(__CLASS__ . ' has been removed. Please update your code to use boxnet_client.',
DEBUG_DEVELOPER);
}
}
......@@ -1733,12 +1733,12 @@ class core_plugin_manager {
'enrol' => array('authorize'),
'filter' => array('censor'),
'media' => array('swf'),
'portfolio' => array('picasa'),
'portfolio' => array('picasa', 'boxnet'),
'qformat' => array('webct'),
'message' => array('jabber'),
'quizaccess' => array('safebrowser'),
'report' => array('search'),
'repository' => array('alfresco', 'picasa', 'skydrive'),
'repository' => array('alfresco', 'picasa', 'skydrive', 'boxnet'),
'tinymce' => array('dragmath'),
'tool' => array('bloglevelupgrade', 'qeupgradehelper', 'timezoneimport', 'assignmentupgrade', 'health'),
'theme' => array('bootstrapbase', 'clean', 'more', 'afterburner', 'anomaly', 'arialist', 'base',
......@@ -1942,7 +1942,7 @@ class core_plugin_manager {
),
'portfolio' => array(
'boxnet', 'download', 'flickr', 'googledocs', 'mahara'
'download', 'flickr', 'googledocs', 'mahara'
),
'profilefield' => array(
......@@ -2002,7 +2002,7 @@ class core_plugin_manager {
),
'repository' => array(
'areafiles', 'boxnet', 'contentbank', 'coursefiles', 'dropbox', 'equella', 'filesystem',
'areafiles', 'contentbank', 'coursefiles', 'dropbox', 'equella', 'filesystem',
'flickr', 'flickr_public', 'googledocs', 'local', 'merlot', 'nextcloud',
'onedrive', 'recent', 's3', 'upload', 'url', 'user', 'webdav',
'wikimedia', 'youtube'
......
......@@ -3010,5 +3010,48 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021101900.01);
}
if ($oldversion < 2021102600.01) {
// If portfolio_boxnet is no longer present, remove it.
if (!file_exists($CFG->dirroot . '/portfolio/boxnet/version.php')) {
$instance = $DB->get_record('portfolio_instance', ['plugin' => 'boxnet']);
if (!empty($instance)) {
// Remove all records from portfolio_instance_config.
$DB->delete_records('portfolio_instance_config', ['instance' => $instance->id]);
// Remove all records from portfolio_instance_user.
$DB->delete_records('portfolio_instance_user', ['instance' => $instance->id]);
// Remove all records from portfolio_log.
$DB->delete_records('portfolio_log', ['portfolio' => $instance->id]);
// Remove all records from portfolio_tempdata.
$DB->delete_records('portfolio_tempdata', ['instance' => $instance->id]);
// Remove the record from the portfolio_instance table.
$DB->delete_records('portfolio_instance', ['id' => $instance->id]);
}
// Clean config.
unset_all_config_for_plugin('portfolio_boxnet');
}
// If repository_boxnet is no longer present, remove it.
if (!file_exists($CFG->dirroot . '/repository/boxnet/version.php')) {
$instance = $DB->get_record('repository', ['type' => 'boxnet']);
if (!empty($instance)) {
// Remove all records from repository_instance_config table.
$DB->delete_records('repository_instance_config', ['instanceid' => $instance->id]);
// Remove all records from repository_instances table.
$DB->delete_records('repository_instances', ['typeid' => $instance->id]);
// Remove the record from the repository table.
$DB->delete_records('repository', ['id' => $instance->id]);
}
// Clean config.
unset_all_config_for_plugin('repository_boxnet');
// Remove orphaned files.
upgrade_delete_orphaned_file_records();
}
upgrade_main_savepoint(true, 2021102600.01);
}
return true;
}
......@@ -208,7 +208,7 @@ abstract class portfolio_plugin_base {
* Eg: things that your subclasses want to keep in state
* across the export.
* Keys must be in get_allowed_export_config
* This is deliberately not final (see boxnet plugin)
* This is deliberately not final (see googledocs plugin)
* @see get_allowed_export_config
*
* @param array $config named array of config items to set.
......@@ -402,7 +402,7 @@ abstract class portfolio_plugin_base {
* and the request (get and post but not cookie) parameters.
* This is useful for external systems that need to redirect the user back
* with some extra data in the url (like auth tokens etc)
* for an example implementation, see boxnet portfolio plugin.
* for an example implementation, see googledocs portfolio plugin.
*
* @param int $stage the stage before control was stolen
* @param array $params a merge of $_GET and $_POST
......
......@@ -2,6 +2,7 @@ This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
=== 4.0 ===
* Since Boxnet has been remove from core then boxnet_client() class has been removed from core too.
* New navigation classes to mimic the new navigation project. The existing navigation callbacks are still available and
will be called. The following behaviour will be the new standard for nodes added via callbacks:
- Module nodes added will be appended to the end and will appear within the hamburger option.
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy class for requesting user data.
*
* @package portfolio_boxnet
* @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace portfolio_boxnet\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\metadata\collection;
/**
* Provider for the portfolio_boxnet plugin.
*
* @copyright 2018 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
// This portfolio plugin does not store any data itself.
// It has no database tables, and it purely acts as a conduit, sending data externally.
\core_privacy\local\metadata\provider,
\core_portfolio\privacy\portfolio_provider {
/**
* Returns meta data about this system.
*
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection) : collection {
return $collection->add_external_location_link('box.net', ['data' => 'privacy:metadata:data'],
'privacy:metadata');
}
/**
* Export all portfolio data from each portfolio plugin for the specified userid and context.
*
* @param int $userid The user to export.
* @param \context $context The context to export.
* @param array $subcontext The subcontext within the context to export this information to.
* @param array $linkarray The weird and wonderful link array used to display information for a specific item
*/
public static function export_portfolio_user_data(int $userid, \context $context, array $subcontext, array $linkarray) {
}
/**
* Delete all user information for the provided context.
*
* @param \context $context The context to delete user data for.
*/
public static function delete_portfolio_for_context(\context $context) {
}
/**
* Delete all user information for the provided user and context.
*
* @param int $userid The user to delete
* @param \context $context The context to refine the deletion.
*/
public static function delete_portfolio_for_user(int $userid, \context $context) {
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Upgrade.
*
* @package portfolio_boxnet
* @copyright 2013 Frédéric Massart
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Upgrade function.
*
* @param int $oldversion the version we are upgrading from.
* @return bool result
*/
function xmldb_portfolio_boxnet_upgrade($oldversion) {
global $CFG;
// Automatically generated Moodle v3.6.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.7.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.8.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v3.9.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'portfolio_boxnet', language 'en', branch 'MOODLE_20_STABLE'
*
* @package portfolio_boxnet
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['clientid'] = 'Client ID';
$string['clientsecret'] = 'Client secret';
$string['existingfolder'] = 'Existing folder to put file(s) into';
$string['folderclash'] = 'The folder you asked to create already exists!';
$string['foldercreatefailed'] = 'Failed to create your target folder on Box';
$string['folderlistfailed'] = 'Failed to retrieve a folder listing from Box';
$string['missinghttps'] = 'HTTPS required';
$string['missinghttps_help'] = 'Box will only work with an HTTPS enabled website.';
$string['missingoauthkeys'] = 'Missing client ID and secret';
$string['missingoauthkeys_help'] = 'There is no client ID or secret configured for this plugin. You can get one of these from Box development page.';
$string['newfolder'] = 'New folder to put file(s) into';
$string['noauthtoken'] = 'Could not retrieve an authentication token for use in this session';
$string['notarget'] = 'You must specify either an existing folder or a new folder to upload into';
$string['noticket'] = 'Could not retrieve a ticket from Box to begin the authentication session';
$string['password'] = 'Your Box password (will not be stored)';
$string['pluginname'] = 'Box';
$string['privacy:metadata'] = 'This plugin sends data externally to a linked Box account. It does not store data locally.';
$string['privacy:metadata:data'] = 'Personal data passed through from the portfolio subsystem.';
$string['sendfailed'] = 'Failed to send content to Box: {$a}';
$string['setupinfo'] = 'Setup instructions';
$string['setupinfodetails'] = 'To obtain a client ID and secret, log in to Box and visit the <a href="{$a->servicesurl}">Box developers page</a>. Follow \'Create new application\' and create a new application for your Moodle site. The client ID and secret are displayed in the \'OAuth2 parameters\' section of the application edit form. Optionally, you can also provide other information about your Moodle site.';
$string['sharedfolder'] = 'Shared';
$string['sharefile'] = 'Share this file?';
$string['sharefolder'] = 'Share this new folder?';
$string['targetfolder'] = 'Target folder';
$string['tobecreated'] = 'To be created';
$string['username'] = 'Your Box username (will not be stored)';
$string['warninghttps'] = 'Box requires your website to be using HTTPS in order for the portfolio to work.';
<?php
require_once($CFG->libdir.'/portfolio/plugin.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/boxlib.php');
class portfolio_plugin_boxnet extends portfolio_plugin_push_base {
public $boxclient;
private $ticket;
private $authtoken;
private $folders;
private $accounttree;
public static function get_name() {
return get_string('pluginname', 'portfolio_boxnet');
}
public function prepare_package() {
// don't do anything for this plugin, we want to send all files as they are.
}
public function send_package() {
// if we need to create the folder, do it now
if ($newfolder = $this->get_export_config('newfolder')) {
$created = $this->boxclient->create_folder($newfolder);
if (empty($created->id)) {
throw new portfolio_plugin_exception('foldercreatefailed', 'portfolio_boxnet');
}
$this->folders[$created->id] = $created->name;
$this->set_export_config(array('folder' => $created->id));
}
foreach ($this->exporter->get_tempfiles() as $file) {
$return = $this->boxclient->upload_file($file, $this->get_export_config('folder'));
if (!empty($result->type) && $result->type == 'error') {
throw new portfolio_plugin_exception('sendfailed', 'portfolio_boxnet', $result->message);
}
$createdfile = reset($return->entries);
if (!empty($createdfile->id)) {
$result = $this->rename_file($createdfile->id, $file->get_filename());
// If this fails, the file was sent but not renamed.
}
}
}
public function get_export_summary() {
$allfolders = $this->get_folder_list();
if ($newfolder = $this->get_export_config('newfolder')) {
$foldername = $newfolder . ' (' . get_string('tobecreated', 'portfolio_boxnet') . ')';