diff --git a/DropBoxPhp/DropboxClient.php b/DropBoxPhp/DropboxClient.php new file mode 100644 index 0000000..ab66ac0 --- /dev/null +++ b/DropBoxPhp/DropboxClient.php @@ -0,0 +1,672 @@ + + * @copyright Fabian Schlieper 2014 + * @version 1.7.1 + * @license See LICENSE + * + */ + +require_once(dirname(__FILE__)."/OAuthSimple.php"); + +class DropboxClient { + + const API_URL = "https://api.dropbox.com/1/"; + const API_CONTENT_URL = "https://api-content.dropbox.com/1/"; + + const BUFFER_SIZE = 4096; + + const MAX_UPLOAD_CHUNK_SIZE = 150000000; // 150MB + + const UPLOAD_CHUNK_SIZE = 4000000; // 4MB + + private $appParams; + private $consumerToken; + + private $requestToken; + private $accessToken; + + private $locale; + private $rootPath; + + private $useCurl; + + function __construct ($app_params, $locale = "en"){ + $this->appParams = $app_params; + if(empty($app_params['app_key'])) + throw new DropboxException("App Key is empty!"); + + $this->consumerToken = array('t' => $this->appParams['app_key'], 's' => $this->appParams['app_secret']); + $this->locale = $locale; + $this->rootPath = empty($app_params['app_full_access']) ? "sandbox" : "dropbox"; + + $this->requestToken = null; + $this->accessToken = null; + + $this->useCurl = function_exists('curl_init'); + } + + function __wakeup() { + $this->useCurl = $this->useCurl && function_exists('curl_init'); + } + /** + * Sets whether to use cURL if its available or PHP HTTP wrappers otherwise + * + * @access public + * @return boolean Whether to actually use cURL (always false if not installed) + */ + public function SetUseCUrl($use_it) + { + return ($this->useCurl = ($use_it && function_exists('curl_init'))); + } + + // ################################################## + // Authorization + + /** + * Step 1 of authentication process. Retrieves a request token or returns a previously retrieved one. + * + * @access public + * @param boolean $get_new_token Optional (default false). Wether to retrieve a new request token. + * @return array Request Token array. + */ + public function GetRequestToken($get_new_token=false) + { + if(!empty($this->requestToken) && !$get_new_token) + return $this->requestToken; + + $rt = $this->authCall("oauth/request_token"); + if(empty($rt) || empty($rt['oauth_token'])) + throw new DropboxException('Could not get request token!'); + + return ($this->requestToken = array('t'=>$rt['oauth_token'], 's'=>$rt['oauth_token_secret'])); + } + + /** + * Step 2. Returns a URL the user must be redirected to in order to connect the app to their Dropbox account + * + * @access public + * @param string $return_url URL users are redirected after authorization + * @return string URL + */ + public function BuildAuthorizeUrl($return_url) + { + $rt = $this->GetRequestToken(); + if(empty($rt) || empty($rt['t'])) throw new DropboxException('Request Token Invalid ('.print_r($rt,true).').'); + return "https://www.dropbox.com/1/oauth/authorize?oauth_token=".$rt['t']."&oauth_callback=".urlencode($return_url); + } + + /** + * Step 3. Acquires an access token. This is the final step of authentication. + * + * @access public + * @param array $request_token Optional. The previously retrieved request token. This parameter can only be skipped if the DropboxClient object has been (de)serialized. + * @return array Access Token array. + */ + public function GetAccessToken($request_token = null) + { + if(!empty($this->accessToken)) return $this->accessToken; + + if(empty($request_token)) $request_token = $this->requestToken; + if(empty($request_token)) throw new DropboxException('Request token required!'); + + $at = $this->authCall("oauth/access_token", $request_token); + if(empty($at)) + throw new DropboxException(sprintf('Could not get access token! (request token: %s)', $request_token['t'])); + + return ($this->accessToken = array('t'=>$at['oauth_token'], 's'=>$at['oauth_token_secret'])); + } + + /** + * Sets a previously retrieved (and stored) access token. + * + * @access public + * @param string|object $token The Access Token + * @return none + */ + public function SetAccessToken($token) + { + if(empty($token['t']) || empty($token['s'])) throw new DropboxException('Passed invalid access token.'); + $this->accessToken = $token; + } + + /** + * Checks if an access token has been set. + * + * @access public + * @return boolean Authorized or not + */ + public function IsAuthorized() + { + if(empty($this->accessToken)) return false; + return true; + } + + + // ################################################## + // API Functions + + + /** + * Retrieves information about the user's account. + * + * @access public + * @return object Account info object. See https://www.dropbox.com/developers/reference/api#account-info + */ + public function GetAccountInfo() + { + return $this->apiCall("account/info", "GET"); + } + + + /** + * Get file list of a dropbox folder. + * + * @access public + * @param string|object $dropbox_path Dropbox path of the folder + * @return array An array with metadata of files/folders keyed by paths + */ + public function GetFiles($dropbox_path='', $recursive=false, $include_deleted=false) + { + if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path; + return $this->getFileTree($dropbox_path, $include_deleted, $recursive ? 1000 : 0); + } + + /** + * Get file or folder metadata + * + * @access public + * @param $dropbox_path string Dropbox path of the file or folder + */ + public function GetMetadata($dropbox_path, $include_deleted=false, $rev=null) + { + if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path; + return $this->apiCall("metadata/$this->rootPath/$dropbox_path", "GET", compact('include_deleted','rev')); + } + + /** + * Download a file to the webserver + * + * @access public + * @param string|object $dropbox_file Dropbox path or metadata object of the file to download. + * @param string $dest_path Local path for destination + * @param string $rev Optional. The revision of the file to retrieve. This defaults to the most recent revision. + * @param callback $progress_changed_callback Optional. Callback that will be called during download with 2 args: 1. bytes loaded, 2. file size + * @return object Dropbox file metadata + */ + public function DownloadFile($dropbox_file, $dest_path='', $rev=null, $progress_changed_callback = null) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) + $dropbox_file = $dropbox_file->path; + + if(empty($dest_path)) $dest_path = basename($dropbox_file); + + $url = $this->cleanUrl(self::API_CONTENT_URL."/files/$this->rootPath/$dropbox_file") + . (!empty($rev) ? ('?'.http_build_query(array('rev' => $rev),'','&')) : ''); + $context = $this->createRequestContext($url, "GET"); + + $fh = @fopen($dest_path, 'wb'); // write binary + if($fh === false) { + @fclose($rh); + throw new DropboxException("Could not create file $dest_path !"); + } + + if($this->useCurl) { + curl_setopt($context, CURLOPT_BINARYTRANSFER, true); + curl_setopt($context, CURLOPT_RETURNTRANSFER, true); + curl_setopt($context, CURLOPT_FILE, $fh); + $response_headers = array(); + self::execCurlAndClose($context, $response_headers); + fclose($fh); + $meta = self::getMetaFromHeaders($response_headers, true); + $bytes_loaded = filesize($dest_path); + } else { + $rh = @fopen($url, 'rb', false, $context); // read binary + if($rh === false) + throw new DropboxException("HTTP request to $url failed!"); + + + // get file meta from HTTP header + $s_meta = stream_get_meta_data($rh); + $meta = self::getMetaFromHeaders($s_meta['wrapper_data'], true); + $bytes_loaded = 0; + while (!feof($rh)) { + if(($s=fwrite($fh, fread($rh, self::BUFFER_SIZE))) === false) { + @fclose($rh); + @fclose($fh); + throw new DropboxException("Writing to file $dest_path failed!'"); + } + $bytes_loaded += $s; + if(!empty($progress_changed_callback)) { + call_user_func($progress_changed_callback, $bytes_loaded, $meta->bytes); + } + } + + fclose($rh); + fclose($fh); + } + + if($meta->bytes != $bytes_loaded) + throw new DropboxException("Download size mismatch! (header:{$meta->bytes} vs actual:{$bytes_loaded}; curl:{$this->useCurl})"); + + return $meta; + } + + /** + * Upload a file to dropbox + * + * @access public + * @param $src_file string Local file to upload + * @param $dropbox_path string Dropbox path for destination + * @return object Dropbox file metadata + */ + public function UploadFile($src_file, $dropbox_path='', $overwrite=true, $parent_rev=null) + { + if(empty($dropbox_path)) $dropbox_path = basename($src_file); + elseif(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path; + + // make sure the dropbox_path is not a dir. if it is, append baseneme of $src_file + $dropbox_bn = basename($dropbox_path); + if(strpos($dropbox_bn,'.') === false) { // check if ext. is missing -> could be a directory! + try { + $meta = $this->GetMetadata($dropbox_path); + if($meta && $meta->is_dir) + $dropbox_path = $dropbox_path . '/'. basename($src_file); + } catch(Exception $e) {} + } + + $file_size = filesize($src_file); + + if($file_size > self::MAX_UPLOAD_CHUNK_SIZE) + { + $fh = fopen($src_file,'rb'); + if($fh === false) + throw new DropboxException(); + + $upload_id = null; + $offset = 0; + + + while(!feof($fh)) { + $url = $this->cleanUrl(self::API_CONTENT_URL."/chunked_upload").'?'.http_build_query(compact('upload_id', 'offset'),'','&'); + $content = fread($fh, self::UPLOAD_CHUNK_SIZE); + $context = $this->createRequestContext($url, "PUT", $content); + + if($this->useCurl) { + curl_setopt($context, CURLOPT_BINARYTRANSFER, true); + $response = json_decode(self::execCurlAndClose($context)); + } else { + $response = json_decode(file_get_contents($url, false, $context)); + } + $offset += strlen($content); + unset($content); + unset($context); + + self::checkForError($response); + + if(empty($upload_id)) { + $upload_id = $response->upload_id; + if(empty($upload_id)) throw new DropboxException("Upload ID empty!"); + } + if($offset >= $file_size) + break; + } + + @fclose($fh); + + return $this->apiCall("commit_chunked_upload/$this->rootPath/$dropbox_path", "POST", compact('overwrite','parent_rev','upload_id'), true); + } + + $query = http_build_query(array_merge(compact('overwrite', 'parent_rev'), array('locale' => $this->locale)),'','&'); + $url = $this->cleanUrl(self::API_CONTENT_URL."/files_put/$this->rootPath/$dropbox_path")."?$query"; + + if($this->useCurl) { + $context = $this->createRequestContext($url, "PUT"); + curl_setopt($context, CURLOPT_BINARYTRANSFER, true); + $fh = fopen($src_file, 'rb'); + curl_setopt($context, CURLOPT_PUT, 1); + curl_setopt($context, CURLOPT_INFILE, $fh); // file pointer + curl_setopt($context, CURLOPT_INFILESIZE, filesize($src_file)); + $meta = json_decode(self::execCurlAndClose($context)); + fclose($fh); + return self::checkForError($meta); + } else { + $content = file_get_contents($src_file); + if(strlen($content) == 0) + throw new DropboxException("Could not read file $src_file or file is empty!"); + + $context = $this->createRequestContext($url, "PUT", $content); + + return self::checkForError(json_decode(file_get_contents($url, false, $context))); + } + } + + /** + * Get thumbnail for a specified image + * + * @access public + * @param $dropbox_file string Path to the image + * @param $format string Image format of the thumbnail (jpeg or png) + * @param $size string Thumbnail size (xs, s, m, l, xl) + * @return mime/* Returns the thumbnail as binary image data + */ + public function GetThumbnail($dropbox_file, $size = 's', $format = 'jpeg', $echo = false) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path; + $url = $this->cleanUrl(self::API_CONTENT_URL."thumbnails/$this->rootPath/$dropbox_file") + . '?' . http_build_query(array('format' => $format, 'size' => $size),'','&'); + $context = $this->createRequestContext($url, "GET"); + + if($this->useCurl) { + curl_setopt($context, CURLOPT_BINARYTRANSFER, true); + curl_setopt($context, CURLOPT_RETURNTRANSFER, true); + } + + $thumb = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, NULL, $context); + + if($echo) { + header('Content-type: image/'.$format); + echo $thumb; + unset($thumb); + return; + } + + return $thumb; + } + + + function GetLink($dropbox_file, $preview=true, $short=true, &$expires=null) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path; + $url = $this->apiCall(($preview?"shares":"media")."/$this->rootPath/$dropbox_file", "POST", array('locale' => null, 'short_url'=> $preview ? $short : null)); + $expires = strtotime($url->expires); + return $url->url; + } + + function Delta($cursor) + { + return $this->apiCall("delta", "POST", compact('cursor')); + } + + function GetRevisions($dropbox_file, $rev_limit=10) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path; + return $this->apiCall("revisions/$this->rootPath/$dropbox_file", "GET", compact('rev_limit')); + } + + function Restore($dropbox_file, $rev) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path; + return $this->apiCall("restore/$this->rootPath/$dropbox_file", "POST", compact('rev')); + } + + function Search($path, $query, $file_limit=1000, $include_deleted=false) + { + return $this->apiCall("search/$this->rootPath/$path", "POST", compact('query','file_limit','include_deleted')); + } + + function GetCopyRef($dropbox_file, &$expires=null) + { + if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path; + $ref = $this->apiCall("copy_ref/$this->rootPath/$dropbox_file", "GET", array('locale' => null)); + $expires = strtotime($ref->expires); + return $ref->copy_ref; + } + + + function Copy($from_path, $to_path, $copy_ref=false) + { + if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path; + return $this->apiCall("fileops/copy", "POST", array('root'=> $this->rootPath, ($copy_ref ? 'from_copy_ref' : 'from_path') => $from_path, 'to_path' => $to_path)); + } + + /** + * Creates a new folder in the DropBox + * + * @access public + * @param $path string The path to the new folder to create + * @return object Dropbox folder metadata + */ + function CreateFolder($path) + { + return $this->apiCall("fileops/create_folder", "POST", array('root'=> $this->rootPath, 'path' => $path)); + } + + /** + * Delete file or folder + * + * @access public + * @param $path mixed The path or metadata of the file/folder to be deleted. + * @return object Dropbox metadata of deleted file or folder + */ + function Delete($path) + { + if(is_object($path) && !empty($path->path)) $path = $path->path; + return $this->apiCall("fileops/delete", "POST", array('locale' =>null, 'root'=> $this->rootPath, 'path' => $path)); + } + + function Move($from_path, $to_path) + { + if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path; + return $this->apiCall("fileops/move", "POST", array('root'=> $this->rootPath, 'from_path' => $from_path, 'to_path' => $to_path)); + } + + function getFileTree($path="", $include_deleted = false, $max_depth = 0, $depth=0) + { + static $files; + if($depth == 0) $files = array(); + + $dir = $this->apiCall("metadata/$this->rootPath/$path", "GET", compact('include_deleted')); + + if(empty($dir) || !is_object($dir)) return false; + + if(!empty($dir->error)) throw new DropboxException($dir->error); + + foreach($dir->contents as $item) + { + $files[trim($item->path,'/')] = $item; + if($item->is_dir && $depth < $max_depth) + { + $this->getFileTree($item->path, $include_deleted, $max_depth, $depth+1); + } + } + + return $files; + } + + function createCurl($url, $http_context) + { + $ch = curl_init($url); + + $curl_opts = array( + CURLOPT_HEADER => false, // exclude header from output + //CURLOPT_MUTE => true, // no output! + CURLOPT_RETURNTRANSFER => true, // but return! + CURLOPT_SSL_VERIFYPEER => false, + ); + + $curl_opts[CURLOPT_CUSTOMREQUEST] = $http_context['method']; + + if(!empty($http_context['content'])) { + $curl_opts[CURLOPT_POSTFIELDS] =& $http_context['content']; + if(defined("CURLOPT_POSTFIELDSIZE")) + $curl_opts[CURLOPT_POSTFIELDSIZE] = strlen($http_context['content']); + } + + $curl_opts[CURLOPT_HTTPHEADER] = array_map('trim',explode("\n",$http_context['header'])); + + curl_setopt_array($ch, $curl_opts); + return $ch; + } + + static private $_curlHeadersRef; + static function _curlHeaderCallback($ch, $header) + { + self::$_curlHeadersRef[] = trim($header); + return strlen($header); + } + + static function &execCurlAndClose($ch, &$out_response_headers = null) + { + if(is_array($out_response_headers)) { + self::$_curlHeadersRef =& $out_response_headers; + curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(__CLASS__, '_curlHeaderCallback')); + } + $res = curl_exec($ch); + $err_no = curl_errno($ch); + $err_str = curl_error($ch); + curl_close($ch); + if($err_no || $res === false) { + throw new DropboxException("cURL-Error ($err_no): $err_str"); + } + + return $res; + } + + private function createRequestContext($url, $method, &$content=null, $oauth_token=-1) + { + if($oauth_token === -1) + $oauth_token = $this->accessToken; + + $method = strtoupper($method); + $http_context = array('method'=>$method, 'header'=> ''); + + $oauth = new OAuthSimple($this->consumerToken['t'],$this->consumerToken['s']); + + if(empty($oauth_token) && !empty($this->accessToken)) + $oauth_token = $this->accessToken; + + if(!empty($oauth_token)) { + $oauth->setParameters(array('oauth_token' => $oauth_token['t'])); + $oauth->signatures(array('oauth_secret'=>$oauth_token['s'])); + } + + if(!empty($content)) { + $post_vars = ($method != "PUT" && preg_match("/^[a-z][a-z0-9_]*=/i", substr($content, 0, 32))); + $http_context['header'] .= "Content-Length: ".strlen($content)."\r\n"; + $http_context['header'] .= "Content-Type: application/".($post_vars?"x-www-form-urlencoded":"octet-stream")."\r\n"; + $http_context['content'] =& $content; + if($method == "POST" && $post_vars) + $oauth->setParameters($content); + } elseif($method == "POST") { + // make sure that content-length is always set when post request (otherwise some wrappers fail!) + $http_context['content'] = ""; + $http_context['header'] .= "Content-Length: 0\r\n"; + } + + + // check for query vars in url and add them to oauth parameters (and remove from path) + $path = $url; + $query = strrchr($url,'?'); + if(!empty($query)) { + $oauth->setParameters(substr($query,1)); + $path = substr($url, 0, -strlen($query)); + } + + + $signed = $oauth->sign(array( + 'action' => $method, + 'path'=> $path)); + //print_r($signed); + + $http_context['header'] .= "Authorization: ".$signed['header']."\r\n"; + + return $this->useCurl ? $this->createCurl($url, $http_context) : stream_context_create(array('http'=>$http_context)); + } + + private function authCall($path, $request_token=null) + { + $url = $this->cleanUrl(self::API_URL.$path); + $dummy = null; + $context = $this->createRequestContext($url, "POST", $dummy, $request_token); + + $contents = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context); + $data = array(); + parse_str($contents, $data); + return $data; + } + + private static function checkForError($resp) + { + if(!empty($resp->error)) + throw new DropboxException($resp->error); + return $resp; + } + + + private function apiCall($path, $method, $params=array(), $content_call=false) + { + $url = $this->cleanUrl(($content_call ? self::API_CONTENT_URL : self::API_URL).$path); + $content = http_build_query(array_merge(array('locale'=>$this->locale), $params),'','&'); + + if($method == "GET") { + $url .= "?".$content; + $content = null; + } + + $context = $this->createRequestContext($url, $method, $content); + $json = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context); + //if($json === false) +// throw new DropboxException(); + $resp = json_decode($json); + return self::checkForError($resp); + } + + + private static function getMetaFromHeaders(&$header_array, $throw_on_error=false) + { + $obj = json_decode(substr(@array_shift(array_filter($header_array, create_function('$s', 'return stripos($s, "x-dropbox-metadata:") === 0;'))), 20)); + if($throw_on_error && (empty($obj)||!is_object($obj))) + throw new DropboxException("Could not retrieve meta data from header data: ".print_r($header_array,true)); + if($throw_on_error) + self::checkForError ($obj); + return $obj; + } + + + function cleanUrl($url) { + $p = substr($url,0,8); + $url = str_replace('//','/', str_replace('\\','/',substr($url,8))); + $url = rawurlencode($url); + $url = str_replace('%2F', '/', $url); + return $p.$url; + } +} + +class DropboxException extends Exception { + + public function __construct($err = null, $isDebug = FALSE) + { + if(is_null($err)) { + $el = error_get_last(); + $this->message = $el['message']; + $this->file = $el['file']; + $this->line = $el['line']; + } else + $this->message = $err; + self::log_error($err); + if ($isDebug) + { + self::display_error($err, TRUE); + } + } + + public static function log_error($err) + { + error_log($err, 0); + } + + public static function display_error($err, $kill = FALSE) + { + print_r($err); + if ($kill === FALSE) + { + die(); + } + } +} diff --git a/DropBoxPhp/OAuthSimple.php b/DropBoxPhp/OAuthSimple.php new file mode 100644 index 0000000..130123b --- /dev/null +++ b/DropBoxPhp/OAuthSimple.php @@ -0,0 +1,532 @@ + + * @copyright unitedHeroes.net 2011 + * @version 1.3 + * @license See OAuthSimple_license.txt + * + */ + +class OAuthSimple { + private $_secrets; + private $_default_signature_method; + private $_action; + private $_nonce_chars; + + /** + * Constructor + * + * @access public + * @param api_key (String) The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use. + * @param shared_secret (String) The shared secret. This value is also usually provided by the site you wish to use. + * @return OAuthSimple (Object) + */ + function __construct ($APIKey = "", $sharedSecret=""){ + + if (!empty($APIKey)) + { + $this->_secrets['consumer_key'] = $APIKey; + } + + if (!empty($sharedSecret)) + { + $this->_secrets['shared_secret'] = $sharedSecret; + } + + $this->_default_signature_method = "HMAC-SHA1"; + $this->_action = "GET"; + $this->_nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + return $this; + } + + /** + * Reset the parameters and URL + * + * @access public + * @return OAuthSimple (Object) + */ + public function reset() { + $this->_parameters = Array(); + $this->path = NULL; + $this->sbs = NULL; + + return $this; + } + + /** + * Set the parameters either from a hash or a string + * + * @access public + * @param(string, object) List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash) + * @return OAuthSimple (Object) + */ + public function setParameters ($parameters=Array()) { + + if (is_string($parameters)) + { + $parameters = $this->_parseParameterString($parameters); + } + if (empty($this->_parameters)) + { + $this->_parameters = $parameters; + } + else if (!empty($parameters)) + { + $this->_parameters = array_merge($this->_parameters,$parameters); + } + if (empty($this->_parameters['oauth_nonce'])) + { + $this->_getNonce(); + } + if (empty($this->_parameters['oauth_timestamp'])) + { + $this->_getTimeStamp(); + } + if (empty($this->_parameters['oauth_consumer_key'])) + { + $this->_getApiKey(); + } + if (empty($this->_parameters['oauth_token'])) + { + $this->_getAccessToken(); + } + if (empty($this->_parameters['oauth_signature_method'])) + { + $this->setSignatureMethod(); + } + if (empty($this->_parameters['oauth_version'])) + { + $this->_parameters['oauth_version']="1.0"; + } + + return $this; + } + + /** + * Convenience method for setParameters + * + * @access public + * @see setParameters + */ + public function setQueryString ($parameters) + { + return $this->setParameters($parameters); + } + + /** + * Set the target URL (does not include the parameters) + * + * @param path (String) the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo") + * @return OAuthSimple (Object) + */ + public function setURL ($path) + { + if (empty($path)) + { + throw new OAuthSimpleException('No path specified for OAuthSimple.setURL'); + } + $this->_path=$path; + + return $this; + } + + /** + * Convenience method for setURL + * + * @param path (String) + * @see setURL + */ + public function setPath ($path) + { + return $this->_path=$path; + } + + /** + * Set the "action" for the url, (e.g. GET,POST, DELETE, etc.) + * + * @param action (String) HTTP Action word. + * @return OAuthSimple (Object) + */ + public function setAction ($action) + { + if (empty($action)) + { + $action = 'GET'; + } + $action = strtoupper($action); + if (preg_match('/[^A-Z]/',$action)) + { + throw new OAuthSimpleException('Invalid action specified for OAuthSimple.setAction'); + } + $this->_action = $action; + + return $this; + } + + /** + * Set the signatures (as well as validate the ones you have) + * + * @param signatures (object) object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:} + * @return OAuthSimple (Object) + */ + public function signatures ($signatures) + { + if (!empty($signatures) && !is_array($signatures)) + { + throw new OAuthSimpleException('Must pass dictionary array to OAuthSimple.signatures'); + } + if (!empty($signatures)) + { + if (empty($this->_secrets)) + { + $this->_secrets=Array(); + } + $this->_secrets=array_merge($this->_secrets,$signatures); + } + if (isset($this->_secrets['api_key'])) + { + $this->_secrets['consumer_key'] = $this->_secrets['api_key']; + } + if (isset($this->_secrets['access_token'])) + { + $this->_secrets['oauth_token'] = $this->_secrets['access_token']; + } + if (isset($this->_secrets['access_secret'])) + { + $this->_secrets['oauth_secret'] = $this->_secrets['access_secret']; + } + if (isset($this->_secrets['access_token_secret'])) + { + $this->_secrets['oauth_secret'] = $this->_secrets['access_token_secret']; + } + if (empty($this->_secrets['consumer_key'])) + { + throw new OAuthSimpleException('Missing required consumer_key in OAuthSimple.signatures'); + } + if (empty($this->_secrets['shared_secret'])) + { + throw new OAuthSimpleException('Missing requires shared_secret in OAuthSimple.signatures'); + } + if (!empty($this->_secrets['oauth_token']) && empty($this->_secrets['oauth_secret'])) + { + throw new OAuthSimpleException('Missing oauth_secret for supplied oauth_token in OAuthSimple.signatures'); + } + + return $this; + } + + public function setTokensAndSecrets($signatures) + { + return $this->signatures($signatures); + } + + /** + * Set the signature method (currently only Plaintext or SHA-MAC1) + * + * @param method (String) Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now) + * @return OAuthSimple (Object) + */ + public function setSignatureMethod ($method="") + { + if (empty($method)) + { + $method = $this->_default_signature_method; + } + $method = strtoupper($method); + switch($method) + { + case 'PLAINTEXT': + case 'HMAC-SHA1': + $this->_parameters['oauth_signature_method']=$method; + break; + default: + throw new OAuthSimpleException ("Unknown signing method $method specified for OAuthSimple.setSignatureMethod"); + break; + } + + return $this; + } + + /** sign the request + * + * note: all arguments are optional, provided you've set them using the + * other helper functions. + * + * @param args (Array) hash of arguments for the call {action, path, parameters (array), method, signatures (array)} all arguments are optional. + * @return (Array) signed values + */ + public function sign($args=array()) + { + if (!empty($args['action'])) + { + $this->setAction($args['action']); + } + if (!empty($args['path'])) + { + $this->setPath($args['path']); + } + if (!empty($args['method'])) + { + $this->setSignatureMethod($args['method']); + } + if (!empty($args['signatures'])) + { + $this->signatures($args['signatures']); + } + if (empty($args['parameters'])) + { + $args['parameters']=array(); + } + $this->setParameters($args['parameters']); + $normParams = $this->_normalizedParameters(); + $this->_parameters['oauth_signature'] = $this->_generateSignature($normParams); + + return Array ( + 'parameters' => $this->_parameters, + 'signature' => self::_oauthEscape($this->_parameters['oauth_signature']), + 'signed_url' => $this->_path . '?' . $this->_normalizedParameters(), + 'header' => $this->getHeaderString(), + 'sbs'=> $this->sbs + ); + } + + /** + * Return a formatted "header" string + * + * NOTE: This doesn't set the "Authorization: " prefix, which is required. + * It's not set because various set header functions prefer different + * ways to do that. + * + * @param args (Array) + * @return $result (String) + */ + public function getHeaderString ($args=array()) + { + if (empty($this->_parameters['oauth_signature'])) + { + $this->sign($args); + } + $result = 'OAuth '; + + foreach ($this->_parameters as $pName => $pValue) + { + if (strpos($pName,'oauth_') !== 0 || $pName == 'oauth_token_secret2') + { + continue; + } + if (is_array($pValue)) + { + foreach ($pValue as $val) + { + $result .= $pName .'="' . self::_oauthEscape($val) . '", '; + } + } + else + { + $result .= $pName . '="' . self::_oauthEscape($pValue) . '", '; + } + } + + return preg_replace('/, $/','',$result); + } + + private function _parseParameterString ($paramString) + { + $elements = explode('&',$paramString); + $result = array(); + foreach ($elements as $element) + { + list ($key,$token) = explode('=',$element); + if ($token) + { + $token = urldecode($token); + } + if (!empty($result[$key])) + { + if (!is_array($result[$key])) + { + $result[$key] = array($result[$key],$token); + } + else + { + array_push($result[$key],$token); + } + } + else + $result[$key]=$token; + } + return $result; + } + + + private static function _oauthEscape($string) + { + if ($string === 0) { return 0; } + if ($string == '0') { return '0'; } + if (strlen($string) == 0) { return ''; } + if (is_array($string)) { + throw new OAuthSimpleException('Array passed to _oauthEscape'); + } + $string = rawurlencode($string); + + $string = str_replace('+','%20',$string); + $string = str_replace('!','%21',$string); + $string = str_replace('*','%2A',$string); + $string = str_replace('\'','%27',$string); + $string = str_replace('(','%28',$string); + $string = str_replace(')','%29',$string); + + return $string; + } + + private function _getNonce($length=5) + { + $result = ''; + $cLength = strlen($this->_nonce_chars); + for ($i=0; $i < $length; $i++) + { + $rnum = rand(0,$cLength); + $result .= substr($this->_nonce_chars,$rnum,1); + } + $result = md5($result); + $this->_parameters['oauth_nonce'] = $result; + + return $result; + } + + private function _getApiKey() + { + if (empty($this->_secrets['consumer_key'])) + { + throw new OAuthSimpleException('No consumer_key set for OAuthSimple'); + } + $this->_parameters['oauth_consumer_key']=$this->_secrets['consumer_key']; + + return $this->_parameters['oauth_consumer_key']; + } + + private function _getAccessToken() + { + if (!isset($this->_secrets['oauth_secret'])) + { + return ''; + } + if (!isset($this->_secrets['oauth_token'])) + { + throw new OAuthSimpleException('No access token (oauth_token) set for OAuthSimple.'); + } + $this->_parameters['oauth_token'] = $this->_secrets['oauth_token']; + + return $this->_parameters['oauth_token']; + } + + private function _getTimeStamp() + { + return $this->_parameters['oauth_timestamp'] = time(); + } + + private function _normalizedParameters() + { + $normalized_keys = array(); + $return_array = array(); + + foreach ( $this->_parameters as $paramName=>$paramValue) { + if (!preg_match('/\w+_secret/',$paramName) OR (strpos($paramValue, '@') !== 0 && !file_exists(substr($paramValue, 1))) ) + { + if (is_array($paramValue)) + { + $normalized_keys[self::_oauthEscape($paramName)] = array(); + foreach($paramValue as $item) + { + array_push($normalized_keys[self::_oauthEscape($paramName)], self::_oauthEscape($item)); + } + } + else + { + $normalized_keys[self::_oauthEscape($paramName)] = self::_oauthEscape($paramValue); + } + } + } + + ksort($normalized_keys); + + foreach($normalized_keys as $key=>$val) + { + if (is_array($val)) + { + sort($val); + foreach($val as $element) + { + array_push($return_array, $key . "=" . $element); + } + } + else + { + array_push($return_array, $key .'='. $val); + } + + } + + return join("&", $return_array); + } + + + private function _generateSignature () + { + $secretKey = ''; + if(isset($this->_secrets['shared_secret'])) + { + $secretKey = self::_oauthEscape($this->_secrets['shared_secret']); + } + + $secretKey .= '&'; + if(isset($this->_secrets['oauth_secret'])) + { + $secretKey .= self::_oauthEscape($this->_secrets['oauth_secret']); + } + + switch($this->_parameters['oauth_signature_method']) + { + case 'PLAINTEXT': + return urlencode($secretKey);; + case 'HMAC-SHA1': + $this->sbs = self::_oauthEscape($this->_action).'&'.self::_oauthEscape($this->_path).'&'.self::_oauthEscape($this->_normalizedParameters()); + + return base64_encode(hash_hmac('sha1',$this->sbs,$secretKey,TRUE)); + default: + throw new OAuthSimpleException('Unknown signature method for OAuthSimple'); + break; + } + } +} + +class OAuthSimpleException extends Exception { + + public function __construct($err, $isDebug = FALSE) + { + self::log_error($err); + if ($isDebug) + { + self::display_error($err, TRUE); + } + } + + public static function log_error($err) + { + error_log($err, 0); + } + + public static function display_error($err, $kill = FALSE) + { + print_r($err); + if ($kill === FALSE) + { + die(); + } + } +} diff --git a/DropBoxPhp/sample-form.php b/DropBoxPhp/sample-form.php new file mode 100644 index 0000000..c439f63 --- /dev/null +++ b/DropBoxPhp/sample-form.php @@ -0,0 +1,85 @@ + "ft0zodv89xx804e", + 'app_secret' => "ut43sn7m9wufy3s", + 'app_full_access' => true, +),'it'); + +handle_dropbox_auth($dropbox); // see below + +// if there is no upload, show the form +if(empty($_FILES['the_upload'])) { +?> +
+

+ + +

+

+
+"; + echo "\r\n\r\nUploading $upload_name:\r\n"; + $meta = $dropbox->UploadFile($_FILES["the_upload"]["tmp_name"], $upload_name); + print_r($meta); + echo "\r\n done!"; + echo ""; +} + + +// ================================================================================ +// store_token, load_token, delete_token are SAMPLE functions! please replace with your own! +function store_token($token, $name) +{ + file_put_contents("tokens/$name.token", serialize($token)); +} + +function load_token($name) +{ + if(!file_exists("tokens/$name.token")) return null; + return @unserialize(@file_get_contents("tokens/$name.token")); +} + +function delete_token($name) +{ + @unlink("tokens/$name.token"); +} +// ================================================================================ + +function handle_dropbox_auth($dropbox) +{ + // first try to load existing access token + $access_token = load_token("access"); + if(!empty($access_token)) { + $dropbox->SetAccessToken($access_token); + } + elseif(!empty($_GET['auth_callback'])) // are we coming from dropbox's auth page? + { + // then load our previosly created request token + $request_token = load_token($_GET['oauth_token']); + if(empty($request_token)) die('Request token not found!'); + + // get & store access token, the request token is not needed anymore + $access_token = $dropbox->GetAccessToken($request_token); + store_token($access_token, "access"); + delete_token($_GET['oauth_token']); + } + + // checks if access token is required + if(!$dropbox->IsAuthorized()) + { + // redirect user to dropbox auth page + $return_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?auth_callback=1"; + $auth_url = $dropbox->BuildAuthorizeUrl($return_url); + $request_token = $dropbox->GetRequestToken(); + store_token($request_token, $request_token['t']); + die("Authentication required. Click here."); + } +} \ No newline at end of file diff --git a/DropBoxPhp/sample.php b/DropBoxPhp/sample.php new file mode 100644 index 0000000..393023b --- /dev/null +++ b/DropBoxPhp/sample.php @@ -0,0 +1,133 @@ + + * @copyright Fabian Schlieper 2012 + * @version 1.1 + * @license See license.txt + * + */ + + +// these 2 lines are just to enable error reporting and disable output buffering (don't include this in you application!) +error_reporting(E_ALL); +enable_implicit_flush(); +// -- end of unneeded stuff + +// if there are many files in your Dropbox it can take some time, so disable the max. execution time +set_time_limit(0); + +require_once("DropboxClient.php"); + +// you have to create an app at https://www.dropbox.com/developers/apps and enter details below: +$dropbox = new DropboxClient(array( + 'app_key' => "ft0zodv89xx804e", + 'app_secret' => "ut43sn7m9wufy3s", + 'app_full_access' => true, +),'it'); + + +// first try to load existing access token +$access_token = load_token("access"); +if(!empty($access_token)) { + $dropbox->SetAccessToken($access_token); + echo "loaded access token:"; + print_r($access_token); +} +elseif(!empty($_GET['auth_callback'])) // are we coming from dropbox's auth page? +{ + // then load our previosly created request token + $request_token = load_token($_GET['oauth_token']); + if(empty($request_token)) die('Request token not found!'); + + // get & store access token, the request token is not needed anymore + $access_token = $dropbox->GetAccessToken($request_token); + store_token($access_token, "access"); + delete_token($_GET['oauth_token']); +} + +// checks if access token is required +if(!$dropbox->IsAuthorized()) +{ + // redirect user to dropbox auth page + $return_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?auth_callback=1"; + $auth_url = $dropbox->BuildAuthorizeUrl($return_url); + $request_token = $dropbox->GetRequestToken(); + store_token($request_token, $request_token['t']); + die("Authentication required. Click here."); +} + +echo "
";
+echo "Account:\r\n";
+print_r($dropbox->GetAccountInfo());
+
+$files = $dropbox->GetFiles("",false);
+
+echo "\r\n\r\nFiles:\r\n";
+print_r(array_keys($files));
+
+if(!empty($files)) {
+	$file = reset($files);
+	$test_file = "test_download_".basename($file->path);
+	
+	echo "\r\n\r\nMeta data of $file->path:\r\n";
+	print_r($dropbox->GetMetadata($file->path));
+	
+	echo "\r\n\r\nDownloading $file->path:\r\n";
+	print_r($dropbox->DownloadFile($file, $test_file));
+		
+	echo "\r\n\r\nUploading $test_file:\r\n";
+	print_r($dropbox->UploadFile($test_file));
+	echo "\r\n done!";	
+	
+	echo "\r\n\r\nRevisions of $test_file:\r\n";	
+	print_r($dropbox->GetRevisions($test_file));
+}
+	
+echo "\r\n\r\nSearching for JPG files:\r\n";	
+$jpg_files = $dropbox->Search("/", ".jpg", 5);
+if(empty($jpg_files))
+	echo "Nothing found.";
+else {
+	print_r($jpg_files);
+	$jpg_file = reset($jpg_files);
+
+	echo "\r\n\r\nThumbnail of $jpg_file->path:\r\n";	
+	$img_data = base64_encode($dropbox->GetThumbnail($jpg_file->path));
+	echo "\"Generating";
+}
+
+
+function store_token($token, $name)
+{
+	if(!file_put_contents("tokens/$name.token", serialize($token)))
+		die('
Could not store token! Make sure that the directory `tokens` exists and is writable!'); +} + +function load_token($name) +{ + if(!file_exists("tokens/$name.token")) return null; + return @unserialize(@file_get_contents("tokens/$name.token")); +} + +function delete_token($name) +{ + @unlink("tokens/$name.token"); +} + + + + + +function enable_implicit_flush() +{ + @apache_setenv('no-gzip', 1); + @ini_set('zlib.output_compression', 0); + @ini_set('implicit_flush', 1); + for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); } + ob_implicit_flush(1); + echo ""; +} \ No newline at end of file diff --git a/DropBoxPhp/test_download_Apps b/DropBoxPhp/test_download_Apps new file mode 100644 index 0000000..d538cda --- /dev/null +++ b/DropBoxPhp/test_download_Apps @@ -0,0 +1 @@ +{"error": "File not found"} \ No newline at end of file diff --git a/DropBoxPhp/tokens/access.token b/DropBoxPhp/tokens/access.token new file mode 100644 index 0000000..42b3ffc --- /dev/null +++ b/DropBoxPhp/tokens/access.token @@ -0,0 +1 @@ +a:2:{s:1:"t";s:16:"2lfmugdr7rp3yp2q";s:1:"s";s:15:"i3nrl13aduhhufw";} \ No newline at end of file diff --git a/Service_Manut.zip b/Service_Manut.zip new file mode 100644 index 0000000..60e7b96 Binary files /dev/null and b/Service_Manut.zip differ diff --git a/config.inc.php b/config.inc.php index 100a90c..0342970 100644 --- a/config.inc.php +++ b/config.inc.php @@ -8,3 +8,7 @@ $allowedHost = array( "blog.gruppolapastamadre.it", "management.gruppolapastamadre.it" ); + +$dirRicetteDropBox = "IlLievitario/Images/Ricette"; + +?> \ No newline at end of file diff --git a/image.php b/image.php index 00f4d85..06715df 100644 --- a/image.php +++ b/image.php @@ -1,103 +1,62 @@ -get('/photos/thumbnail/:imageID(/:createImgTag)', function ($imageID, $createImgTag = 0) use ($app) { - $mysqlconnetion = new MysqlClass; - - $retObj = $mysqlconnetion->queryToObject("select type_format, image_thumbnail from immagini where id=" . $imageID, false); - $mysqlconnetion->disconnetti(); - - if($createImgTag) - echo ''; - else - { - $app->contentType($retObj["type_format"]); - echo $retObj['image_thumbnail']; - } -}); - -$app->get('/photos/:imageID(/:createImgTag)', function ($imageID, $createImgTag = 0) use ($app) { - $mysqlconnetion = new MysqlClass; - - $retObj = $mysqlconnetion->queryToObject("select type_format, image from immagini where id=" . $imageID, false); - $mysqlconnetion->disconnetti(); - - if($createImgTag) - echo ''; -}); - -$app->put('/photos/publish/:imageID', function ($imageID) use ($app) { - $mysqlconnetion = new MysqlClass; - - $query = "update immagini set published = 1, published_date = NOW() where ProfiloID = " . $imageID; - $mysqlconnetion->disconnetti(); - $mysqlconnetion->insertRecord($query); - $mysqlconnetion->disconnetti(); -}); - -$app->post('/photos', function () use ($app) { - $idRicette = $app->request()->post('ricetta_id'); - $profileID = $app->request()->post('keyStore'); - $imageFileName = $_FILES['image']["tmp_name"]; - - $layer = ImageWorkshop::initFromPath($imageFileName); - $layer->resizeByLargestSideInPixel(640, true); - - $layer->save(dirname($imageFileName), basename($imageFileName)); - - $imgData = addslashes(file_get_contents($imageFileName)); - - $layer->resizeByLargestSideInPixel(300, true); - - $layer->save(dirname($imageFileName), basename($imageFileName)); - - $ThumbImageData = addslashes(file_get_contents($imageFileName)); - -// istanza della classe - $mysqlconnetion = new MysqlClass; -//$mysqlconneti on->connetti(); - $query = "insert into immagini(id_ricette, type_format, image_thumbnail, image, from_profile_id, uploaded_date) " . - "values(" . $idRicette . ", '" . image_type_to_mime_type($image->image_type) . - "', '" . $ThumbImageData . "', '" . $imgData . "', '" . $profileID . "', NOW())"; - $newID = $mysqlconnetion->insertRecord($query); - $mysqlconnetion->disconnetti(); - - echo $newID; -}); - -$app->put('/photos/:imageID', function ($imageID) use ($app) { - $imageFileName = $_FILES['image']["tmp_name"]; - - $layer = ImageWorkshop::initFromPath($imageFileName); - $layer->resizeByLargestSideInPixel(640, true); - - $layer->save(dirname($imageFileName), basename($imageFileName)); - - $imgData = addslashes(file_get_contents($imageFileName)); - - $layer->resizeByLargestSideInPixel(300, true); - - $layer->save(dirname($imageFileName), basename($imageFileName)); - - $ThumbImageData = addslashes(file_get_contents($imageFileName)); - -// istanza della classe - $mysqlconnetion = new MysqlClass; -//$mysqlconneti on->connetti(); - $query = "update immagini set (type_format = '" . image_type_to_mime_type($image->image_type) . "', " . - "image_thumbnail = '" . $ThumbImageData . "', " . - "image = '" . $imgData . "' where id=" . $imageID; - - $newID = $mysqlconnetion->insertRecord($query); - $mysqlconnetion->disconnetti(); - - return $newID; -}); +get('/photo/thumbnail/:imageID(/:createImgTag)', function ($imageID, $createImgTag = 0) use ($app, $dirRicetteDropBox) { + $mysqlconnetion = new MysqlClass; + + $retObj = $mysqlconnetion->queryToObject("select type_format, id_ricette from immagini where id=" . $imageID, false); + $mysqlconnetion->disconnetti(); + + + $ext = ""; + if ($retObj["type_format"] == "image/jpeg") { + $ext = "jpeg"; + } else if ($retObj["type_format"] == "image/png") { + $ext = "png"; + } + + $folder = $dirRicetteDropBox . "/" . $retObj["id_ricette"]; + + $imageFileName = $imageID . "_thumb_ricetta." . $ext; + + $dropBoxObj = new myDropBox(); + + if ($createImgTag) { + echo ''; + } + else + $app->response->redirect($dropBoxObj->GetLink($folder . "/" . $imageFileName), 303); +}); + +$app->get('/photo/:imageID(/:createImgTag)', function ($imageID, $createImgTag = 0) use ($app, $dirRicetteDropBox) { + $mysqlconnetion = new MysqlClass; + + $retObj = $mysqlconnetion->queryToObject("select type_format, id_ricette from immagini where id=" . $imageID, false); + $mysqlconnetion->disconnetti(); + $ext = ""; + if ($retObj["type_format"] == "image/jpeg") { + $ext = "jpeg"; + } else if ($retObj["type_format"] == "image/png") { + $ext = "png"; + } + + $folder = $dirRicetteDropBox . "/" . $retObj["id_ricette"]; + + $imageFileName = $imageID . "_full_ricetta." . $ext; + + $dropBoxObj = new myDropBox(); + + if ($createImgTag) { + echo ''; + } + else + $app->response->redirect($dropBoxObj->GetLink($folder . "/" . $imageFileName), 303); +}); \ No newline at end of file diff --git a/image_backend.php b/image_backend.php new file mode 100644 index 0000000..87f913a --- /dev/null +++ b/image_backend.php @@ -0,0 +1,111 @@ +get('/photo/publish/:imageID', function ($imageID) use ($app) { + $mysqlconnetion = new MysqlClass; + + $query = "update immagini set published = 1, published_date = NOW() where id = " . $imageID; + + $mysqlconnetion->insertRecord($query); + $mysqlconnetion->disconnetti(); +}); + +$app->delete('/photo/:imageID', function ($imageID) use ($app,$dirRicetteDropBox) { + $mysqlconnetion = new MysqlClass; + + $query = "select id_ricette, type_format from immagini where id = " . $imageID; + $retObj = $mysqlconnetion->queryToObject($query, false); + + $ext = ""; + if ($retObj["type_format"] == "image/jpeg") { + $ext = "jpeg"; + } else if ($retObj["type_format"] == "image/png") { + $ext = "png"; + } + + $dropBoxObj = new myDropBox(); + $folder = $dirRicetteDropBox . "/" . $retObj["id_ricette"]; + $imageFileName = $imageID . "_full_ricetta." . $ext; + $dropBoxObj->Delete($folder . "/" . $imageFileName); + + $imageFileName = $imageID . "_medium_ricetta." . $ext; + $dropBoxObj->Delete($folder . "/" . $imageFileName); + + $imageFileName = $imageID . "_thumb_ricetta." . $ext; + $dropBoxObj->Delete($folder . "/" . $imageFileName); + + $query = "delete from immagini where id = " . $imageID; + $mysqlconnetion->executeQuery($query); + $mysqlconnetion->disconnetti(); +}); + +$app->post('/photos', function () use ($app, $dirRicetteDropBox) { + $idRicette = $app->request()->post('ricetta_id'); + $profileID = $app->request()->post('keyStore'); + $tmpFileName = $_FILES['image']["tmp_name"]; + $layer = ImageWorkshop::initFromPath($tmpFileName); + // istanza della classe + $mysqlconnetion = new MysqlClass; + //$mysqlconneti on->connetti(); + $query = "insert into immagini(id_ricette, type_format, from_profile_id, uploaded_date) " . + "values(" . $idRicette . ", '" . image_type_to_mime_type(exif_imagetype($tmpFileName)) . + "', '" . $profileID . "', NOW())"; + $newID = $mysqlconnetion->insertRecord($query); + $ext = image_type_to_extension(exif_imagetype($tmpFileName), FALSE); + + $folder = $dirRicetteDropBox . "/" . $idRicette; + $imageFileName = $newID . "_full_ricetta." . $ext; + + $dropBoxObj = new myDropBox(); + + resizeImage($dropBoxObj, $layer, 640, dirname($tmpFileName), $imageFileName, $folder); + + $imageMediumFileName = $newID . "_medium_ricetta." . $ext; + + resizeImage($dropBoxObj, $layer, 320, dirname($tmpFileName), $imageMediumFileName, $folder); + + $thumbFileName = $newID . "_thumb_ricetta." . $ext; + + resizeImage($dropBoxObj, $layer, 80, dirname($tmpFileName), $thumbFileName, $folder); + + $mysqlconnetion->disconnetti(); + + echo $newID; +}); + +$app->put('/photos/:imageID', function ($imageID) use ($app, $dirRicetteDropBox) { + $tmpFileName = $_FILES['image']["tmp_name"]; + $layer = ImageWorkshop::initFromPath($tmpFileName); +// istanza della classe + $mysqlconnetion = new MysqlClass; +//$mysqlconneti on->connetti(); + $query = "update immagini set (type_format = '" . image_type_to_mime_type(exif_imagetype($tmpFileName)) . "', " . + " where id=" . $imageID; + + $newID = $mysqlconnetion->insertRecord($query); + + $folder = $dirRicetteDropBox . "/" . $newID; + $imageFileName = $newID . "_full_ricetta." . $ext; + + resizeImage($dropBoxObj, $layer, 640, dirname($tmpFileName), $imageFileName, $folder); + + $imageMediumFileName = $newID . "_medium_ricetta." . $ext; + + resizeImage($dropBoxObj, $layer, 320, dirname($tmpFileName), $imageMediumFileName, $folder); + + $thumbFileName = $newID . "_thumb_ricetta." . $ext; + + resizeImage($dropBoxObj, $layer, 80, dirname($tmpFileName), $thumbFileName, $folder); + + $mysqlconnetion->disconnetti(); + + return $newID; +}); diff --git a/include.php b/include.php index 945b365..dc4072b 100644 --- a/include.php +++ b/include.php @@ -12,8 +12,10 @@ require_once 'Slim/Slim.php'; $app = new \Slim\Slim(); +date_default_timezone_set('Europe/Rome'); + $app->hook('slim.before.router', function () use ($app, $allowedHost) { - $currentRefererRequest = $app->request()->getReferer(); + /*$currentRefererRequest = $app->request()->getReferer(); $currentRefererRequest = substr($currentRefererRequest, 7); //Senza http:// $indexDoublePoint = strpos($currentRefererRequest, ':'); $indexFirstSlash = strpos($currentRefererRequest, '/'); @@ -29,7 +31,7 @@ $app->hook('slim.before.router', function () use ($app, $allowedHost) { { $app->halt(403, "Request arrive from host not allowed " . $currentHostRequest ); return; - } + }*/ if(isset($_SERVER['HTTP_ORIGIN'])) header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); diff --git a/management.php b/management.php index 9a55781..3567410 100644 --- a/management.php +++ b/management.php @@ -30,7 +30,7 @@ $app->get('/typeqtys', function () use ($app) { returnJsonWithDecode($app, $callbackFn, $retObj); }); -$app->get('/categoryitems/:catID', function ($categoryID) use ($app) { +$app->get('/ricette/:catID', function ($categoryID) use ($app) { $callbackFn = $app->request()->get('callback'); $mysqlconnetion = new MysqlClass; //$mysqlconnetion->connetti(); @@ -197,6 +197,18 @@ $app->get('/statistics/themesUsage', function () use ($app) { $query = "SELECT 'TemaUI' as Type, TemaUI as Serie, COUNT(TemaUI) as CountSerie from profilo GROUP BY TemaUI"; + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $retObj = $mysqlconnetion->queryToObject($query); + $mysqlconnetion->disconnetti(); + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/profiles', function () use ($app) { + $callbackFn = $app->request()->get('callback'); + + $query = "SELECT ProfiloID as id, Name as name from profilo where name <> '' order by Name"; + $mysqlconnetion = new MysqlClass; //$mysqlconnetion->connetti(); $retObj = $mysqlconnetion->queryToObject($query); diff --git a/myDropBoxObj.php b/myDropBoxObj.php new file mode 100644 index 0000000..61d8273 --- /dev/null +++ b/myDropBoxObj.php @@ -0,0 +1,83 @@ +dropbox = new DropboxClient( + array( + 'app_key' => "ft0zodv89xx804e", + 'app_secret' => "ut43sn7m9wufy3s", + 'app_full_access' => true + ), 'it'); + $this->internalLoad(); + } + + protected function internalLoad() { + // first try to load existing access token + $access_token = $this->load_token("access"); + if (!empty($access_token)) { + $this->dropbox->SetAccessToken($access_token); + //echo "loaded access token:"; + //print_r($access_token); + } elseif (!empty($_GET['auth_callback'])) { // are we coming from dropbox's auth page? + // then load our previosly created request token + $request_token = $this->load_token($_GET['oauth_token']); + if (empty($request_token)) + die('Request token not found!'); + // get & store access token, the request token is not needed anymore + $access_token = $this->dropbox->GetAccessToken($request_token); + $this->store_token($access_token, "access"); + $this->delete_token($_GET['oauth_token']); + } + // checks if access token is required + if (!$this->dropbox->IsAuthorized()) { + // redirect user to dropbox auth page + $return_url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?auth_callback=1"; + $auth_url = $this->dropbox->BuildAuthorizeUrl($return_url); + $request_token = $this->dropbox->GetRequestToken(); + $this->store_token($request_token, $request_token['t']); + die("Authentication required. Click here."); + } + } + + public function UploadFile($fileToUpload, $dropBoxPath) { + $ret = $this->dropbox->UploadFile($fileToUpload, $dropBoxPath); + return true; + } + + public function GetLink($dropBoxPathFile) { + return $this->dropbox->GetLink($dropBoxPathFile, false, false); + } + + public function CreateFolder($dropBoxPath) { + $ret = $this->dropbox->CreateFolder($dropBoxPath); + return true; + } + + public function Delete($dropBoxPath) { + $ret = $this->dropbox->Delete($dropBoxPath); + return true; + } + + private function store_token($token, $name) { + if (!file_put_contents("tokens/$name.token", serialize($token))) + die('
Could not store token! Make sure that the directory `tokens` exists and is writable!'); + } + + private function load_token($name) { + if (!file_exists("tokens/$name.token")) + return null; + return @unserialize(@file_get_contents("tokens/$name.token")); + } + + private function delete_token($name) { + @unlink("tokens/$name.token"); + } + +} diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..ee7e44e --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,6 @@ +copy.src.files=false +copy.src.on.open=false +copy.src.target= +index.file= +run.as=LOCAL +url=http://localhost:8081/Service_Manut/ diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..284eeec --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..8b7302c --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,7 @@ +include.path=${php.global.include.path} +php.version=PHP_54 +source.encoding=UTF-8 +src.dir=. +tags.asp=false +tags.short=false +web.root=. diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..ed51825 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,9 @@ + + + org.netbeans.modules.php.project + + + Service_Manut + + + diff --git a/ricette.php b/ricette.php index e63a742..b9b45f4 100644 --- a/ricette.php +++ b/ricette.php @@ -33,11 +33,13 @@ $app->get('/typeqtys', function () use ($app) { returnJson($app, $callbackFn, $retObj); }); -$app->get('/categoryitems/:catID', function ($categoryID) use ($app) { +$app->get('/ricette/:catID', function ($categoryID) use ($app) { $callbackFn = $app->request()->get('callback'); $mysqlconnetion = new MysqlClass; //$mysqlconnetion->connetti(); - $query = "select ID as ricetta_id, titolo, autore, valutazione, difficolta from ricette where ID_CATEGORIA = " . $categoryID . " order by titolo, autore"; + $query = "select * from (select ID as ricetta_id, titolo, autore, valutazione, difficolta, " . + "(select id from immagini where immagini.id_ricette = ricette.id and published = 1 order by published_date limit 1) as firstImage " . + "from ricette where ricette.ID_CATEGORIA = " . $categoryID . " order by titolo, autore) as TMP"; $retObj = $mysqlconnetion->queryToObject($query); $mysqlconnetion->disconnetti(); @@ -48,7 +50,7 @@ $app->get('/categoryitems/:catID', function ($categoryID) use ($app) { returnJson($app, $callbackFn, $retObj); }); -$app->get('/categoryitems/:categoryID/mostvote(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { +$app->get('/ricette/:categoryID/mostvote(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { $callbackFn = $app->request()->get('callback'); $mysqlconnetion = new MysqlClass; //$mysqlconnetion->connetti(); @@ -63,7 +65,7 @@ $app->get('/categoryitems/:categoryID/mostvote(/:numItems)', function ($category returnJson($app, $callbackFn, $retObj); }); -$app->get('/categoryitems/:categoryID/lastinserted(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { +$app->get('/ricette/:categoryID/lastinserted(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { $callbackFn = $app->request()->get('callback'); $mysqlconnetion = new MysqlClass; //$mysqlconnetion->connetti(); @@ -78,7 +80,7 @@ $app->get('/categoryitems/:categoryID/lastinserted(/:numItems)', function ($cate returnJson($app, $callbackFn, $retObj); }); -$app->get('/categoryitems/search/:numItems/:startItem(/:categoryId(/:difficolta(/:titolo)))', +$app->get('/ricette/search/:numItems/:startItem(/:categoryId(/:difficolta(/:titolo)))', function ($numItems = 10, $startItem = 0, $categoryId = 0, $difficolta = 0, $titolo = "") use ($app) { $callbackFn = $app->request()->get('callback'); $mysqlconnetion = new MysqlClass; diff --git a/serviceapp.php b/serviceapp.php index cd1db2e..c5e9a38 100644 --- a/serviceapp.php +++ b/serviceapp.php @@ -2,15 +2,16 @@ include_once "./include.php"; -$app->group('/api', function () use ($app) { +$app->group('/api', function () use ($app, $dirRicetteDropBox) { include "./ricette.php"; include "./profile.php"; include "./image.php"; include "./spacciatoripm.php"; }); -$app->group('/backend', function () use ($app) { +$app->group('/backend', function () use ($app, $dirRicetteDropBox) { include "./management.php"; + include "./image_backend.php"; }); //include "./image.php"; diff --git a/t.php b/t.php new file mode 100644 index 0000000..ee3b988 --- /dev/null +++ b/t.php @@ -0,0 +1,178 @@ +get('/categories', function () use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconneti on->connetti(); + $retObj = $mysqlconnetion->queryToObject("select ID as category_id, NAME as name from categorie order by name"); + $mysqlconnetion->disconnetti(); + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/typeingredients', function () use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $retObj = $mysqlconnetion->queryToObject("select ID as tipo_ingredienti_id, name from tipo_ingredienti order by name"); + $mysqlconnetion->disconnetti(); + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/typeqtys', function () use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $retObj = $mysqlconnetion->queryToObject("select ID as tipo_quantita_id, name from tipo_quantita"); + $mysqlconnetion->disconnetti(); + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/categoryitems/:catID', function ($categoryID) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $query = "select ID as ricetta_id, titolo, autore, valutazione, difficolta from ricette where ID_CATEGORIA = " . $categoryID . " order by titolo, autore"; + $retObj = $mysqlconnetion->queryToObject($query); + $mysqlconnetion->disconnetti(); + + foreach ($retObj as $ele) { + $ele["titolo"] = html_entity_decode($ele["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + } + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/categoryitems/:categoryID/mostvote(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $query = "select ID as ricetta_id, titolo, autore from ricette where ID_CATEGORIA = " . $categoryID . " order by Valutazione desc, titolo, autore LIMIT " . $numItems; + $retObj = $mysqlconnetion->queryToObject($query); + $mysqlconnetion->disconnetti(); + + foreach ($retObj as $ele) { + $ele["titolo"] = html_entity_decode($ele["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + } + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/categoryitems/:categoryID/lastinserted(/:numItems)', function ($categoryID, $numItems = 10) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + //$mysqlconnetion->connetti(); + $query = "select ID as ricetta_id, titolo, autore from ricette where ID_CATEGORIA = " . $categoryID . " order by Data_creazione desc, titolo, autore LIMIT " . $numItems; + $retObj = $mysqlconnetion->queryToObject($query); + $mysqlconnetion->disconnetti(); + + foreach ($retObj as $ele) { + $ele["titolo"] = html_entity_decode($ele["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + } + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/categoryitems/search/:numItems(/:categoryId(/:difficolta(/:titolo)))', + function ($numItems = 10, $categoryId = 0, $difficolta = 0, $titolo = "") use ($app) { + $callbackFn = $app->request()->get('callback'); + //$filterItem = json_decode($app->request()->post('post')); + $mysqlconnetion = new MysqlClass; + $query = "select ricette.ID as ricetta_id, categorie.name AS categoria_name, titolo, autore, valutazione, difficolta from ricette" + . " INNER JOIN categorie ON categorie.ID = ricette.id_categoria" + . " where 1 = 1"; + if ($categoryId > 0) { + $query = $query . " AND ID_CATEGORIA = " . $categoryId; + } + if ($titolo != null && $titolo != "") { + foreach (explode(" ", htmlentities(urldecode($titolo))) as $ele) + $query = $query . " AND titolo like '%" . $ele . "%'"; + } + if ($difficolta > 0) { + $query = $query . " AND difficolta = " . $difficolta; + } + $query = $query . " order by titolo, autore LIMIT " . $numItems; + $retObj = $mysqlconnetion->queryToObject($query); + $mysqlconnetion->disconnetti(); + + foreach ($retObj as $ele) { + $ele["titolo"] = html_entity_decode($ele["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + } + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/ricetta/body/:itemID', function ($itemID) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + + $query = "UPDATE ricette Set valutazione = valutazione + 1 WHERE ricette.ID = " . $itemID; + $mysqlconnetion->executeQuery($query); + + $query = "SELECT id_categoria, categorie.name AS categoria_name, ricette.ID AS ricetta_id, titolo, procedimento, autore, link_fonte, link_youtube, valutazione FROM ricette INNER JOIN categorie ON categorie.ID = ricette.id_categoria WHERE ricette.ID = " . $itemID; + $retObj = $mysqlconnetion->queryToObject($query); + + $query2 = "select ingredienti.id_tipo_ingredienti, tipo_ingredienti.name as nome_ingrediente, quantita, ingredienti.id_tipo_quantita, tipo_quantita.Name as unita, note, posizione from ingredienti " . + "inner join tipo_ingredienti on ingredienti.ID_TIPO_INGREDIENTI = tipo_ingredienti.ID " . + "left outer join tipo_quantita on ingredienti.ID_TIPO_QUANTITA = tipo_quantita.ID " . + "where ingredienti.ID_RICETTE = " . $itemID . " order by ingredienti.posizione"; + + $retObj2 = $mysqlconnetion->queryToObject($query2); + + $retObj[0]["titolo"] = html_entity_decode($retObj[0]["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + $retObj[0]["procedimento"] = html_entity_decode($retObj[0]["procedimento"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + $retObj[0]["ingredienti"] = $retObj2; + + $mysqlconnetion->disconnetti(); + + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/ricetta/header/:itemID', function ($itemID) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + $query = "UPDATE ricette Set valutazione = valutazione + 1 WHERE ricette.ID = " . $itemID; + $mysqlconnetion->executeQuery($query); + $query = "SELECT id_categoria, categorie.name AS categoria_name, ricette.ID AS ricetta_id, titolo, procedimento, autore, link_fonte, link_youtube, valutazione FROM ricette INNER JOIN categorie ON categorie.ID = ricette.id_categoria WHERE ricette.ID = " . $itemID; + $retObj = $mysqlconnetion->queryToObject($query); + $retObj[0]["titolo"] = html_entity_decode($retObj[0]["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + $retObj[0]["procedimento"] = html_entity_decode($retObj[0]["procedimento"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'); + $data = $retObj[0]["link_youtube"]; + $output = array(); + if ($data != "") { + $d = explode(";", $data); + $index = 0; + foreach ($d as $ele) { + $obj["VideoID"] = $ele; + $output[$index] = $obj; + $index++; + } + } + $retObj[0]["link_youtube"] = $output; + $mysqlconnetion->disconnetti(); + returnJson($app, $callbackFn, $retObj); +}); + +$app->get('/ricetta/ingredienti/:itemID', function ($itemID) use ($app) { + $callbackFn = $app->request()->get('callback'); + $mysqlconnetion = new MysqlClass; + $query2 = "select ingredienti.id_tipo_ingredienti, tipo_ingredienti.name as nome_ingrediente, quantita, ingredienti.id_tipo_quantita, tipo_quantita.Name as unita, note, posizione from ingredienti " . + "inner join tipo_ingredienti on ingredienti.ID_TIPO_INGREDIENTI = tipo_ingredienti.ID " . + "left outer join tipo_quantita on ingredienti.ID_TIPO_QUANTITA = tipo_quantita.ID " . + "where ingredienti.ID_RICETTE = " . $itemID . " order by ingredienti.posizione"; + + $retObj2 = $mysqlconnetion->queryToObject($query2); + + //$retObj[0]["titolo"] = html_entity_decode($retObj[0]["titolo"]); + //$retObj[0]["procedimento"] = html_entity_decode($retObj[0]["procedimento"]); + //$retObj[0]["ingredienti"] = $retObj2; + + $mysqlconnetion->disconnetti(); + + returnJson($app, $callbackFn, $retObj2); +}); +?> diff --git a/tokens/access.token b/tokens/access.token new file mode 100644 index 0000000..ba753a0 --- /dev/null +++ b/tokens/access.token @@ -0,0 +1 @@ +a:2:{s:1:"t";s:16:"s1ti76srenx4b7aj";s:1:"s";s:15:"qshrdehad4dzz6n";} \ No newline at end of file diff --git a/utility.php b/utility.php index 76caec5..0e5573f 100644 --- a/utility.php +++ b/utility.php @@ -1,5 +1,14 @@ resizeByLargestSideInPixel($size, true); + $layer->save($dir, $fileName); + + try { + $dropBoxObj->CreateFolder($dirDropBox); + } catch (DropboxException $ex) { + } + + $dropBoxObj->UploadFile($fullPath, $dirDropBox . "/" . $fileName); +} + ?>