: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Get thumbnail from OneDrive.com.
* @return string | boolean
protected function _od_getThumbnail($path)
list(, $itemId) = $this->_od_splitPath($path);
$url = self::API_URL . $itemId . '/thumbnails/0/medium/content';
return $this->_od_createCurl($url, $contents = true);
* Upload large files with an upload session.
* @param resource $fp source file pointer
* @param number $size total size
* @param string $name item name
* @param string $itemId item identifier
* @param string $parent parent
* @param string $parentId parent identifier
* @return string The item path
protected function _od_uploadSession($fp, $size, $name, $itemId, $parent, $parentId)
$send = $this->_od_getChunkData($fp);
throw new Exception('Data can not be acquired from the source.');
$url = self::API_URL . $itemId . '/createUploadSession';
$url = self::API_URL . $parentId . ':/' . rawurlencode($name) . ':/createUploadSession';
$curl = $this->_od_prepareCurl($url);
curl_setopt_array($curl, array(
CURLOPT_POSTFIELDS => '{}',
$sess = json_decode(elFinder::curlExec($curl));
if (isset($sess->error)) {
throw new Exception($sess->error->message);
$range = '0-' . ($next - 1) . '/' . $size;
throw new Exception('API response can not be obtained.');
elFinder::extendTimeLimit();
CURLOPT_RETURNTRANSFER => true,
CURLOPT_INFILE => $putFp,
CURLOPT_INFILESIZE => $_size,
CURLOPT_HTTPHEADER => array(
'Content-Length: ' . $_size,
'Content-Range: bytes ' . $range,
curl_setopt_array($curl, $options);
$sess = json_decode(elFinder::curlExec($curl));
if (isset($sess->error)) {
throw new Exception($sess->error->message);
if (isset($sess->nextExpectedRanges)) {
list($_next) = explode('-', $sess->nextExpectedRanges[0]);
$send = $this->_od_getChunkData($fp);
throw new Exception('Data can not be acquired from the source.');
$range = $_next . '-' . ($next - 1) . '/' . $size;
throw new Exception('Retry limit exceeded with uploadSession API call.');
throw new Exception('API response can not be obtained.');
return $this->_joinPath($parent, $id);
throw new Exception('An error occurred in the uploadSession API call.');
return $this->setError('OneDrive error: ' . $e->getMessage());
* Get chunk data by file pointer to upload session.
* @param resource $fp source file pointer
* @return bool|string chunked data
protected function _od_getChunkData($fp)
static $chunkSize = null;
if ($chunkSize === null) {
$mem = elFinder::getIniBytes('memory_limit');
$mem = 10485760; // 10 MiB
$mem -= memory_get_usage() - 1061548;
$mem = min($mem, 10485760);
$chunkSize = floor($mem / 327680) * 327680;
while (!feof($fp) && strlen($contents) < $chunkSize) {
$contents .= fread($fp, 8192);
* Get AccessToken file path
* @return string ( description_of_the_return_value )
protected function _od_getATokenFile()
if (!empty($this->token->data->refresh_token)) {
$tmp = elFinder::getStaticVar('commonTempPath');
$tmp = $this->getTempPath();
$aTokenFile = $tmp . DIRECTORY_SEPARATOR . $this->_od_getInitialToken() . '.otoken';
* Get Initial Token (MD5 hash)
protected function _od_getInitialToken()
return (empty($this->token->initialToken)? md5($this->options['client_id'] . (!empty($this->token->data->refresh_token)? $this->token->data->refresh_token : $this->token->data->access_token)) : $this->token->initialToken);
/*********************************************************************/
/*********************************************************************/
* Call from elFinder::netmout() before volume->mount().
* @author Raja Sharma updating for OneDrive
public function netmountPrepare($options)
if (empty($options['client_id']) && defined('ELFINDER_ONEDRIVE_CLIENTID')) {
$options['client_id'] = ELFINDER_ONEDRIVE_CLIENTID;
if (empty($options['client_secret']) && defined('ELFINDER_ONEDRIVE_CLIENTSECRET')) {
$options['client_secret'] = ELFINDER_ONEDRIVE_CLIENTSECRET;
if (isset($options['pass']) && $options['pass'] === 'reauth') {
$options['user'] = 'init';
$this->session->remove('OneDriveTokens');
if (isset($options['id'])) {
$this->session->set('nodeId', $options['id']);
} elseif ($_id = $this->session->get('nodeId')) {
$this->session->set('nodeId', $_id);
if (!empty($options['tmpPath'])) {
if ((is_dir($options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($options['tmpPath'])) {
$this->tmp = $options['tmpPath'];
if (empty($options['client_id']) || empty($options['client_secret'])) {
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
$itpCare = isset($options['code']);
$code = $itpCare? $options['code'] : (isset($_GET['code'])? $_GET['code'] : '');
if (!empty($options['id'])) {
// Obtain the token using the code received by the OneDrive API
$this->session->set('OneDriveTokens',
$this->_od_obtainAccessToken($options['client_id'], $options['client_secret'], $code, $options['id']));
'node' => $options['id'],
'json' => '{"protocol": "onedrive", "mode": "done", "reset": 1}',
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
'json' => json_encode(array(
'protocol' => 'onedrive',
return array('exit' => 'callback', 'out' => $out);
return array('exit' => true, 'body' => $out['json']);
'node' => $options['id'],
'json' => json_encode(array('error' => elFinder::ERROR_ACCESS_DENIED . ' ' . $e->getMessage())),
return array('exit' => 'callback', 'out' => $out);
} elseif (!empty($_GET['error'])) {
'node' => $options['id'],
'json' => json_encode(array('error' => elFinder::ERROR_ACCESS_DENIED)),
return array('exit' => 'callback', 'out' => $out);
if ($options['user'] === 'init') {
$this->token = $this->session->get('OneDriveTokens');
$this->_od_refreshToken();
$this->setError($e->getMessage());
$this->session->remove('OneDriveTokens');
if (empty($this->token)) {
$path = $options['path'];
$result = $this->_od_query($path, false, false, array(
'filter' => 'folder ne null',
$this->session->set('OneDriveTokens', (object)array('token' => null));
// Gets a log in URL with sufficient privileges from the OneDrive API
if (!empty($options['offline'])) {
$offline = ' offline_access';
$redirect_uri = elFinder::getConnectorUrl() . '/netmount/onedrive/' . ($options['id'] === 'elfinder'? '1' : $options['id']);
. '?client_id=' . urlencode($options['client_id'])
. '&scope=' . urlencode('files.readwrite.all' . $offline)
. '&redirect_uri=' . urlencode($redirect_uri);
return array('exit' => true, 'body' => '{msg:errAccess}');
$html = '<input id="elf-volumedriver-onedrive-host-btn" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" value="{msg:btnApprove}" type="button">';
jQuery("#' . $options['id'] . '").elfinder("instance").trigger("netmount", {protocol: "onedrive", mode: "makebtn", url: "' . $url . '"});
return array('exit' => true, 'body' => $html);
foreach ($result as $res) {
$folders[$res->id] = $res->name;
if ($options['pass'] === 'folders') {
return ['exit' => true, 'folders' => $folders];
$folders = ['root' => 'My OneDrive'] + $folders;
$folders = json_encode($folders);
$expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;
$mnt2res = empty($this->token->data->refresh_token) ? '' : ', "mnt2res": 1';
$json = '{"protocol": "onedrive", "mode": "done", "folders": ' . $folders . ', "expires": ' . $expires . $mnt2res .'}';
jQuery("#' . $options['id'] . '").elfinder("instance").trigger("netmount", ' . $json . ');
return array('exit' => true, 'body' => $html);
return array('exit' => true, 'body' => '{msg:errNetMountNoDriver}');
if ($_aToken = $this->session->get('OneDriveTokens')) {
$options['accessToken'] = json_encode($_aToken);
if ($this->options['path'] === 'root' || !$this->options['path']) {
$this->options['path'] = '/';
$this->session->remove('OneDriveTokens');
$this->setError(elFinder::ERROR_NETMOUNT, $options['host'], implode(' ', $this->error()));
return array('exit' => true, 'error' => $this->error());
$this->session->remove('nodeId');
unset($options['user'], $options['pass'], $options['id']);
* process of on netunmount
* Drop `onedrive` & rm thumbs.
public function netunmount($netVolumes, $key)
if (!$this->options['useApiThumbnail'] && ($tmbs = glob(rtrim($this->options['tmbPath'], '\\/') . DIRECTORY_SEPARATOR . $this->tmbPrefix . '*.png'))) {
foreach ($tmbs as $file) {
* Return debug info for client.
if (!empty($this->options['netkey']) && !empty($this->options['accessToken'])) {
$res['accessToken'] = $this->options['accessToken'];
/*********************************************************************/
/*********************************************************************/
* Connect to remote server and check if credentials are correct, if so, store the connection id in $ftp_conn.
* @throws elFinderAbortException
* @author Dmitry (dio) Levashov
* @author Cem (DiscoFever)
protected function init()
if (!$this->options['accessToken']) {
return $this->setError('Required option `accessToken` is undefined.');
if (!empty($this->options['tmpPath'])) {
if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'])) && is_writable($this->options['tmpPath'])) {
$this->tmp = $this->options['tmpPath'];
$this->token = json_decode($this->options['accessToken']);
if (!is_object($this->token)) {
throw new Exception('Required option `accessToken` is invalid JSON.');
if (empty($this->options['netkey'])) {
$this->netMountKey = $this->_od_getInitialToken();
$this->netMountKey = $this->options['netkey'];
if ($this->aTokenFile = $this->_od_getATokenFile()) {
if (empty($this->options['netkey'])) {
if (is_file($this->aTokenFile)) {
$this->token = json_decode(file_get_contents($this->aTokenFile));
if (!is_object($this->token)) {
unlink($this->aTokenFile);
throw new Exception('Required option `accessToken` is invalid JSON.');
file_put_contents($this->aTokenFile, $this->token);
} else if (is_file($this->aTokenFile)) {
// If the refresh token is the same as the permanent volume
$this->token = json_decode(file_get_contents($this->aTokenFile));
$this->_od_refreshToken();
$this->expires = empty($this->token->data->refresh_token) ? (int)$this->token->expires : 0;