@copyright Copyright (C) 2015. All Rights Reserved @license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html /------------------------------------------------------------------------------------------------------*/ // No direct access. defined('_JEXEC') or die; /** * Dropbox class */ class Dropbox { /** * final url */ protected $url; /** * The array for the post url */ protected $postUrl = array( "protocol" => "https://", "suddomain" => "api.", "domain" => "dropboxapi.com", "path" => "/2/" ); /** * the verious pathes we need */ protected $domainpath = array( "list_folder" => "files/list_folder", "list_folder_continue" => "files/list_folder/continue", "create_shared_link" => "sharing/create_shared_link", "get_shared_link_metadata" => "sharing/get_shared_link_metadata", "revoke" => "auth/token/revoke" ); /** * the target pathe to get */ protected $targetPath = false; protected $targetPathOriginal = false; /** * oauth token */ protected $oauthToken; /** * the verious pathes we need */ protected $permissionType; /** * The loop controller in calling Dropbox API */ protected $continueCalling = array(); /** * the success switch */ protected $succes; /** * the type call */ protected $type; /** * the query for the call */ protected $query; /** * the query for the call */ protected $model; /** * the mediaData bucket */ public $mediaData = array(); /** * the error messages */ public $error_summary = array(); /** * force the update to reset * */ public $forceReset = false; /** * Constructor */ public function __construct(JModelLegacy $model, $buildType) { // set the url at this point for now $this->url = $this->postUrl["protocol"] . $this->postUrl["suddomain"] . $this->postUrl["domain"] . $this->postUrl["path"]; // set the local model $this->model = $model; // set the build type $this->build = (int) $buildType; } /** * getFiles * * ============= * $details * ============= * sourceID * dropboxOption * dropboxTarget * addTypes * */ public function getFiles($token, $permissiontype, $details = array()) { // we need more then the normal time to run this script 5 minutes at least. ini_set('max_execution_time', 500); // set the oauth toke $this->oauthToken = $token; // set the permission type $this->permissionType = $permissiontype; // set the details if ($this->checkArray($details)) { foreach ($details as $detail => $value) { $this->$detail = $value; } } // set the curent folder path if (!$this->setFolderPath()) { return false; } // start the main factory that calles for the folder data $this->query = array("path" => $this->targetPath, "recursive" => true, "include_media_info" => true); $this->type = 'list_folder'; if ($this->makeCall()) { return true; } } public function revokeToken($token = null) { if ($token) { // set the oauth toke $this->oauthToken = $token; } // set the call to revoke the token $this->query = 'null'; $this->type = 'revoke'; if ($this->makeCall()) { return true; } return false; } protected function setFolderPath() { if ('full' == $this->permissionType && isset($this->dropboxOption) && isset($this->dropboxTarget) && $this->checkString($this->dropboxTarget)) { if (2 == $this->dropboxOption) { // simply set the path $this->targetPath = '/' . trim(strtolower($this->dropboxTarget), '/'); return true; } elseif (1 == $this->dropboxOption) { // make a call to get the path $this->query = array("url" => $this->dropboxTarget); $this->type = 'get_shared_link_metadata'; if ($this->makeCall()) { return true; } } } elseif ('app' == $this->permissionType) { $this->targetPath = ""; return true; } return false; } protected function makeCall() { if ($this->_isCurl()) { return $this->makeCurlCall(); } else { return $this->makeGetCall(); } } protected function makeGetCall() { $options = array( 'http' => array( 'header' => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $this->oauthToken, 'method' => "POST" ), ); if ($this->checkArray($this->query)) { $this->query = json_encode($this->query); } $options['http']['content'] = $this->query; $context = stream_context_create($options); $response = file_get_contents($this->url . $this->domainpath[$this->type], false, $context); // store the result return $this->getCallResult($response); } protected function getCallResult($response) { if ($response === FALSE) { $this->error_summary[] = $this->type . '_error'; return false; } // store the result return $this->setTheResult(json_decode($response)); } protected function makeCurlCall() { $headers = array('Authorization: Bearer ' . $this->oauthToken, 'Content-Type: application/json' ); $ch = curl_init($this->url . $this->domainpath[$this->type]); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // check if query is set if ($this->checkArray($this->query)) { $this->query = json_encode($this->query); } curl_setopt($ch, CURLOPT_POSTFIELDS, $this->query); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // curl_setopt($ch, CURLOPT_VERBOSE, 1); // debug $response = curl_exec($ch); curl_close($ch); // store the result return $this->curlCallResult($response); } public function curlCallResult($response) { if ($this->checkJson($response)) { $response = json_decode($response); } // store the result return $this->setTheResult($response); } protected function setTheResult($data) { // if there was an error stop!!! if (isset($data->error_summary)) { $this->error_summary[] = $data->error_summary; $this->forceReset = true; return false; } // deal with each type switch ($this->type) { case "list_folder": case "list_folder_continue": if (isset($data->entries) && $this->checkArray($data->entries)) { if ($this->storeFiles($data->entries)) { // run the continue if needed if (isset($data->has_more) && $data->has_more && isset($data->cursor)) { // start the main factory that calles for the folder data $this->query = array("cursor" => $data->cursor); $this->type = 'list_folder_continue'; if ($this->makeCall()) { return true; } } return true; } } $this->error_summary[] = $this->type . '_error'; break; case "create_shared_link": if (isset($data->url) && isset($data->path) && $this->storeSharedLink($this->fixPath($data->path), str_replace('?dl=0', '?dl=1', $data->url))) { // we stored the link return true; } $this->error_summary[] = $this->type . '_error'; break; case "get_shared_link_metadata": if (isset($data->path_lower)) { $this->targetPath = $data->path_lower; return true; } $this->error_summary[] = $this->type . '_error'; break; case "revoke": if (is_null($data)) { return true; } $this->error_summary[] = $this->type . '_error'; break; } $this->forceReset = true; return false; } protected function storeSharedLink($path, $url) { // we need to store the url to DB if (isset($this->mediaData[$path])) { $localListing = array(); $localListing['id'] = 0; $localListing['name'] = $this->mediaData[$path]['name']; $localListing['size'] = $this->mediaData[$path]['size']; $localListing['key'] = $path; $localListing['url'] = $url; $localListing['build'] = $this->build; $localListing['external_source'] = (int) $this->sourceID; // free some memory unset($this->mediaData[$path]); // check if item already set if ($id = $this->model->searchForId($path)) { // update item $localListing['id'] = $id; } return $this->model->save($localListing); } return false; } protected function storeFiles($entries) { foreach ($entries as $item) { if (isset($item->{'.tag'}) && 'file' == $item->{'.tag'} && isset($item->name)) { $addLink = false; // remove if not related to type if (isset($this->addTypes) && $this->checkArray($this->addTypes)) { foreach ($this->addTypes as $add) { if (strpos($item->name, $add) !== false) { $addLink = true; } } } if ($addLink && isset($item->path_lower)) { // store media info $this->mediaData[$this->fixPath($item->path_lower)] = array('name' => $item->name, 'size' => $item->size); // get the shared link $this->query = array("path" => $item->path_lower); $this->type = 'create_shared_link'; if (!$this->makeCall()) { return false; } } } } return true; } protected function fixPath($path) { if ($this->checkString($this->targetPath)) { $path = str_replace($this->targetPath, 'VDM_pLeK_h0uEr', $path); } else { $path = 'VDM_pLeK_h0uEr' . $path; } return $path; } protected function checkObject($object) { if (isset($object) && is_object($object) && count($object) > 0) { return true; } return false; } protected function checkArray($array) { if (isset($array) && is_array($array) && count($array) > 0) { return true; } return false; } protected function checkJson($string) { if ($this->checkString($string)) { json_decode($string); return (json_last_error() === JSON_ERROR_NONE); } return false; } protected function checkString($string) { if (isset($string) && is_string($string) && strlen($string) > 0) { return true; } return false; } protected function _isCurl() { return function_exists('curl_version'); } }