: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$result = $this->_bd_fetch($url);
* Get dat(box metadata) from Box.com.
* @return object box metadata
protected function _bd_getRawItem($path)
return $this->_bd_query('0', $fetch_self = true);
list(, $itemId) = $this->_bd_splitPath($path);
return $this->_bd_query($itemId, $fetch_self = true);
* Parse line from box metadata output and return file stat (array).
* @param object $raw line from ftp_rawlist() output
* @author Dmitry Levashov
protected function _bd_parseRaw($raw)
$stat['rev'] = isset($raw->id) ? $raw->id : 'root';
$stat['name'] = $raw->name;
if (!empty($raw->modified_at)) {
$stat['ts'] = strtotime($raw->modified_at);
if ($raw->type === 'folder') {
$stat['mime'] = 'directory';
$stat['size'] = (int)$raw->size;
if (!empty($raw->shared_link->url) && $raw->shared_link->access == 'open') {
if ($url = $this->getSharedWebContentLink($raw)) {
} elseif (!$this->disabledGetUrl) {
* Get thumbnail from Box.com.
* @return string | boolean
protected function _bd_getThumbnail($path)
list(, $itemId) = $this->_bd_splitPath($path);
$url = self::API_URL . '/files/' . $itemId . '/thumbnail.png?min_height=' . $this->tmbSize . '&min_width=' . $this->tmbSize;
$contents = $this->_bd_fetch($url, true);
* @param string $path file path
protected function _bd_unlink($path, $type = null)
list(, $itemId) = $this->_bd_splitPath($path);
if ($type == 'folders') {
$url = self::API_URL . '/' . $type . '/' . $itemId . '?recursive=true';
$url = self::API_URL . '/' . $type . '/' . $itemId;
$curl = $this->_bd_prepareCurl(array(
CURLOPT_CUSTOMREQUEST => 'DELETE',
//unlink or delete File or Folder in the Parent
$this->_bd_curlExec($curl);
return $this->setError('Box error: ' . $e->getMessage());
* Get AccessToken file path
* @return string ( description_of_the_return_value )
protected function _bd_getATokenFile()
if (!empty($this->token->data->refresh_token)) {
$tmp = elFinder::getStaticVar('commonTempPath');
$tmp = $this->getTempPath();
$aTokenFile = $tmp . DIRECTORY_SEPARATOR . $this->_bd_getInitialToken() . '.btoken';
* Get Initial Token (MD5 hash)
protected function _bd_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 Box
public function netmountPrepare($options)
if (empty($options['client_id']) && defined('ELFINDER_BOX_CLIENTID')) {
$options['client_id'] = ELFINDER_BOX_CLIENTID;
if (empty($options['client_secret']) && defined('ELFINDER_BOX_CLIENTSECRET')) {
$options['client_secret'] = ELFINDER_BOX_CLIENTSECRET;
if (isset($options['pass']) && $options['pass'] === 'reauth') {
$options['user'] = 'init';
$this->session->remove('BoxTokens');
if (isset($options['id'])) {
$this->session->set('nodeId', $options['id']);
} else if ($_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 Box.com API
$this->session->set('BoxTokens',
$this->_bd_obtainAccessToken($options['client_id'], $options['client_secret'], $code));
'node' => $options['id'],
'json' => '{"protocol": "box", "mode": "done", "reset": 1}',
$nodeid = ($_GET['host'] === '1')? 'elfinder' : $_GET['host'];
'json' => json_encode(array(
return array('exit' => 'callback', 'out' => $out);
return array('exit' => true, 'body' => $out['json']);
'node' => $options['id'],
'json' => json_encode(array('error' => $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('BoxTokens');
$this->_bd_refreshToken();
$this->setError($e->getMessage());
$this->session->remove('BoxTokens');
if (empty($this->token)) {
$path = $options['path'];
if ($path === '/' || $path === 'root') {
$result = $this->_bd_query($path, $fetch_self = false, $recursive = false);
$redirect = elFinder::getConnectorUrl();
$redirect .= (strpos($redirect, '?') !== false? '&' : '?') . 'cmd=netmount&protocol=box&host=' . ($options['id'] === 'elfinder'? '1' : $options['id']);
$this->session->set('BoxTokens', (object)array('token' => null));
$url = self::AUTH_URL . '?' . http_build_query(array('response_type' => 'code', 'client_id' => $options['client_id'], 'redirect_uri' => $redirect));
return array('exit' => true, 'body' => '{msg:errAccess}');
$html = '<input id="elf-volumedriver-box-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: "box", mode: "makebtn", url: "' . $url . '"});
return array('exit' => true, 'body' => $html);
foreach ($result as $res) {
if ($res->type == 'folder') {
$folders[$res->id . ' '] = $res->name;
if ($options['pass'] === 'folders') {
return ['exit' => true, 'folders' => $folders];
$folders = ['root' => 'My Box'] + $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": "box", "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('BoxTokens')) {
$options['accessToken'] = json_encode($_aToken);
if ($this->options['path'] === 'root' || !$this->options['path']) {
$this->options['path'] = '/';
$this->session->remove('BoxTokens');
$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 `box` & rm thumbs.
public function netunmount($netVolumes, $key)
if ($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.
* @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->_bd_getInitialToken();
$this->netMountKey = $this->options['netkey'];
if ($this->aTokenFile = $this->_bd_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, json_encode($this->token), LOCK_EX);
} 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->needOnline && $this->_bd_refreshToken();
$this->setError($e->getMessage());
if ($this->netMountKey) {
$this->tmbPrefix = 'box' . base_convert($this->netMountKey, 16, 32);
if (empty($this->options['netkey']) && $this->tmbPrefix) {
$this->netunmount(null, null);
if ($this->options['path'] == 'root') {
$this->options['path'] = '/';
$this->root = $this->options['path'] = $this->_normpath($this->options['path']);
$this->options['root'] = ($this->options['root'] == '')? 'Box.com' : $this->options['root'];
if (empty($this->options['alias'])) {
list(, $itemId) = $this->_bd_splitPath($this->options['path']);
$this->options['alias'] = ($this->options['path'] === '/') ? $this->options['root'] :
$this->_bd_query($itemId, $fetch_self = true)->name . '@Box';
if (!empty($this->options['netkey'])) {
elFinder::$instance->updateNetVolumeOption($this->options['netkey'], 'alias', $this->options['alias']);
$this->options['alias'] = $this->options['root'];
$this->rootName = $this->options['alias'];
// This driver dose not support `syncChkAsTs`
$this->options['syncChkAsTs'] = false;
// 'lsPlSleep' minmum 10 sec
$this->options['lsPlSleep'] = max(10, $this->options['lsPlSleep']);
// enable command archive
$this->options['useRemoteArchive'] = true;
* Configure after successfull mount.
* @author Dmitry (dio) Levashov
* @throws elFinderAbortException
protected function configure()