git-svn-id: https://msi/svn/firstRepo/Service/branches/Slim3@39 0f545695-f87b-41b6-9a03-7f16563b5454
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<ifModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*)$ serviceapp.php [QSA,L]
|
||||
</ifModule>
|
||||
@@ -0,0 +1,672 @@
|
||||
<?php
|
||||
/**
|
||||
* DropPHP - A simple Dropbox client that works without cURL.
|
||||
*
|
||||
* http://fabi.me/en/php-projects/dropphp-dropbox-api-client/
|
||||
*
|
||||
*
|
||||
* @author Fabian Schlieper <[email protected]>
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,532 @@
|
||||
<?php
|
||||
/**
|
||||
* OAuthSimple - A simpler version of OAuth
|
||||
*
|
||||
* https://github.com/jrconlin/oauthsimple
|
||||
*
|
||||
* @author jr conlin <[email protected]>
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
error_reporting(E_ALL);
|
||||
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');
|
||||
|
||||
handle_dropbox_auth($dropbox); // see below
|
||||
|
||||
// if there is no upload, show the form
|
||||
if(empty($_FILES['the_upload'])) {
|
||||
?>
|
||||
<form enctype="multipart/form-data" method="POST" action="">
|
||||
<p>
|
||||
<label for="file">Upload File</label>
|
||||
<input type="file" name="the_upload" />
|
||||
</p>
|
||||
<p><input type="submit" name="submit-btn" value="Upload!"></p>
|
||||
</form>
|
||||
<?php } else {
|
||||
|
||||
$upload_name = $_FILES["the_upload"]["name"];
|
||||
echo "<pre>";
|
||||
echo "\r\n\r\n<b>Uploading $upload_name:</b>\r\n";
|
||||
$meta = $dropbox->UploadFile($_FILES["the_upload"]["tmp_name"], $upload_name);
|
||||
print_r($meta);
|
||||
echo "\r\n done!";
|
||||
echo "</pre>";
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================
|
||||
// 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. <a href='$auth_url'>Click here.</a>");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* DropPHP sample
|
||||
*
|
||||
* http://fabi.me/en/php-projects/dropphp-dropbox-api-client/
|
||||
*
|
||||
* @author Fabian Schlieper <[email protected]>
|
||||
* @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. <a href='$auth_url'>Click here.</a>");
|
||||
}
|
||||
|
||||
echo "<pre>";
|
||||
echo "<b>Account:</b>\r\n";
|
||||
print_r($dropbox->GetAccountInfo());
|
||||
|
||||
$files = $dropbox->GetFiles("",false);
|
||||
|
||||
echo "\r\n\r\n<b>Files:</b>\r\n";
|
||||
print_r(array_keys($files));
|
||||
|
||||
if(!empty($files)) {
|
||||
$file = reset($files);
|
||||
$test_file = "test_download_".basename($file->path);
|
||||
|
||||
echo "\r\n\r\n<b>Meta data of <a href='".$dropbox->GetLink($file)."'>$file->path</a>:</b>\r\n";
|
||||
print_r($dropbox->GetMetadata($file->path));
|
||||
|
||||
echo "\r\n\r\n<b>Downloading $file->path:</b>\r\n";
|
||||
print_r($dropbox->DownloadFile($file, $test_file));
|
||||
|
||||
echo "\r\n\r\n<b>Uploading $test_file:</b>\r\n";
|
||||
print_r($dropbox->UploadFile($test_file));
|
||||
echo "\r\n done!";
|
||||
|
||||
echo "\r\n\r\n<b>Revisions of $test_file:</b>\r\n";
|
||||
print_r($dropbox->GetRevisions($test_file));
|
||||
}
|
||||
|
||||
echo "\r\n\r\n<b>Searching for JPG files:</b>\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\n<b>Thumbnail of $jpg_file->path:</b>\r\n";
|
||||
$img_data = base64_encode($dropbox->GetThumbnail($jpg_file->path));
|
||||
echo "<img src=\"data:image/jpeg;base64,$img_data\" alt=\"Generating PDF thumbnail failed!\" style=\"border: 1px solid black;\" />";
|
||||
}
|
||||
|
||||
|
||||
function store_token($token, $name)
|
||||
{
|
||||
if(!file_put_contents("tokens/$name.token", serialize($token)))
|
||||
die('<br />Could not store token! <b>Make sure that the directory `tokens` exists and is writable!</b>');
|
||||
}
|
||||
|
||||
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 "<!-- ".str_repeat(' ', 2000)." -->";
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"error": "File not found"}
|
||||
@@ -0,0 +1 @@
|
||||
a:2:{s:1:"t";s:16:"2lfmugdr7rp3yp2q";s:1:"s";s:15:"i3nrl13aduhhufw";}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
class MysqlClass {
|
||||
|
||||
// parametri per la connessione al database
|
||||
private $nomehost = "localhost";
|
||||
private $nomeuser = "root";
|
||||
private $password = "root";
|
||||
private $mydb = "w18092_ricettario";
|
||||
/*
|
||||
private $nomehost = "sql.gruppolapastamadre.it";
|
||||
private $nomeuser = "w18092_ricuser";
|
||||
private $password = "RTvg0o6IESoqQyx8CCJn";
|
||||
private $mydb = "w18092_ricettario";
|
||||
*/
|
||||
// controllo sulle connessioni attive
|
||||
private $attiva = false;
|
||||
private $connessione = null;
|
||||
|
||||
// funzione per la connessione a MySQL
|
||||
public function connetti() {
|
||||
if (!$this->attiva) {
|
||||
$this->connessione = mysqli_connect($this->nomehost, $this->nomeuser, $this->password);
|
||||
if ($this->connessione == FALSE)
|
||||
die(mysqli_error());
|
||||
mysqli_select_db($this->connessione, $this->mydb) or die("Errore nella selezione del database. Verificare i parametri nel file config.inc.php");
|
||||
$this->attiva = true;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeQuery($queryStr) {
|
||||
$this->connetti();
|
||||
|
||||
if (!$res = mysqli_query($this->connessione, $queryStr))
|
||||
die(mysqli_error());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function insertRecord($queryStr) {
|
||||
$this->connetti();
|
||||
|
||||
if (!$res = mysqli_query($this->connessione, $queryStr))
|
||||
die(mysqli_error());
|
||||
return mysqli_insert_id($this->connessione);
|
||||
}
|
||||
|
||||
public function queryToObject($queryStr, $encode = true) {
|
||||
$this->connetti();
|
||||
|
||||
$sth = mysqli_query($this->connessione, $queryStr) or die(mysqli_error());
|
||||
|
||||
if($encode){
|
||||
$rows = array();
|
||||
while ($r = mysqli_fetch_assoc($sth)) {
|
||||
array_push($rows, array_map('utf8_encode', $r));
|
||||
}
|
||||
mysqli_free_result($sth);
|
||||
return $rows;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysqli_fetch_array($sth);
|
||||
}
|
||||
}
|
||||
|
||||
// funzione per la chiusura della connessione
|
||||
public function disconnetti() {
|
||||
if ($this->attiva) {
|
||||
if (mysqli_close($this->connessione)) {
|
||||
$this->attiva = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->disconnetti();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop\Core\Exception;
|
||||
|
||||
use PHPImageWorkshop\Exception\ImageWorkshopBaseException as ImageWorkshopBaseException;
|
||||
|
||||
// If no autoloader, uncomment these lines:
|
||||
require_once(__DIR__.'/../../Exception/ImageWorkshopBaseException.php');
|
||||
|
||||
/**
|
||||
* ImageWorkshopLayerException
|
||||
*
|
||||
* Manage ImageWorkshopLayer exceptions
|
||||
*
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshopLayerException extends ImageWorkshopBaseException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop\Core\Exception;
|
||||
|
||||
use PHPImageWorkshop\Exception\ImageWorkshopBaseException as ImageWorkshopBaseException;
|
||||
|
||||
// If no autoloader, uncomment these lines:
|
||||
require_once(__DIR__.'/../../Exception/ImageWorkshopBaseException.php');
|
||||
|
||||
/**
|
||||
* ImageWorkshopLibException
|
||||
*
|
||||
* Manage ImageWorkshopLib exceptions
|
||||
*
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshopLibException extends ImageWorkshopBaseException
|
||||
{
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop\Core;
|
||||
|
||||
use PHPImageWorkshop\Core\Exception\ImageWorkshopLibException as ImageWorkshopLibException;
|
||||
|
||||
// If no autoloader, uncomment these lines:
|
||||
require_once(__DIR__.'/Exception/ImageWorkshopLibException.php');
|
||||
|
||||
/**
|
||||
* ImageWorkshopLib class
|
||||
*
|
||||
* Contains some tools to help in some ImageWorkshop calculations
|
||||
*
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshopLib
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const ERROR_FONT_NOT_FOUND = 3;
|
||||
|
||||
/**
|
||||
* Calculate the left top positions of a layer inside a parent layer container
|
||||
* $position: http://phpimageworkshop.com/doc/22/corners-positions-schema-of-an-image.html
|
||||
*
|
||||
* @param integer $containerWidth
|
||||
* @param integer $containerHeight
|
||||
* @param integer $layerWidth
|
||||
* @param integer $layerHeight
|
||||
* @param integer $layerPositionX
|
||||
* @param integer $layerPositionY
|
||||
* @param string $position
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function calculatePositions($containerWidth, $containerHeight, $layerWidth, $layerHeight, $layerPositionX, $layerPositionY, $position = 'LT')
|
||||
{
|
||||
$position = strtolower($position);
|
||||
|
||||
if ($position == 'rt') {
|
||||
|
||||
$layerPositionX = $containerWidth - $layerWidth - $layerPositionX;
|
||||
|
||||
} elseif ($position == 'lb') {
|
||||
|
||||
$layerPositionY = $containerHeight - $layerHeight - $layerPositionY;
|
||||
|
||||
} elseif ($position == 'rb') {
|
||||
|
||||
$layerPositionX = $containerWidth - $layerWidth - $layerPositionX;
|
||||
$layerPositionY = $containerHeight - $layerHeight - $layerPositionY;
|
||||
|
||||
} elseif ($position == 'mm') {
|
||||
|
||||
$layerPositionX = (($containerWidth - $layerWidth) / 2) + $layerPositionX;
|
||||
$layerPositionY = (($containerHeight - $layerHeight) / 2) + $layerPositionY;
|
||||
|
||||
} elseif ($position == 'mt') {
|
||||
|
||||
$layerPositionX = (($containerWidth - $layerWidth) / 2) + $layerPositionX;
|
||||
|
||||
} elseif ($position == 'mb') {
|
||||
|
||||
$layerPositionX = (($containerWidth - $layerWidth) / 2) + $layerPositionX;
|
||||
$layerPositionY = $containerHeight - $layerHeight - $layerPositionY;
|
||||
|
||||
} elseif ($position == 'lm') {
|
||||
|
||||
$layerPositionY = (($containerHeight - $layerHeight) / 2) + $layerPositionY;
|
||||
|
||||
} elseif ($position == 'rm') {
|
||||
|
||||
$layerPositionX = $containerWidth - $layerWidth - $layerPositionX;
|
||||
$layerPositionY = (($containerHeight - $layerHeight) / 2) + $layerPositionY;
|
||||
}
|
||||
|
||||
return array(
|
||||
'x' => $layerPositionX,
|
||||
'y' => $layerPositionY,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Hex color to RGB color format
|
||||
*
|
||||
* @param string $hex
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function convertHexToRGB($hex)
|
||||
{
|
||||
return array(
|
||||
'R' => (int) base_convert(substr($hex, 0, 2), 16, 10),
|
||||
'G' => (int) base_convert(substr($hex, 2, 2), 16, 10),
|
||||
'B' => (int) base_convert(substr($hex, 4, 2), 16, 10),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new image resource var
|
||||
*
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param string $color
|
||||
* @param integer $opacity
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public static function generateImage($width = 100, $height = 100, $color = 'ffffff', $opacity = 127)
|
||||
{
|
||||
$RGBColors = ImageWorkshopLib::convertHexToRGB($color);
|
||||
|
||||
$image = imagecreatetruecolor($width, $height);
|
||||
imagesavealpha($image, true);
|
||||
$color = imagecolorallocatealpha($image, $RGBColors['R'], $RGBColors['G'], $RGBColors['B'], $opacity);
|
||||
imagefill($image, 0, 0, $color);
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dimension of a text
|
||||
*
|
||||
* @param $fontSize
|
||||
* @param $fontAngle
|
||||
* @param $fontFile
|
||||
* @param $text
|
||||
*
|
||||
* @return array or boolean
|
||||
*/
|
||||
public static function getTextBoxDimension($fontSize, $fontAngle, $fontFile, $text)
|
||||
{
|
||||
if (!file_exists($fontFile)) {
|
||||
throw new ImageWorkshopLibException('Can\'t find a font file at this path : "'.$fontFile.'".', static::ERROR_FONT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$box = imagettfbbox($fontSize, $fontAngle, $fontFile, $text);
|
||||
|
||||
if (!$box) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$minX = min(array($box[0], $box[2], $box[4], $box[6]));
|
||||
$maxX = max(array($box[0], $box[2], $box[4], $box[6]));
|
||||
$minY = min(array($box[1], $box[3], $box[5], $box[7]));
|
||||
$maxY = max(array($box[1], $box[3], $box[5], $box[7]));
|
||||
$width = ($maxX - $minX);
|
||||
$height = ($maxY - $minY);
|
||||
$left = abs($minX) + $width;
|
||||
$top = abs($minY) + $height;
|
||||
|
||||
// to calculate the exact bounding box, we write the text in a large image
|
||||
$img = @imagecreatetruecolor($width << 2, $height << 2);
|
||||
$white = imagecolorallocate($img, 255, 255, 255);
|
||||
$black = imagecolorallocate($img, 0, 0, 0);
|
||||
imagefilledrectangle($img, 0, 0, imagesx($img), imagesy($img), $black);
|
||||
|
||||
// for ensure that the text is completely in the image
|
||||
imagettftext($img, $fontSize, $fontAngle, $left, $top, $white, $fontFile, $text);
|
||||
|
||||
// start scanning (0=> black => empty)
|
||||
$rleft = $w4 = $width<<2;
|
||||
$rright = 0;
|
||||
$rbottom = 0;
|
||||
$rtop = $h4 = $height<<2;
|
||||
|
||||
for ($x = 0; $x < $w4; $x++) {
|
||||
|
||||
for ($y = 0; $y < $h4; $y++) {
|
||||
|
||||
if (imagecolorat($img, $x, $y)) {
|
||||
|
||||
$rleft = min($rleft, $x);
|
||||
$rright = max($rright, $x);
|
||||
$rtop = min($rtop, $y);
|
||||
$rbottom = max($rbottom, $y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imagedestroy($img);
|
||||
|
||||
return array(
|
||||
'left' => $left - $rleft,
|
||||
'top' => $top - $rtop,
|
||||
'width' => $rright - $rleft + 1,
|
||||
'height' => $rbottom - $rtop + 1,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy an image on another one and converse transparency
|
||||
*
|
||||
* @param resource $destImg
|
||||
* @param resource $srcImg
|
||||
* @param integer $destX
|
||||
* @param integer $destY
|
||||
* @param integer $srcX
|
||||
* @param integer $srcY
|
||||
* @param integer $srcW
|
||||
* @param integer $srcH
|
||||
* @param integer $pct
|
||||
*/
|
||||
public static function imageCopyMergeAlpha(&$destImg, &$srcImg, $destX, $destY, $srcX, $srcY, $srcW, $srcH, $pct = 0)
|
||||
{
|
||||
$destX = (int) $destX;
|
||||
$destY = (int) $destY;
|
||||
$srcX = (int) $srcX;
|
||||
$srcY = (int) $srcY;
|
||||
$srcW = (int) $srcW;
|
||||
$srcH = (int) $srcH;
|
||||
$pct = (int) $pct;
|
||||
$destW = imageSX($destImg);
|
||||
$destH = imageSY($destImg);
|
||||
|
||||
for ($y = 0; $y < $srcH + $srcY; $y++) {
|
||||
|
||||
for ($x = 0; $x < $srcW + $srcX; $x++) {
|
||||
|
||||
if ($x + $destX >= 0 && $x + $destX < $destW && $x + $srcX >= 0 && $x + $srcX < $srcW && $y + $destY >= 0 && $y + $destY < $destH && $y + $srcY >= 0 && $y + $srcY < $srcH) {
|
||||
|
||||
$destPixel = imageColorsForIndex($destImg, imageColorat($destImg, $x + $destX, $y + $destY));
|
||||
$srcImgColorat = imageColorat($srcImg, $x + $srcX, $y + $srcY);
|
||||
|
||||
if ($srcImgColorat >= 0) {
|
||||
|
||||
$srcPixel = imageColorsForIndex($srcImg, $srcImgColorat);
|
||||
|
||||
$srcAlpha = 1 - ($srcPixel['alpha'] / 127);
|
||||
$destAlpha = 1 - ($destPixel['alpha'] / 127);
|
||||
$opacity = $srcAlpha * $pct / 100;
|
||||
|
||||
if ($destAlpha >= $opacity) {
|
||||
$alpha = $destAlpha;
|
||||
}
|
||||
|
||||
if ($destAlpha < $opacity) {
|
||||
$alpha = $opacity;
|
||||
}
|
||||
|
||||
if ($alpha > 1) {
|
||||
$alpha = 1;
|
||||
}
|
||||
|
||||
if ($opacity > 0) {
|
||||
|
||||
$destRed = round((($destPixel['red'] * $destAlpha * (1 - $opacity))));
|
||||
$destGreen = round((($destPixel['green'] * $destAlpha * (1 - $opacity))));
|
||||
$destBlue = round((($destPixel['blue'] * $destAlpha * (1 - $opacity))));
|
||||
$srcRed = round((($srcPixel['red'] * $opacity)));
|
||||
$srcGreen = round((($srcPixel['green'] * $opacity)));
|
||||
$srcBlue = round((($srcPixel['blue'] * $opacity)));
|
||||
$red = round(($destRed + $srcRed ) / ($destAlpha * (1 - $opacity) + $opacity));
|
||||
$green = round(($destGreen + $srcGreen) / ($destAlpha * (1 - $opacity) + $opacity));
|
||||
$blue = round(($destBlue + $srcBlue ) / ($destAlpha * (1 - $opacity) + $opacity));
|
||||
|
||||
if ($red > 255) {
|
||||
$red = 255;
|
||||
}
|
||||
|
||||
if ($green > 255) {
|
||||
$green = 255;
|
||||
}
|
||||
|
||||
if ($blue > 255) {
|
||||
$blue = 255;
|
||||
}
|
||||
|
||||
$alpha = round((1 - $alpha) * 127);
|
||||
$color = imageColorAllocateAlpha($destImg, $red, $green, $blue, $alpha);
|
||||
imageSetPixel($destImg, $x + $destX, $y + $destY, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two image var
|
||||
*
|
||||
* @param resource $destinationImage
|
||||
* @param resource $sourceImage
|
||||
* @param integer $destinationPosX
|
||||
* @param integer $destinationPosY
|
||||
* @param integer $sourcePosX
|
||||
* @param integer $sourcePosY
|
||||
*/
|
||||
public static function mergeTwoImages(&$destinationImage, $sourceImage, $destinationPosX = 0, $destinationPosY = 0, $sourcePosX = 0, $sourcePosY = 0)
|
||||
{
|
||||
imageCopy($destinationImage, $sourceImage, $destinationPosX, $destinationPosY, $sourcePosX, $sourcePosY, imageSX($sourceImage), imageSY($sourceImage));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop\Exception;
|
||||
|
||||
/**
|
||||
* ImageWorkshopBaseException
|
||||
*
|
||||
* The inherited exception class
|
||||
*
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Bjørn Børresen | Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshopBaseException extends \Exception
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $message
|
||||
* @param integer $code
|
||||
* @param Exception $previous
|
||||
*/
|
||||
public function __construct($message, $code = 0, \Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* __toString method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__.": [{$this->code}]: {$this->message}\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop\Exception;
|
||||
|
||||
use PHPImageWorkshop\Exception\ImageWorkshopBaseException as ImageWorkshopBaseException;
|
||||
|
||||
// If no autoloader, uncomment these lines:
|
||||
require_once(__DIR__.'/ImageWorkshopBaseException.php');
|
||||
|
||||
/**
|
||||
* ImageWorkshopException
|
||||
*
|
||||
* Manage ImageWorkshop exceptions
|
||||
*
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshopException extends ImageWorkshopBaseException
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace PHPImageWorkshop;
|
||||
|
||||
use PHPImageWorkshop\Core\ImageWorkshopLayer as ImageWorkshopLayer;
|
||||
use PHPImageWorkshop\Core\ImageWorkshopLib as ImageWorkshopLib;
|
||||
use PHPImageWorkshop\Exception\ImageWorkshopException as ImageWorkshopException;
|
||||
|
||||
// If no autoloader, uncomment these lines:
|
||||
require_once(__DIR__.'/Core/ImageWorkshopLayer.php');
|
||||
require_once(__DIR__.'/Exception/ImageWorkshopException.php');
|
||||
|
||||
/**
|
||||
* ImageWorkshop class
|
||||
*
|
||||
* Use this class as a factory to initialize ImageWorkshop layers
|
||||
*
|
||||
* @version 2.0.6
|
||||
* @link http://phpimageworkshop.com
|
||||
* @author Sybio (Clément Guillemain / @Sybio01)
|
||||
* @license http://en.wikipedia.org/wiki/MIT_License
|
||||
* @copyright Clément Guillemain
|
||||
*/
|
||||
class ImageWorkshop
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const ERROR_NOT_AN_IMAGE_FILE = 1;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const ERROR_IMAGE_NOT_FOUND = 2;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const ERROR_NOT_WRITABLE_FILE = 3;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
const ERROR_CREATE_IMAGE_FROM_STRING = 4;
|
||||
|
||||
/**
|
||||
* Initialize a layer from a given image path
|
||||
*
|
||||
* From an upload form, you can give the "tmp_name" path
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return ImageWorkshopLayer
|
||||
*/
|
||||
public static function initFromPath($path)
|
||||
{
|
||||
if (file_exists($path) && !is_dir($path)) {
|
||||
|
||||
if (!is_readable($path)) {
|
||||
throw new ImageWorkshopException('Can\'t open the file at "'.$path.'" : file is not writable, did you check permissions (755 / 777) ?', static::ERROR_NOT_WRITABLE_FILE);
|
||||
}
|
||||
|
||||
$imageSizeInfos = @getImageSize($path);
|
||||
$mimeContentType = explode('/', $imageSizeInfos['mime']);
|
||||
|
||||
if (!$mimeContentType || !array_key_exists(1, $mimeContentType)) {
|
||||
throw new ImageWorkshopException('Not an image file (jpeg/png/gif) at "'.$path.'"', static::ERROR_NOT_AN_IMAGE_FILE);
|
||||
}
|
||||
|
||||
$mimeContentType = $mimeContentType[1];
|
||||
|
||||
switch ($mimeContentType) {
|
||||
case 'jpeg':
|
||||
$image = imageCreateFromJPEG($path);
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
$image = imageCreateFromGIF($path);
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
$image = imageCreateFromPNG($path);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ImageWorkshopException('Not an image file (jpeg/png/gif) at "'.$path.'"', static::ERROR_NOT_AN_IMAGE_FILE);
|
||||
break;
|
||||
}
|
||||
|
||||
return new ImageWorkshopLayer($image);
|
||||
}
|
||||
|
||||
throw new ImageWorkshopException('No such file found at "'.$path.'"', static::ERROR_IMAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a text layer
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $fontPath
|
||||
* @param integer $fontSize
|
||||
* @param string $fontColor
|
||||
* @param integer $textRotation
|
||||
* @param integer $backgroundColor
|
||||
*
|
||||
* @return ImageWorkshopLayer
|
||||
*/
|
||||
public static function initTextLayer($text, $fontPath, $fontSize = 13, $fontColor = 'ffffff', $textRotation = 0, $backgroundColor = null)
|
||||
{
|
||||
$textDimensions = ImageWorkshopLib::getTextBoxDimension($fontSize, $textRotation, $fontPath, $text);
|
||||
|
||||
$layer = static::initVirginLayer($textDimensions['width'], $textDimensions['height'], $backgroundColor);
|
||||
$layer->write($text, $fontPath, $fontSize, $fontColor, $textDimensions['left'], $textDimensions['top'], $textRotation);
|
||||
|
||||
return $layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new virgin layer
|
||||
*
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param string $backgroundColor
|
||||
*
|
||||
* @return ImageWorkshopLayer
|
||||
*/
|
||||
public static function initVirginLayer($width = 100, $height = 100, $backgroundColor = null)
|
||||
{
|
||||
$opacity = 0;
|
||||
|
||||
if (!$backgroundColor || $backgroundColor == 'transparent') {
|
||||
$opacity = 127;
|
||||
$backgroundColor = 'ffffff';
|
||||
}
|
||||
|
||||
return new ImageWorkshopLayer(ImageWorkshopLib::generateImage($width, $height, $backgroundColor, $opacity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a layer from a resource image var
|
||||
*
|
||||
* @param \resource $image
|
||||
*
|
||||
* @return ImageWorkshopLayer
|
||||
*/
|
||||
public static function initFromResourceVar($image)
|
||||
{
|
||||
return new ImageWorkshopLayer($image);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a layer from a string (obtains with file_get_contents, cURL...)
|
||||
*
|
||||
* This not recommanded to initialize JPEG string with this method, GD displays bugs !
|
||||
*
|
||||
* @param string $imageString
|
||||
*
|
||||
* @return ImageWorkshopLayer
|
||||
*/
|
||||
public static function initFromString($imageString)
|
||||
{
|
||||
if (!$image = @imageCreateFromString($imageString)) {
|
||||
throw new ImageWorkshopException('Can\'t generate an image from the given string.', static::ERROR_CREATE_IMAGE_FROM_STRING);
|
||||
}
|
||||
|
||||
return new ImageWorkshopLayer($image);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Environment
|
||||
*
|
||||
* This class creates and returns a key/value array of common
|
||||
* environment variables for the current HTTP request.
|
||||
*
|
||||
* This is a singleton class; derived environment variables will
|
||||
* be common across multiple Slim applications.
|
||||
*
|
||||
* This class matches the Rack (Ruby) specification as closely
|
||||
* as possible. More information available below.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Environment implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties;
|
||||
|
||||
/**
|
||||
* @var \Slim\Environment
|
||||
*/
|
||||
protected static $environment;
|
||||
|
||||
/**
|
||||
* Get environment instance (singleton)
|
||||
*
|
||||
* This creates and/or returns an environment instance (singleton)
|
||||
* derived from $_SERVER variables. You may override the global server
|
||||
* variables by using `\Slim\Environment::mock()` instead.
|
||||
*
|
||||
* @param bool $refresh Refresh properties using global server variables?
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function getInstance($refresh = false)
|
||||
{
|
||||
if (is_null(self::$environment) || $refresh) {
|
||||
self::$environment = new self();
|
||||
}
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mock environment instance
|
||||
*
|
||||
* @param array $userSettings
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function mock($userSettings = array())
|
||||
{
|
||||
$defaults = array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '',
|
||||
'PATH_INFO' => '',
|
||||
'QUERY_STRING' => '',
|
||||
'SERVER_NAME' => 'localhost',
|
||||
'SERVER_PORT' => 80,
|
||||
'ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
|
||||
'ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
|
||||
'USER_AGENT' => 'Slim Framework',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => @fopen('php://stderr', 'w')
|
||||
);
|
||||
self::$environment = new self(array_merge($defaults, $userSettings));
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor (private access)
|
||||
*
|
||||
* @param array|null $settings If present, these are used instead of global server variables
|
||||
*/
|
||||
private function __construct($settings = null)
|
||||
{
|
||||
if ($settings) {
|
||||
$this->properties = $settings;
|
||||
} else {
|
||||
$env = array();
|
||||
|
||||
//The HTTP request method
|
||||
$env['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
//The IP
|
||||
$env['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
// Server params
|
||||
$scriptName = $_SERVER['SCRIPT_NAME']; // <-- "/foo/index.php"
|
||||
$requestUri = $_SERVER['REQUEST_URI']; // <-- "/foo/bar?test=abc" or "/foo/index.php/bar?test=abc"
|
||||
$queryString = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; // <-- "test=abc" or ""
|
||||
|
||||
// Physical path
|
||||
if (strpos($requestUri, $scriptName) !== false) {
|
||||
$physicalPath = $scriptName; // <-- Without rewriting
|
||||
} else {
|
||||
$physicalPath = str_replace('\\', '', dirname($scriptName)); // <-- With rewriting
|
||||
}
|
||||
$env['SCRIPT_NAME'] = rtrim($physicalPath, '/'); // <-- Remove trailing slashes
|
||||
|
||||
// Virtual path
|
||||
$env['PATH_INFO'] = substr_replace($requestUri, '', 0, strlen($physicalPath)); // <-- Remove physical path
|
||||
$env['PATH_INFO'] = str_replace('?' . $queryString, '', $env['PATH_INFO']); // <-- Remove query string
|
||||
$env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/'); // <-- Ensure leading slash
|
||||
|
||||
// Query string (without leading "?")
|
||||
$env['QUERY_STRING'] = $queryString;
|
||||
|
||||
//Name of server host that is running the script
|
||||
$env['SERVER_NAME'] = $_SERVER['SERVER_NAME'];
|
||||
|
||||
//Number of server port that is running the script
|
||||
$env['SERVER_PORT'] = $_SERVER['SERVER_PORT'];
|
||||
|
||||
//HTTP request headers (retains HTTP_ prefix to match $_SERVER)
|
||||
$headers = \Slim\Http\Headers::extract($_SERVER);
|
||||
foreach ($headers as $key => $value) {
|
||||
$env[$key] = $value;
|
||||
}
|
||||
|
||||
//Is the application running under HTTPS or HTTP protocol?
|
||||
$env['slim.url_scheme'] = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ? 'http' : 'https';
|
||||
|
||||
//Input stream (readable one time only; not available for multipart/form-data requests)
|
||||
$rawInput = @file_get_contents('php://input');
|
||||
if (!$rawInput) {
|
||||
$rawInput = '';
|
||||
}
|
||||
$env['slim.input'] = $rawInput;
|
||||
|
||||
//Error stream
|
||||
$env['slim.errors'] = @fopen('php://stderr', 'w');
|
||||
|
||||
$this->properties = $env;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (isset($this->properties[$offset])) {
|
||||
return $this->properties[$offset];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->properties[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* IteratorAggregate
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->properties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Exception;
|
||||
|
||||
/**
|
||||
* Pass Exception
|
||||
*
|
||||
* This Exception will cause the Router::dispatch method
|
||||
* to skip the current matching route and continue to the next
|
||||
* matching route. If no subsequent routes are found, a
|
||||
* HTTP 404 Not Found response will be sent to the client.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Pass extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Exception;
|
||||
|
||||
/**
|
||||
* Stop Exception
|
||||
*
|
||||
* This Exception is thrown when the Slim application needs to abort
|
||||
* processing and return control flow to the outer PHP script.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Stop extends \Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Helper;
|
||||
|
||||
class Set implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Key-value array of arbitrary data
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $items Pre-populate set with this key-value array
|
||||
*/
|
||||
public function __construct($items = array())
|
||||
{
|
||||
$this->replace($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize data key
|
||||
*
|
||||
* Used to transform data key into the necessary
|
||||
* key format for this set. Used in subclasses
|
||||
* like \Slim\Http\Headers.
|
||||
*
|
||||
* @param string $key The data key
|
||||
* @return mixed The transformed/normalized data key
|
||||
*/
|
||||
protected function normalizeKey($key)
|
||||
{
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data key to value
|
||||
* @param string $key The data key
|
||||
* @param mixed $value The data value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->data[$this->normalizeKey($key)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data value with key
|
||||
* @param string $key The data key
|
||||
* @param mixed $default The value to return if data key does not exist
|
||||
* @return mixed The data value, or the default value
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if ($this->has($key)) {
|
||||
$isInvokable = is_object($this->data[$this->normalizeKey($key)]) && method_exists($this->data[$this->normalizeKey($key)], '__invoke');
|
||||
|
||||
return $isInvokable ? $this->data[$this->normalizeKey($key)]($this) : $this->data[$this->normalizeKey($key)];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to set
|
||||
* @param array $items Key-value array of data to append to this set
|
||||
*/
|
||||
public function replace($items)
|
||||
{
|
||||
foreach ($items as $key => $value) {
|
||||
$this->set($key, $value); // Ensure keys are normalized
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch set data
|
||||
* @return array This set's key-value data array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch set data keys
|
||||
* @return array This set's key-value data array keys
|
||||
*/
|
||||
public function keys()
|
||||
{
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this set contain a key?
|
||||
* @param string $key The data key
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return array_key_exists($this->normalizeKey($key), $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove value with key from this set
|
||||
* @param string $key The data key
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
unset($this->data[$this->normalizeKey($key)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Property Overloading
|
||||
*/
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
public function __isset($key)
|
||||
{
|
||||
return $this->has($key);
|
||||
}
|
||||
|
||||
public function __unset($key)
|
||||
{
|
||||
return $this->remove($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all values
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access
|
||||
*/
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->has($offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->remove($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable
|
||||
*/
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* IteratorAggregate
|
||||
*/
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a value or object will remain globally unique
|
||||
* @param string $key The value or object name
|
||||
* @param Closure The closure that defines the object
|
||||
* @return mixed
|
||||
*/
|
||||
public function singleton($key, $value)
|
||||
{
|
||||
$this->set($key, function ($c) use ($value) {
|
||||
static $object;
|
||||
|
||||
if (null === $object) {
|
||||
$object = $value($c);
|
||||
}
|
||||
|
||||
return $object;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect closure from being directly invoked
|
||||
* @param Closure $callable A closure to keep from being invoked and evaluated
|
||||
* @return Closure
|
||||
*/
|
||||
public function protect(\Closure $callable)
|
||||
{
|
||||
return function () use ($callable) {
|
||||
return $callable;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim Framework (http://slimframework.com)
|
||||
*
|
||||
* @link https://github.com/slimphp/Slim
|
||||
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Slim\Interfaces\Http\CookiesInterface;
|
||||
|
||||
/**
|
||||
* Cookie helper
|
||||
*/
|
||||
class Cookies implements CookiesInterface
|
||||
{
|
||||
/**
|
||||
* Cookies from HTTP request
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestCookies = [];
|
||||
|
||||
/**
|
||||
* Cookies for HTTP response
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $responseCookies = [];
|
||||
|
||||
/**
|
||||
* Default cookie properties
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $defaults = [
|
||||
'value' => '',
|
||||
'domain' => null,
|
||||
'path' => null,
|
||||
'expires' => null,
|
||||
'secure' => false,
|
||||
'httponly' => false
|
||||
];
|
||||
|
||||
/**
|
||||
* Create new cookies helper
|
||||
*
|
||||
* @param array $cookies
|
||||
*/
|
||||
public function __construct(array $cookies = [])
|
||||
{
|
||||
$this->requestCookies = $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default cookie properties
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function setDefaults(array $settings)
|
||||
{
|
||||
$this->defaults = array_replace($this->defaults, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request cookie
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param mixed $default Cookie default value
|
||||
*
|
||||
* @return mixed Cookie value if present, else default
|
||||
*/
|
||||
public function get($name, $default = null)
|
||||
{
|
||||
return isset($this->requestCookies[$name]) ? $this->requestCookies[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set response cookie
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param string|array $value Cookie value, or cookie properties
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = ['value' => (string)$value];
|
||||
}
|
||||
$this->responseCookies[$name] = array_replace($this->defaults, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to `Set-Cookie` headers
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function toHeaders()
|
||||
{
|
||||
$headers = [];
|
||||
foreach ($this->responseCookies as $name => $properties) {
|
||||
$headers[] = $this->toHeader($name, $properties);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to `Set-Cookie` header
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param array $properties Cookie properties
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function toHeader($name, array $properties)
|
||||
{
|
||||
$result = urlencode($name) . '=' . urlencode($properties['value']);
|
||||
|
||||
if (isset($properties['domain'])) {
|
||||
$result .= '; domain=' . $properties['domain'];
|
||||
}
|
||||
|
||||
if (isset($properties['path'])) {
|
||||
$result .= '; path=' . $properties['path'];
|
||||
}
|
||||
|
||||
if (isset($properties['expires'])) {
|
||||
if (is_string($properties['expires'])) {
|
||||
$timestamp = strtotime($properties['expires']);
|
||||
} else {
|
||||
$timestamp = (int)$properties['expires'];
|
||||
}
|
||||
if ($timestamp !== 0) {
|
||||
$result .= '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($properties['secure']) && $properties['secure']) {
|
||||
$result .= '; secure';
|
||||
}
|
||||
|
||||
if (isset($properties['httponly']) && $properties['httponly']) {
|
||||
$result .= '; HttpOnly';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse HTTP request `Cookie:` header and extract
|
||||
* into a PHP associative array.
|
||||
*
|
||||
* @param string $header The raw HTTP request `Cookie:` header
|
||||
*
|
||||
* @return array Associative array of cookie names and values
|
||||
*
|
||||
* @throws InvalidArgumentException if the cookie data cannot be parsed
|
||||
*/
|
||||
public static function parseHeader($header)
|
||||
{
|
||||
if (is_array($header) === true) {
|
||||
$header = isset($header[0]) ? $header[0] : '';
|
||||
}
|
||||
|
||||
if (is_string($header) === false) {
|
||||
throw new InvalidArgumentException('Cannot parse Cookie data. Header value must be a string.');
|
||||
}
|
||||
|
||||
$header = rtrim($header, "\r\n");
|
||||
$pieces = preg_split('@\s*[;,]\s*@', $header);
|
||||
$cookies = [];
|
||||
|
||||
foreach ($pieces as $cookie) {
|
||||
$cookie = explode('=', $cookie, 2);
|
||||
|
||||
if (count($cookie) === 2) {
|
||||
$key = urldecode($cookie[0]);
|
||||
$value = urldecode($cookie[1]);
|
||||
|
||||
if (!isset($cookies[$key])) {
|
||||
$cookies[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim Framework (http://slimframework.com)
|
||||
*
|
||||
* @link https://github.com/slimphp/Slim
|
||||
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
use Slim\Collection;
|
||||
use Slim\Interfaces\Http\HeadersInterface;
|
||||
|
||||
/**
|
||||
* Headers
|
||||
*
|
||||
* This class represents a collection of HTTP headers
|
||||
* that is used in both the HTTP request and response objects.
|
||||
* It also enables header name case-insensitivity when
|
||||
* getting or setting a header value.
|
||||
*
|
||||
* Each HTTP header can have multiple values. This class
|
||||
* stores values into an array for each header name. When
|
||||
* you request a header value, you receive an array of values
|
||||
* for that header.
|
||||
*/
|
||||
class Headers extends Collection implements HeadersInterface
|
||||
{
|
||||
/**
|
||||
* Special HTTP headers that do not have the "HTTP_" prefix
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $special = [
|
||||
'CONTENT_TYPE' => 1,
|
||||
'CONTENT_LENGTH' => 1,
|
||||
'PHP_AUTH_USER' => 1,
|
||||
'PHP_AUTH_PW' => 1,
|
||||
'PHP_AUTH_DIGEST' => 1,
|
||||
'AUTH_TYPE' => 1,
|
||||
];
|
||||
|
||||
/**
|
||||
* Create new headers collection with data extracted from
|
||||
* the application Environment object
|
||||
*
|
||||
* @param Environment $environment The Slim application Environment
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createFromEnvironment(Environment $environment)
|
||||
{
|
||||
$data = [];
|
||||
foreach ($environment as $key => $value) {
|
||||
$key = strtoupper($key);
|
||||
if (isset(static::$special[$key]) || strpos($key, 'HTTP_') === 0) {
|
||||
if ($key !== 'HTTP_CONTENT_LENGTH') {
|
||||
$data[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new static($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of HTTP header names and values.
|
||||
* This method returns the _original_ header name
|
||||
* as specified by the end user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$all = parent::all();
|
||||
$out = [];
|
||||
foreach ($all as $key => $props) {
|
||||
$out[$props['originalKey']] = $props['value'];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HTTP header value
|
||||
*
|
||||
* This method sets a header value. It replaces
|
||||
* any values that may already exist for the header name.
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
* @param string $value The header value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
parent::set($this->normalizeKey($key), [
|
||||
'value' => $value,
|
||||
'originalKey' => $key
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP header value
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
* @param mixed $default The default value if key does not exist
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if ($this->has($key)) {
|
||||
return parent::get($this->normalizeKey($key))['value'];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP header key as originally specified
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
* @param mixed $default The default value if key does not exist
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOriginalKey($key, $default = null)
|
||||
{
|
||||
if ($this->has($key)) {
|
||||
return parent::get($this->normalizeKey($key))['originalKey'];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add HTTP header value
|
||||
*
|
||||
* This method appends a header value. Unlike the set() method,
|
||||
* this method _appends_ this new value to any values
|
||||
* that already exist for this header name.
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
* @param array|string $value The new header value(s)
|
||||
*/
|
||||
public function add($key, $value)
|
||||
{
|
||||
$oldValues = $this->get($key, []);
|
||||
$newValues = is_array($value) ? $value : [$value];
|
||||
$this->set($key, array_merge($oldValues, array_values($newValues)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this collection have a given header?
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return parent::has($this->normalizeKey($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove header from collection
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
parent::remove($this->normalizeKey($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize header name
|
||||
*
|
||||
* This method transforms header names into a
|
||||
* normalized form. This is how we enable case-insensitive
|
||||
* header names in the other methods in this class.
|
||||
*
|
||||
* @param string $key The case-insensitive header name
|
||||
*
|
||||
* @return string Normalized header name
|
||||
*/
|
||||
public function normalizeKey($key)
|
||||
{
|
||||
$key = strtr(strtolower($key), '_', '-');
|
||||
if (strpos($key, 'http-') === 0) {
|
||||
$key = substr($key, 5);
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim Framework (http://slimframework.com)
|
||||
*
|
||||
* @link https://github.com/slimphp/Slim
|
||||
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Slim\Interfaces\Http\HeadersInterface;
|
||||
|
||||
/**
|
||||
* Response
|
||||
*
|
||||
* This class represents an HTTP response. It manages
|
||||
* the response status, headers, and body
|
||||
* according to the PSR-7 standard.
|
||||
*
|
||||
* @link https://github.com/php-fig/http-message/blob/master/src/MessageInterface.php
|
||||
* @link https://github.com/php-fig/http-message/blob/master/src/ResponseInterface.php
|
||||
*/
|
||||
class Response extends Message implements ResponseInterface
|
||||
{
|
||||
/**
|
||||
* Status code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $status = 200;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $reasonPhrase = '';
|
||||
|
||||
/**
|
||||
* Status codes and reason phrases
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $messages = [
|
||||
//Informational 1xx
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
102 => 'Processing',
|
||||
//Successful 2xx
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
207 => 'Multi-Status',
|
||||
208 => 'Already Reported',
|
||||
226 => 'IM Used',
|
||||
//Redirection 3xx
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found',
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
306 => '(Unused)',
|
||||
307 => 'Temporary Redirect',
|
||||
308 => 'Permanent Redirect',
|
||||
//Client Error 4xx
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
418 => 'I\'m a teapot',
|
||||
422 => 'Unprocessable Entity',
|
||||
423 => 'Locked',
|
||||
424 => 'Failed Dependency',
|
||||
426 => 'Upgrade Required',
|
||||
428 => 'Precondition Required',
|
||||
429 => 'Too Many Requests',
|
||||
431 => 'Request Header Fields Too Large',
|
||||
//Server Error 5xx
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
506 => 'Variant Also Negotiates',
|
||||
507 => 'Insufficient Storage',
|
||||
508 => 'Loop Detected',
|
||||
510 => 'Not Extended',
|
||||
511 => 'Network Authentication Required',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create new HTTP response.
|
||||
*
|
||||
* @param int $status The response status code.
|
||||
* @param HeadersInterface|null $headers The response headers.
|
||||
* @param StreamInterface|null $body The response body.
|
||||
*/
|
||||
public function __construct($status = 200, HeadersInterface $headers = null, StreamInterface $body = null)
|
||||
{
|
||||
$this->status = $this->filterStatus($status);
|
||||
$this->headers = $headers ? $headers : new Headers();
|
||||
$this->body = $body ? $body : new Body(fopen('php://temp', 'r+'));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is applied to the cloned object
|
||||
* after PHP performs an initial shallow-copy. This
|
||||
* method completes a deep-copy by creating new objects
|
||||
* for the cloned object's internal reference pointers.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->headers = clone $this->headers;
|
||||
$this->body = clone $this->body;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Status
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Gets the response status code.
|
||||
*
|
||||
* The status code is a 3-digit integer result code of the server's attempt
|
||||
* to understand and satisfy the request.
|
||||
*
|
||||
* @return int Status code.
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance with the specified status code and, optionally, reason phrase.
|
||||
*
|
||||
* If no reason phrase is specified, implementations MAY choose to default
|
||||
* to the RFC 7231 or IANA recommended reason phrase for the response's
|
||||
* status code.
|
||||
*
|
||||
* This method MUST be implemented in such a way as to retain the
|
||||
* immutability of the message, and MUST return an instance that has the
|
||||
* updated status and reason phrase.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc7231#section-6
|
||||
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
* @param int $code The 3-digit integer result code to set.
|
||||
* @param string $reasonPhrase The reason phrase to use with the
|
||||
* provided status code; if none is provided, implementations MAY
|
||||
* use the defaults as suggested in the HTTP specification.
|
||||
* @return self
|
||||
* @throws \InvalidArgumentException For invalid status code arguments.
|
||||
*/
|
||||
public function withStatus($code, $reasonPhrase = '')
|
||||
{
|
||||
$code = $this->filterStatus($code);
|
||||
|
||||
if (!is_string($reasonPhrase) && !method_exists($reasonPhrase, '__toString')) {
|
||||
throw new InvalidArgumentException('ReasonPhrase must be a string');
|
||||
}
|
||||
|
||||
$clone = clone $this;
|
||||
$clone->status = $code;
|
||||
if ($reasonPhrase === '' && isset(static::$messages[$code])) {
|
||||
$reasonPhrase = static::$messages[$code];
|
||||
}
|
||||
|
||||
if ($reasonPhrase === '') {
|
||||
throw new InvalidArgumentException('ReasonPhrase must be supplied for this code');
|
||||
}
|
||||
|
||||
$clone->reasonPhrase = $reasonPhrase;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter HTTP status code.
|
||||
*
|
||||
* @param int $status HTTP status code.
|
||||
* @return int
|
||||
* @throws \InvalidArgumentException If an invalid HTTP status code is provided.
|
||||
*/
|
||||
protected function filterStatus($status)
|
||||
{
|
||||
if (!is_integer($status) || $status<100 || $status>599) {
|
||||
throw new InvalidArgumentException('Invalid HTTP status code');
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response reason phrase associated with the status code.
|
||||
*
|
||||
* Because a reason phrase is not a required element in a response
|
||||
* status line, the reason phrase value MAY be null. Implementations MAY
|
||||
* choose to return the default RFC 7231 recommended reason phrase (or those
|
||||
* listed in the IANA HTTP Status Code Registry) for the response's
|
||||
* status code.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc7231#section-6
|
||||
* @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
* @return string Reason phrase; must return an empty string if none present.
|
||||
*/
|
||||
public function getReasonPhrase()
|
||||
{
|
||||
if ($this->reasonPhrase) {
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
if (isset(static::$messages[$this->status])) {
|
||||
return static::$messages[$this->status];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Body
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Write data to the response body.
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* Proxies to the underlying stream and writes the provided data to it.
|
||||
*
|
||||
* @param string $data
|
||||
* @return self
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
$this->getBody()->write($data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Response Helpers
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Redirect.
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* This method prepares the response object to return an HTTP Redirect
|
||||
* response to the client.
|
||||
*
|
||||
* @param string|UriInterface $url The redirect destination.
|
||||
* @param int $status The redirect HTTP status code.
|
||||
* @return self
|
||||
*/
|
||||
public function withRedirect($url, $status = 302)
|
||||
{
|
||||
return $this->withStatus($status)->withHeader('Location', (string)$url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Json.
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* This method prepares the response object to return an HTTP Json
|
||||
* response to the client.
|
||||
*
|
||||
* @param mixed $data The data
|
||||
* @param int $status The HTTP status code.
|
||||
* @param int $encodingOptions Json encoding options
|
||||
* @return self
|
||||
*/
|
||||
public function withJson($data, $status = 200, $encodingOptions = 0)
|
||||
{
|
||||
$body = $this->getBody();
|
||||
$body->rewind();
|
||||
$body->write(json_encode($data, $encodingOptions));
|
||||
|
||||
return $this->withStatus($status)->withHeader('Content-Type', 'application/json;charset=utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response empty?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return in_array($this->getStatusCode(), [204, 205, 304]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response informational?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isInformational()
|
||||
{
|
||||
return $this->getStatusCode() >= 100 && $this->getStatusCode() < 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response OK?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOk()
|
||||
{
|
||||
return $this->getStatusCode() === 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response successful?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessful()
|
||||
{
|
||||
return $this->getStatusCode() >= 200 && $this->getStatusCode() < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response a redirect?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->getStatusCode(), [301, 302, 303, 307]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response a redirection?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirection()
|
||||
{
|
||||
return $this->getStatusCode() >= 300 && $this->getStatusCode() < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response forbidden?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
* @api
|
||||
*/
|
||||
public function isForbidden()
|
||||
{
|
||||
return $this->getStatusCode() === 403;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response not Found?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotFound()
|
||||
{
|
||||
return $this->getStatusCode() === 404;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response a client error?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClientError()
|
||||
{
|
||||
return $this->getStatusCode() >= 400 && $this->getStatusCode() < 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this response a server error?
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isServerError()
|
||||
{
|
||||
return $this->getStatusCode() >= 500 && $this->getStatusCode() < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert response to string.
|
||||
*
|
||||
* Note: This method is not part of the PSR-7 standard.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$output = sprintf(
|
||||
'HTTP/%s %s %s',
|
||||
$this->getProtocolVersion(),
|
||||
$this->getStatusCode(),
|
||||
$this->getReasonPhrase()
|
||||
);
|
||||
$output .= PHP_EOL;
|
||||
foreach ($this->getHeaders() as $name => $values) {
|
||||
$output .= sprintf('%s: %s', $name, $this->getHeaderLine($name)) . PHP_EOL;
|
||||
}
|
||||
$output .= PHP_EOL;
|
||||
$output .= (string)$this->getBody();
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* Slim HTTP Utilities
|
||||
*
|
||||
* This class provides useful methods for handling HTTP requests.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
*
|
||||
* This method strips slashes from its input. By default, this method will only
|
||||
* strip slashes from its input if magic quotes are enabled. Otherwise, you may
|
||||
* override the magic quotes setting with either TRUE or FALSE as the send argument
|
||||
* to force this method to strip or not strip slashes from its input.
|
||||
*
|
||||
* @param array|string $rawData
|
||||
* @param bool $overrideStripSlashes
|
||||
* @return array|string
|
||||
*/
|
||||
public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null)
|
||||
{
|
||||
$strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes;
|
||||
if ($strip) {
|
||||
return self::stripSlashes($rawData);
|
||||
} else {
|
||||
return $rawData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
* @param array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
protected static function stripSlashes($rawData)
|
||||
{
|
||||
return is_array($rawData) ? array_map(array('self', 'stripSlashes'), $rawData) : stripslashes($rawData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data
|
||||
*
|
||||
* This method will encrypt data using a given key, vector, and cipher.
|
||||
* By default, this will encrypt data using the RIJNDAEL/AES 256 bit cipher. You
|
||||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The unencrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function encrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Merge settings with defaults
|
||||
$defaults = array(
|
||||
'algorithm' => MCRYPT_RIJNDAEL_256,
|
||||
'mode' => MCRYPT_MODE_CBC
|
||||
);
|
||||
$settings = array_merge($defaults, $settings);
|
||||
|
||||
//Get module
|
||||
$module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
|
||||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
//Encrypt value
|
||||
mcrypt_generic_init($module, $key, $iv);
|
||||
$res = @mcrypt_generic($module, $data);
|
||||
mcrypt_generic_deinit($module);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt data
|
||||
*
|
||||
* This method will decrypt data using a given key, vector, and cipher.
|
||||
* By default, this will decrypt data using the RIJNDAEL/AES 256 bit cipher. You
|
||||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The encrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function decrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Merge settings with defaults
|
||||
$defaults = array(
|
||||
'algorithm' => MCRYPT_RIJNDAEL_256,
|
||||
'mode' => MCRYPT_MODE_CBC
|
||||
);
|
||||
$settings = array_merge($defaults, $settings);
|
||||
|
||||
//Get module
|
||||
$module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
|
||||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
//Decrypt value
|
||||
mcrypt_generic_init($module, $key, $iv);
|
||||
$decryptedData = @mdecrypt_generic($module, $data);
|
||||
$res = rtrim($decryptedData, "\0");
|
||||
mcrypt_generic_deinit($module);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize Response cookies into raw HTTP header
|
||||
* @param \Slim\Http\Headers $headers The Response headers
|
||||
* @param \Slim\Http\Cookies $cookies The Response cookies
|
||||
* @param array $config The Slim app settings
|
||||
*/
|
||||
public static function serializeCookies(\Slim\Http\Headers &$headers, \Slim\Http\Cookies $cookies, array $config)
|
||||
{
|
||||
if ($config['cookies.encrypt']) {
|
||||
foreach ($cookies as $name => $settings) {
|
||||
if (is_string($settings['expires'])) {
|
||||
$expires = strtotime($settings['expires']);
|
||||
} else {
|
||||
$expires = (int) $settings['expires'];
|
||||
}
|
||||
|
||||
$settings['value'] = static::encodeSecureCookie(
|
||||
$settings['value'],
|
||||
$expires,
|
||||
$config['cookies.secret_key'],
|
||||
$config['cookies.cipher'],
|
||||
$config['cookies.cipher_mode']
|
||||
);
|
||||
static::setCookieHeader($headers, $name, $settings);
|
||||
}
|
||||
} else {
|
||||
foreach ($cookies as $name => $settings) {
|
||||
static::setCookieHeader($headers, $name, $settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode secure cookie value
|
||||
*
|
||||
* This method will create the secure value of an HTTP cookie. The
|
||||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The insecure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode)
|
||||
{
|
||||
$key = hash_hmac('sha1', (string) $expires, $secret);
|
||||
$iv = self::getIv($expires, $secret);
|
||||
$secureString = base64_encode(
|
||||
self::encrypt(
|
||||
$value,
|
||||
$key,
|
||||
$iv,
|
||||
array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
)
|
||||
)
|
||||
);
|
||||
$verificationString = hash_hmac('sha1', $expires . $value, $key);
|
||||
|
||||
return implode('|', array($expires, $secureString, $verificationString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode secure cookie value
|
||||
*
|
||||
* This method will decode the secure value of an HTTP cookie. The
|
||||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The secure HTTP cookie value
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function decodeSecureCookie($value, $secret, $algorithm, $mode)
|
||||
{
|
||||
if ($value) {
|
||||
$value = explode('|', $value);
|
||||
if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) {
|
||||
$key = hash_hmac('sha1', $value[0], $secret);
|
||||
$iv = self::getIv($value[0], $secret);
|
||||
$data = self::decrypt(
|
||||
base64_decode($value[1]),
|
||||
$key,
|
||||
$iv,
|
||||
array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
)
|
||||
);
|
||||
$verificationString = hash_hmac('sha1', $value[0] . $data, $key);
|
||||
if ($verificationString === $value[2]) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HTTP cookie header
|
||||
*
|
||||
* This method will construct and set the HTTP `Set-Cookie` header. Slim
|
||||
* uses this method instead of PHP's native `setcookie` method. This allows
|
||||
* more control of the HTTP header irrespective of the native implementation's
|
||||
* dependency on PHP versions.
|
||||
*
|
||||
* This method accepts the Slim_Http_Headers object by reference as its
|
||||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public static function setCookieHeader(&$header, $name, $value)
|
||||
{
|
||||
//Build cookie header
|
||||
if (is_array($value)) {
|
||||
$domain = '';
|
||||
$path = '';
|
||||
$expires = '';
|
||||
$secure = '';
|
||||
$httponly = '';
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$domain = '; domain=' . $value['domain'];
|
||||
}
|
||||
if (isset($value['path']) && $value['path']) {
|
||||
$path = '; path=' . $value['path'];
|
||||
}
|
||||
if (isset($value['expires'])) {
|
||||
if (is_string($value['expires'])) {
|
||||
$timestamp = strtotime($value['expires']);
|
||||
} else {
|
||||
$timestamp = (int) $value['expires'];
|
||||
}
|
||||
if ($timestamp !== 0) {
|
||||
$expires = '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp);
|
||||
}
|
||||
}
|
||||
if (isset($value['secure']) && $value['secure']) {
|
||||
$secure = '; secure';
|
||||
}
|
||||
if (isset($value['httponly']) && $value['httponly']) {
|
||||
$httponly = '; HttpOnly';
|
||||
}
|
||||
$cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string) $value['value']), $domain . $path . $expires . $secure . $httponly);
|
||||
} else {
|
||||
$cookie = sprintf('%s=%s', urlencode($name), urlencode((string) $value));
|
||||
}
|
||||
|
||||
//Set cookie header
|
||||
if (!isset($header['Set-Cookie']) || $header['Set-Cookie'] === '') {
|
||||
$header['Set-Cookie'] = $cookie;
|
||||
} else {
|
||||
$header['Set-Cookie'] = implode("\n", array($header['Set-Cookie'], $cookie));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete HTTP cookie header
|
||||
*
|
||||
* This method will construct and set the HTTP `Set-Cookie` header to invalidate
|
||||
* a client-side HTTP cookie. If a cookie with the same name (and, optionally, domain)
|
||||
* is already set in the HTTP response, it will also be removed. Slim uses this method
|
||||
* instead of PHP's native `setcookie` method. This allows more control of the HTTP header
|
||||
* irrespective of PHP's native implementation's dependency on PHP versions.
|
||||
*
|
||||
* This method accepts the Slim_Http_Headers object by reference as its
|
||||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param array $value
|
||||
*/
|
||||
public static function deleteCookieHeader(&$header, $name, $value = array())
|
||||
{
|
||||
//Remove affected cookies from current response header
|
||||
$cookiesOld = array();
|
||||
$cookiesNew = array();
|
||||
if (isset($header['Set-Cookie'])) {
|
||||
$cookiesOld = explode("\n", $header['Set-Cookie']);
|
||||
}
|
||||
foreach ($cookiesOld as $c) {
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$regex = sprintf('@%s=.*domain=%s@', urlencode($name), preg_quote($value['domain']));
|
||||
} else {
|
||||
$regex = sprintf('@%s=@', urlencode($name));
|
||||
}
|
||||
if (preg_match($regex, $c) === 0) {
|
||||
$cookiesNew[] = $c;
|
||||
}
|
||||
}
|
||||
if ($cookiesNew) {
|
||||
$header['Set-Cookie'] = implode("\n", $cookiesNew);
|
||||
} else {
|
||||
unset($header['Set-Cookie']);
|
||||
}
|
||||
|
||||
//Set invalidating cookie to clear client-side cookie
|
||||
self::setCookieHeader($header, $name, array_merge(array('value' => '', 'path' => null, 'domain' => null, 'expires' => time() - 100), $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse cookie header
|
||||
*
|
||||
* This method will parse the HTTP request's `Cookie` header
|
||||
* and extract cookies into an associative array.
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function parseCookieHeader($header)
|
||||
{
|
||||
$cookies = array();
|
||||
$header = rtrim($header, "\r\n");
|
||||
$headerPieces = preg_split('@\s*[;,]\s*@', $header);
|
||||
foreach ($headerPieces as $c) {
|
||||
$cParts = explode('=', $c, 2);
|
||||
if (count($cParts) === 2) {
|
||||
$key = urldecode($cParts[0]);
|
||||
$value = urldecode($cParts[1]);
|
||||
if (!isset($cookies[$key])) {
|
||||
$cookies[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random IV
|
||||
*
|
||||
* This method will generate a non-predictable IV for use with
|
||||
* the cookie encryption
|
||||
*
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @return string Hash
|
||||
*/
|
||||
private static function getIv($expires, $secret)
|
||||
{
|
||||
$data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret);
|
||||
$data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret);
|
||||
|
||||
return pack("h*", $data1.$data2);
|
||||
}
|
||||
}
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Log
|
||||
*
|
||||
* This is the primary logger for a Slim application. You may provide
|
||||
* a Log Writer in conjunction with this Log to write to various output
|
||||
* destinations (e.g. a file). This class provides this interface:
|
||||
*
|
||||
* debug( mixed $object, array $context )
|
||||
* info( mixed $object, array $context )
|
||||
* notice( mixed $object, array $context )
|
||||
* warning( mixed $object, array $context )
|
||||
* error( mixed $object, array $context )
|
||||
* critical( mixed $object, array $context )
|
||||
* alert( mixed $object, array $context )
|
||||
* emergency( mixed $object, array $context )
|
||||
* log( mixed $level, mixed $object, array $context )
|
||||
*
|
||||
* This class assumes only that your Log Writer has a public `write()` method
|
||||
* that accepts any object as its one and only argument. The Log Writer
|
||||
* class may write or send its argument anywhere: a file, STDERR,
|
||||
* a remote web API, etc. The possibilities are endless.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Log
|
||||
{
|
||||
const EMERGENCY = 1;
|
||||
const ALERT = 2;
|
||||
const CRITICAL = 3;
|
||||
const FATAL = 3; //DEPRECATED replace with CRITICAL
|
||||
const ERROR = 4;
|
||||
const WARN = 5;
|
||||
const NOTICE = 6;
|
||||
const INFO = 7;
|
||||
const DEBUG = 8;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $levels = array(
|
||||
self::EMERGENCY => 'EMERGENCY',
|
||||
self::ALERT => 'ALERT',
|
||||
self::CRITICAL => 'CRITICAL',
|
||||
self::ERROR => 'ERROR',
|
||||
self::WARN => 'WARNING',
|
||||
self::NOTICE => 'NOTICE',
|
||||
self::INFO => 'INFO',
|
||||
self::DEBUG => 'DEBUG'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function __construct($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
$this->enabled = true;
|
||||
$this->level = self::DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function getEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable logging
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
if ($enabled) {
|
||||
$this->enabled = true;
|
||||
} else {
|
||||
$this->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set level
|
||||
* @param int $level
|
||||
* @throws \InvalidArgumentException If invalid log level specified
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
if (!isset(self::$levels[$level])) {
|
||||
throw new \InvalidArgumentException('Invalid log level');
|
||||
}
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get level
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set writer
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function setWriter($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get writer
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWriter()
|
||||
{
|
||||
return $this->writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log debug message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function debug($object, $context = array())
|
||||
{
|
||||
return $this->log(self::DEBUG, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log info message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function info($object, $context = array())
|
||||
{
|
||||
return $this->log(self::INFO, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log notice message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function notice($object, $context = array())
|
||||
{
|
||||
return $this->log(self::NOTICE, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log warning message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function warning($object, $context = array())
|
||||
{
|
||||
return $this->log(self::WARN, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED for function warning
|
||||
* Log warning message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function warn($object, $context = array())
|
||||
{
|
||||
return $this->log(self::WARN, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function error($object, $context = array())
|
||||
{
|
||||
return $this->log(self::ERROR, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log critical message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function critical($object, $context = array())
|
||||
{
|
||||
return $this->log(self::CRITICAL, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED for function critical
|
||||
* Log fatal message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function fatal($object, $context = array())
|
||||
{
|
||||
return $this->log(self::CRITICAL, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log alert message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function alert($object, $context = array())
|
||||
{
|
||||
return $this->log(self::ALERT, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log emergency message
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function emergency($object, $context = array())
|
||||
{
|
||||
return $this->log(self::EMERGENCY, $object, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log message
|
||||
* @param mixed $level
|
||||
* @param mixed $object
|
||||
* @param array $context
|
||||
* @return mixed|bool What the Logger returns, or false if Logger not set or not enabled
|
||||
* @throws \InvalidArgumentException If invalid log level
|
||||
*/
|
||||
public function log($level, $object, $context = array())
|
||||
{
|
||||
if (!isset(self::$levels[$level])) {
|
||||
throw new \InvalidArgumentException('Invalid log level supplied to function');
|
||||
} else if ($this->enabled && $this->writer && $level <= $this->level) {
|
||||
$message = (string)$object;
|
||||
if (count($context) > 0) {
|
||||
if (isset($context['exception']) && $context['exception'] instanceof \Exception) {
|
||||
$message .= ' - ' . $context['exception'];
|
||||
unset($context['exception']);
|
||||
}
|
||||
$message = $this->interpolate($message, $context);
|
||||
}
|
||||
return $this->writer->write($message, $level);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED for function log
|
||||
* Log message
|
||||
* @param mixed $object The object to log
|
||||
* @param int $level The message level
|
||||
* @return int|bool
|
||||
*/
|
||||
protected function write($object, $level)
|
||||
{
|
||||
return $this->log($level, $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate log message
|
||||
* @param mixed $message The log message
|
||||
* @param array $context An array of placeholder values
|
||||
* @return string The processed string
|
||||
*/
|
||||
protected function interpolate($message, $context = array())
|
||||
{
|
||||
$replace = array();
|
||||
foreach ($context as $key => $value) {
|
||||
$replace['{' . $key . '}'] = $value;
|
||||
}
|
||||
return strtr($message, $replace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Log Writer
|
||||
*
|
||||
* This class is used by Slim_Log to write log messages to a valid, writable
|
||||
* resource handle (e.g. a file or STDERR).
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class LogWriter
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param resource $resource
|
||||
* @throws \InvalidArgumentException If invalid resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new \InvalidArgumentException('Cannot create LogWriter. Invalid resource handle.');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write message
|
||||
* @param mixed $message
|
||||
* @param int $level
|
||||
* @return int|bool
|
||||
*/
|
||||
public function write($message, $level = null)
|
||||
{
|
||||
return fwrite($this->resource, (string) $message . PHP_EOL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
abstract class Middleware
|
||||
{
|
||||
/**
|
||||
* @var \Slim\Slim Reference to the primary application instance
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var mixed Reference to the next downstream middleware
|
||||
*/
|
||||
protected $next;
|
||||
|
||||
/**
|
||||
* Set application
|
||||
*
|
||||
* This method injects the primary Slim application instance into
|
||||
* this middleware.
|
||||
*
|
||||
* @param \Slim\Slim $application
|
||||
*/
|
||||
final public function setApplication($application)
|
||||
{
|
||||
$this->app = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get application
|
||||
*
|
||||
* This method retrieves the application previously injected
|
||||
* into this middleware.
|
||||
*
|
||||
* @return \Slim\Slim
|
||||
*/
|
||||
final public function getApplication()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set next middleware
|
||||
*
|
||||
* This method injects the next downstream middleware into
|
||||
* this middleware so that it may optionally be called
|
||||
* when appropriate.
|
||||
*
|
||||
* @param \Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function setNextMiddleware($nextMiddleware)
|
||||
{
|
||||
$this->next = $nextMiddleware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next middleware
|
||||
*
|
||||
* This method retrieves the next downstream middleware
|
||||
* previously injected into this middleware.
|
||||
*
|
||||
* @return \Slim\Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function getNextMiddleware()
|
||||
{
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*
|
||||
* Perform actions specific to this middleware and optionally
|
||||
* call the next downstream middleware.
|
||||
*/
|
||||
abstract public function call();
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Content Types
|
||||
*
|
||||
* This is middleware for a Slim application that intercepts
|
||||
* the HTTP request body and parses it into the appropriate
|
||||
* PHP data structure if possible; else it returns the HTTP
|
||||
* request body unchanged. This is particularly useful
|
||||
* for preparing the HTTP request body for an XML or JSON API.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class ContentTypes extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $contentTypes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$defaults = array(
|
||||
'application/json' => array($this, 'parseJson'),
|
||||
'application/xml' => array($this, 'parseXml'),
|
||||
'text/xml' => array($this, 'parseXml'),
|
||||
'text/csv' => array($this, 'parseCsv')
|
||||
);
|
||||
$this->contentTypes = array_merge($defaults, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$mediaType = $this->app->request()->getMediaType();
|
||||
if ($mediaType) {
|
||||
$env = $this->app->environment();
|
||||
$env['slim.input_original'] = $env['slim.input'];
|
||||
$env['slim.input'] = $this->parse($env['slim.input'], $mediaType);
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse input
|
||||
*
|
||||
* This method will attempt to parse the request body
|
||||
* based on its content type if available.
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $contentType
|
||||
* @return mixed
|
||||
*/
|
||||
protected function parse ($input, $contentType)
|
||||
{
|
||||
if (isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType])) {
|
||||
$result = call_user_func($this->contentTypes[$contentType], $input);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON
|
||||
*
|
||||
* This method converts the raw JSON input
|
||||
* into an associative array.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array|string
|
||||
*/
|
||||
protected function parseJson($input)
|
||||
{
|
||||
if (function_exists('json_decode')) {
|
||||
$result = json_decode($input, true);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse XML
|
||||
*
|
||||
* This method creates a SimpleXMLElement
|
||||
* based upon the XML input. If the SimpleXML
|
||||
* extension is not available, the raw input
|
||||
* will be returned unchanged.
|
||||
*
|
||||
* @param string $input
|
||||
* @return \SimpleXMLElement|string
|
||||
*/
|
||||
protected function parseXml($input)
|
||||
{
|
||||
if (class_exists('SimpleXMLElement')) {
|
||||
try {
|
||||
$backup = libxml_disable_entity_loader(true);
|
||||
$result = new \SimpleXMLElement($input);
|
||||
libxml_disable_entity_loader($backup);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSV
|
||||
*
|
||||
* This method parses CSV content into a numeric array
|
||||
* containing an array of data for each CSV line.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array
|
||||
*/
|
||||
protected function parseCsv($input)
|
||||
{
|
||||
$temp = fopen('php://memory', 'rw');
|
||||
fwrite($temp, $input);
|
||||
fseek($temp, 0);
|
||||
$res = array();
|
||||
while (($data = fgetcsv($temp)) !== false) {
|
||||
$res[] = $data;
|
||||
}
|
||||
fclose($temp);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Flash
|
||||
*
|
||||
* This is middleware for a Slim application that enables
|
||||
* Flash messaging between HTTP requests. This allows you
|
||||
* set Flash messages for the current request, for the next request,
|
||||
* or to retain messages from the previous request through to
|
||||
* the next request.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => 'slim.flash'), $settings);
|
||||
$this->messages = array(
|
||||
'prev' => array(), //flash messages from prev request (loaded when middleware called)
|
||||
'next' => array(), //flash messages for next request
|
||||
'now' => array() //flash messages for current request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
//Read flash messaging from previous request if available
|
||||
$this->loadMessages();
|
||||
|
||||
//Prepare flash messaging for current request
|
||||
$env = $this->app->environment();
|
||||
$env['slim.flash'] = $this;
|
||||
$this->next->call();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Now
|
||||
*
|
||||
* Specify a flash message for a given key to be shown for the current request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function now($key, $value)
|
||||
{
|
||||
$this->messages['now'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set
|
||||
*
|
||||
* Specify a flash message for a given key to be shown for the next request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->messages['next'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep
|
||||
*
|
||||
* Retain flash messages from the previous request for the next request
|
||||
*/
|
||||
public function keep()
|
||||
{
|
||||
foreach ($this->messages['prev'] as $key => $val) {
|
||||
$this->messages['next'][$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$_SESSION[$this->settings['key']] = $this->messages['next'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load messages from previous request if available
|
||||
*/
|
||||
public function loadMessages()
|
||||
{
|
||||
if (isset($_SESSION[$this->settings['key']])) {
|
||||
$this->messages['prev'] = $_SESSION[$this->settings['key']];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of flash messages to be shown for the current request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return array_merge($this->messages['prev'], $this->messages['now']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]) ? $messages[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->now($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->messages['prev'][$offset], $this->messages['now'][$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Aggregate: Get Iterator
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return new \ArrayIterator($messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable: Count
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->getMessages());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* HTTP Method Override
|
||||
*
|
||||
* This is middleware for a Slim application that allows traditional
|
||||
* desktop browsers to submit pseudo PUT and DELETE requests by relying
|
||||
* on a pre-determined request parameter. Without this middleware,
|
||||
* desktop browsers are only able to submit GET and POST requests.
|
||||
*
|
||||
* This middleware is included automatically!
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class MethodOverride extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => '_METHOD'), $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*
|
||||
* Implements Slim middleware interface. This method is invoked and passed
|
||||
* an array of environment variables. This middleware inspects the environment
|
||||
* variables for the HTTP method override parameter; if found, this middleware
|
||||
* modifies the environment settings so downstream middleware and/or the Slim
|
||||
* application will treat the request with the desired HTTP method.
|
||||
*
|
||||
* @return array[status, header, body]
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$env = $this->app->environment();
|
||||
if (isset($env['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
|
||||
// Header commonly used by Backbone.js and others
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($env['HTTP_X_HTTP_METHOD_OVERRIDE']);
|
||||
} elseif (isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST') {
|
||||
// HTML Form Override
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$method = $req->post($this->settings['key']);
|
||||
if ($method) {
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($method);
|
||||
}
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Pretty Exceptions
|
||||
*
|
||||
* This middleware catches any Exception thrown by the surrounded
|
||||
* application and displays a developer-friendly diagnostic screen.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class PrettyExceptions extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
try {
|
||||
$this->next->call();
|
||||
} catch (\Exception $e) {
|
||||
$log = $this->app->getLog(); // Force Slim to append log to env if not already
|
||||
$env = $this->app->environment();
|
||||
$env['slim.log'] = $log;
|
||||
$env['slim.log']->error($e);
|
||||
$this->app->contentType('text/html');
|
||||
$this->app->response()->status(500);
|
||||
$this->app->response()->body($this->renderBody($env, $e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render response body
|
||||
* @param array $env
|
||||
* @param \Exception $exception
|
||||
* @return string
|
||||
*/
|
||||
protected function renderBody(&$env, $exception)
|
||||
{
|
||||
$title = 'Slim Application Error';
|
||||
$code = $exception->getCode();
|
||||
$message = $exception->getMessage();
|
||||
$file = $exception->getFile();
|
||||
$line = $exception->getLine();
|
||||
$trace = str_replace(array('#', '\n'), array('<div>#', '</div>'), $exception->getTraceAsString());
|
||||
$html = sprintf('<h1>%s</h1>', $title);
|
||||
$html .= '<p>The application could not run because of the following error:</p>';
|
||||
$html .= '<h2>Details</h2>';
|
||||
$html .= sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));
|
||||
if ($code) {
|
||||
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
|
||||
}
|
||||
if ($message) {
|
||||
$html .= sprintf('<div><strong>Message:</strong> %s</div>', $message);
|
||||
}
|
||||
if ($file) {
|
||||
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
|
||||
}
|
||||
if ($line) {
|
||||
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
|
||||
}
|
||||
if ($trace) {
|
||||
$html .= '<h2>Trace</h2>';
|
||||
$html .= sprintf('<pre>%s</pre>', $trace);
|
||||
}
|
||||
|
||||
return sprintf("<html><head><title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:65px;}</style></head><body>%s</body></html>", $title, $html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Session Cookie
|
||||
*
|
||||
* This class provides an HTTP cookie storage mechanism
|
||||
* for session data. This class avoids using a PHP session
|
||||
* and instead serializes/unserializes the $_SESSION global
|
||||
* variable to/from an HTTP cookie.
|
||||
*
|
||||
* You should NEVER store sensitive data in a client-side cookie
|
||||
* in any format, encrypted (with cookies.encrypt) or not. If you
|
||||
* need to store sensitive user information in a session, you should
|
||||
* rely on PHP's native session implementation, or use other middleware
|
||||
* to store session data in a database or alternative server-side cache.
|
||||
*
|
||||
* Because this class stores serialized session data in an HTTP cookie,
|
||||
* you are inherently limited to 4 Kb. If you attempt to store
|
||||
* more than this amount, serialization will fail.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class SessionCookie extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$defaults = array(
|
||||
'expires' => '20 minutes',
|
||||
'path' => '/',
|
||||
'domain' => null,
|
||||
'secure' => false,
|
||||
'httponly' => false,
|
||||
'name' => 'slim_session',
|
||||
);
|
||||
$this->settings = array_merge($defaults, $settings);
|
||||
if (is_string($this->settings['expires'])) {
|
||||
$this->settings['expires'] = strtotime($this->settings['expires']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Session
|
||||
*
|
||||
* We must start a native PHP session to initialize the $_SESSION superglobal.
|
||||
* However, we won't be using the native session store for persistence, so we
|
||||
* disable the session cookie and cache limiter. We also set the session
|
||||
* handler to this class instance to avoid PHP's native session file locking.
|
||||
*/
|
||||
ini_set('session.use_cookies', 0);
|
||||
session_cache_limiter(false);
|
||||
session_set_save_handler(
|
||||
array($this, 'open'),
|
||||
array($this, 'close'),
|
||||
array($this, 'read'),
|
||||
array($this, 'write'),
|
||||
array($this, 'destroy'),
|
||||
array($this, 'gc')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$this->loadSession();
|
||||
$this->next->call();
|
||||
$this->saveSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load session
|
||||
*/
|
||||
protected function loadSession()
|
||||
{
|
||||
if (session_id() === '') {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$value = $this->app->getCookie($this->settings['name']);
|
||||
|
||||
if ($value) {
|
||||
try {
|
||||
$_SESSION = unserialize($value);
|
||||
} catch (\Exception $e) {
|
||||
$this->app->getLog()->error('Error unserializing session cookie value! ' . $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$_SESSION = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save session
|
||||
*/
|
||||
protected function saveSession()
|
||||
{
|
||||
$value = serialize($_SESSION);
|
||||
|
||||
if (strlen($value) > 4096) {
|
||||
$this->app->getLog()->error('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.');
|
||||
} else {
|
||||
$this->app->setCookie(
|
||||
$this->settings['name'],
|
||||
$value,
|
||||
$this->settings['expires'],
|
||||
$this->settings['path'],
|
||||
$this->settings['domain'],
|
||||
$this->settings['secure'],
|
||||
$this->settings['httponly']
|
||||
);
|
||||
}
|
||||
// session_destroy();
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Session Handler
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function open($savePath, $sessionName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function read($id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function write($id, $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function gc($maxlifetime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+357
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim Framework (http://slimframework.com)
|
||||
*
|
||||
* @link https://github.com/slimphp/Slim
|
||||
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Handlers\Strategies\RequestResponse;
|
||||
use Slim\Interfaces\InvocationStrategyInterface;
|
||||
use Slim\Interfaces\RouteInterface;
|
||||
|
||||
/**
|
||||
* Route
|
||||
*/
|
||||
class Route extends Routable implements RouteInterface
|
||||
{
|
||||
use MiddlewareAwareTrait;
|
||||
|
||||
/**
|
||||
* HTTP methods supported by this route
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $methods = [];
|
||||
|
||||
/**
|
||||
* Route identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $identifier;
|
||||
|
||||
/**
|
||||
* Route name
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Parent route groups
|
||||
*
|
||||
* @var RouteGroup[]
|
||||
*/
|
||||
protected $groups;
|
||||
|
||||
private $finalized = false;
|
||||
|
||||
/**
|
||||
* Output buffering mode
|
||||
*
|
||||
* One of: false, 'prepend' or 'append'
|
||||
*
|
||||
* @var boolean|string
|
||||
*/
|
||||
protected $outputBuffering = 'append';
|
||||
|
||||
/**
|
||||
* Route parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $arguments = [];
|
||||
|
||||
/**
|
||||
* Create new route
|
||||
*
|
||||
* @param string[] $methods The route HTTP methods
|
||||
* @param string $pattern The route pattern
|
||||
* @param callable $callable The route callable
|
||||
* @param int $identifier The route identifier
|
||||
* @param RouteGroup[] $groups The parent route groups
|
||||
*/
|
||||
public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
|
||||
{
|
||||
$this->methods = $methods;
|
||||
$this->pattern = $pattern;
|
||||
$this->callable = $callable;
|
||||
$this->groups = $groups;
|
||||
$this->identifier = 'route' . $identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the route in preparation for dispatching
|
||||
*/
|
||||
public function finalize()
|
||||
{
|
||||
if ($this->finalized) {
|
||||
return;
|
||||
}
|
||||
|
||||
$groupMiddleware = [];
|
||||
foreach ($this->getGroups() as $group) {
|
||||
$groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware);
|
||||
}
|
||||
|
||||
$this->middleware = array_merge($this->middleware, $groupMiddleware);
|
||||
|
||||
foreach ($this->getMiddleware() as $middleware) {
|
||||
$this->addMiddleware($middleware);
|
||||
}
|
||||
|
||||
$this->finalized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route callable
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function getCallable()
|
||||
{
|
||||
return $this->callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route methods
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getMethods()
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent route groups
|
||||
*
|
||||
* @return RouteGroup[]
|
||||
*/
|
||||
public function getGroups()
|
||||
{
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route name
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier()
|
||||
{
|
||||
return $this->identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output buffering mode
|
||||
*
|
||||
* @return boolean|string
|
||||
*/
|
||||
public function getOutputBuffering()
|
||||
{
|
||||
return $this->outputBuffering;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set output buffering mode
|
||||
*
|
||||
* One of: false, 'prepend' or 'append'
|
||||
*
|
||||
* @param boolean|string $mode
|
||||
*
|
||||
* @throws InvalidArgumentException If an unknown buffering mode is specified
|
||||
*/
|
||||
public function setOutputBuffering($mode)
|
||||
{
|
||||
if (!in_array($mode, [false, 'prepend', 'append'], true)) {
|
||||
throw new InvalidArgumentException('Unknown output buffering mode');
|
||||
}
|
||||
$this->outputBuffering = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws InvalidArgumentException if the route name is not a string
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
if (!is_string($name)) {
|
||||
throw new InvalidArgumentException('Route name must be a string');
|
||||
}
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a route argument
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setArgument($name, $value)
|
||||
{
|
||||
$this->arguments[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace route arguments
|
||||
*
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve route arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a specific route argument
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getArgument($name, $default = null)
|
||||
{
|
||||
if (array_key_exists($name, $this->arguments)) {
|
||||
return $this->arguments[$name];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Route Runner
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* Prepare the route for use
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param array $arguments
|
||||
*/
|
||||
public function prepare(ServerRequestInterface $request, array $arguments)
|
||||
{
|
||||
// Add the arguments
|
||||
foreach ($arguments as $k => $v) {
|
||||
$this->setArgument($k, $v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run route
|
||||
*
|
||||
* This method traverses the middleware stack, including the route's callable
|
||||
* and captures the resultant HTTP response object. It then sends the response
|
||||
* back to the Application.
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function run(ServerRequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
// Finalise route now that we are about to run it
|
||||
$this->finalize();
|
||||
|
||||
// Traverse middleware stack and fetch updated response
|
||||
return $this->callMiddlewareStack($request, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch route callable against current Request and Response objects
|
||||
*
|
||||
* This method invokes the route object's callable. If middleware is
|
||||
* registered for the route, each callable middleware is invoked in
|
||||
* the order specified.
|
||||
*
|
||||
* @param ServerRequestInterface $request The current Request object
|
||||
* @param ResponseInterface $response The current Response object
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
* @throws \Exception if the route callable throws an exception
|
||||
*/
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$this->callable = $this->resolveCallable($this->callable);
|
||||
|
||||
/** @var InvocationStrategyInterface $handler */
|
||||
$handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse();
|
||||
|
||||
// invoke route callable
|
||||
if ($this->outputBuffering === false) {
|
||||
$newResponse = $handler($this->callable, $request, $response, $this->arguments);
|
||||
} else {
|
||||
try {
|
||||
ob_start();
|
||||
$newResponse = $handler($this->callable, $request, $response, $this->arguments);
|
||||
$output = ob_get_clean();
|
||||
} catch (Exception $e) {
|
||||
ob_end_clean();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if ($newResponse instanceof ResponseInterface) {
|
||||
// if route callback returns a ResponseInterface, then use it
|
||||
$response = $newResponse;
|
||||
} elseif (is_string($newResponse)) {
|
||||
// if route callback returns a string, then append it to the response
|
||||
if ($response->getBody()->isWritable()) {
|
||||
$response->getBody()->write($newResponse);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($output) && $response->getBody()->isWritable()) {
|
||||
if ($this->outputBuffering === 'prepend') {
|
||||
// prepend output buffer content
|
||||
$body = new Http\Body(fopen('php://temp', 'r+'));
|
||||
$body->write($output . $response->getBody());
|
||||
$response = $response->withBody($body);
|
||||
} elseif ($this->outputBuffering === 'append') {
|
||||
// append output buffer content
|
||||
$response->getBody()->write($output);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
+383
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim Framework (http://slimframework.com)
|
||||
*
|
||||
* @link https://github.com/slimphp/Slim
|
||||
* @copyright Copyright (c) 2011-2015 Josh Lockhart
|
||||
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
use FastRoute\Dispatcher;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use FastRoute\RouteCollector;
|
||||
use FastRoute\RouteParser;
|
||||
use FastRoute\RouteParser\Std as StdParser;
|
||||
use FastRoute\DataGenerator;
|
||||
use Slim\Interfaces\RouteGroupInterface;
|
||||
use Slim\Interfaces\RouterInterface;
|
||||
use Slim\Interfaces\RouteInterface;
|
||||
|
||||
/**
|
||||
* Router
|
||||
*
|
||||
* This class organizes Slim application route objects. It is responsible
|
||||
* for registering route objects, assigning names to route objects,
|
||||
* finding routes that match the current HTTP request, and creating
|
||||
* URLs for a named route.
|
||||
*/
|
||||
class Router implements RouterInterface
|
||||
{
|
||||
/**
|
||||
* Parser
|
||||
*
|
||||
* @var \FastRoute\RouteParser
|
||||
*/
|
||||
protected $routeParser;
|
||||
|
||||
/**
|
||||
* Base path used in pathFor()
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $basePath = '';
|
||||
|
||||
/**
|
||||
* Routes
|
||||
*
|
||||
* @var Route[]
|
||||
*/
|
||||
protected $routes = [];
|
||||
|
||||
/**
|
||||
* Route counter incrementer
|
||||
* @var int
|
||||
*/
|
||||
protected $routeCounter = 0;
|
||||
|
||||
/**
|
||||
* Named routes
|
||||
*
|
||||
* @var null|Route[]
|
||||
*/
|
||||
protected $namedRoutes;
|
||||
|
||||
/**
|
||||
* Route groups
|
||||
*
|
||||
* @var RouteGroup[]
|
||||
*/
|
||||
protected $routeGroups = [];
|
||||
|
||||
/**
|
||||
* @var \FastRoute\Dispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
/**
|
||||
* Create new router
|
||||
*
|
||||
* @param RouteParser $parser
|
||||
*/
|
||||
public function __construct(RouteParser $parser = null)
|
||||
{
|
||||
$this->routeParser = $parser ?: new StdParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base path used in pathFor()
|
||||
*
|
||||
* @param string $basePath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setBasePath($basePath)
|
||||
{
|
||||
if (!is_string($basePath)) {
|
||||
throw new InvalidArgumentException('Router basePath must be a string');
|
||||
}
|
||||
|
||||
$this->basePath = $basePath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add route
|
||||
*
|
||||
* @param string[] $methods Array of HTTP methods
|
||||
* @param string $pattern The route pattern
|
||||
* @param callable $handler The route callable
|
||||
*
|
||||
* @return RouteInterface
|
||||
*
|
||||
* @throws InvalidArgumentException if the route pattern isn't a string
|
||||
*/
|
||||
public function map($methods, $pattern, $handler)
|
||||
{
|
||||
if (!is_string($pattern)) {
|
||||
throw new InvalidArgumentException('Route pattern must be a string');
|
||||
}
|
||||
|
||||
// Prepend parent group pattern(s)
|
||||
if ($this->routeGroups) {
|
||||
$pattern = $this->processGroups() . $pattern;
|
||||
}
|
||||
|
||||
// According to RFC methods are defined in uppercase (See RFC 7231)
|
||||
$methods = array_map("strtoupper", $methods);
|
||||
|
||||
// Add route
|
||||
$route = new Route($methods, $pattern, $handler, $this->routeGroups, $this->routeCounter);
|
||||
$this->routes[$route->getIdentifier()] = $route;
|
||||
$this->routeCounter++;
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch router for HTTP request
|
||||
*
|
||||
* @param ServerRequestInterface $request The current HTTP request object
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @link https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php
|
||||
*/
|
||||
public function dispatch(ServerRequestInterface $request)
|
||||
{
|
||||
$uri = '/' . ltrim($request->getUri()->getPath(), '/');
|
||||
|
||||
return $this->createDispatcher()->dispatch(
|
||||
$request->getMethod(),
|
||||
$uri
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \FastRoute\Dispatcher
|
||||
*/
|
||||
protected function createDispatcher()
|
||||
{
|
||||
return $this->dispatcher ?: \FastRoute\simpleDispatcher(function (RouteCollector $r) {
|
||||
foreach ($this->getRoutes() as $route) {
|
||||
$r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier());
|
||||
}
|
||||
}, [
|
||||
'routeParser' => $this->routeParser
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \FastRoute\Dispatcher $dispatcher
|
||||
*/
|
||||
public function setDispatcher(Dispatcher $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route objects
|
||||
*
|
||||
* @return Route[]
|
||||
*/
|
||||
public function getRoutes()
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get named route object
|
||||
*
|
||||
* @param string $name Route name
|
||||
*
|
||||
* @return Route
|
||||
*
|
||||
* @throws RuntimeException If named route does not exist
|
||||
*/
|
||||
public function getNamedRoute($name)
|
||||
{
|
||||
if (is_null($this->namedRoutes)) {
|
||||
$this->buildNameIndex();
|
||||
}
|
||||
if (!isset($this->namedRoutes[$name])) {
|
||||
throw new RuntimeException('Named route does not exist for name: ' . $name);
|
||||
}
|
||||
return $this->namedRoutes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process route groups
|
||||
*
|
||||
* @return string A group pattern to prefix routes with
|
||||
*/
|
||||
protected function processGroups()
|
||||
{
|
||||
$pattern = "";
|
||||
foreach ($this->routeGroups as $group) {
|
||||
$pattern .= $group->getPattern();
|
||||
}
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a route group to the array
|
||||
*
|
||||
* @param string $pattern
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return RouteGroupInterface
|
||||
*/
|
||||
public function pushGroup($pattern, $callable)
|
||||
{
|
||||
$group = new RouteGroup($pattern, $callable);
|
||||
array_push($this->routeGroups, $group);
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last route group from the array
|
||||
*
|
||||
* @return RouteGroup|bool The RouteGroup if successful, else False
|
||||
*/
|
||||
public function popGroup()
|
||||
{
|
||||
$group = array_pop($this->routeGroups);
|
||||
return $group instanceof RouteGroup ? $group : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $identifier
|
||||
* @return \Slim\Interfaces\RouteInterface
|
||||
*/
|
||||
public function lookupRoute($identifier)
|
||||
{
|
||||
if (!isset($this->routes[$identifier])) {
|
||||
throw new RuntimeException('Route not found, looks like your route cache is stale.');
|
||||
}
|
||||
return $this->routes[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the path for a named route excluding the base path
|
||||
*
|
||||
* @param string $name Route name
|
||||
* @param array $data Named argument replacement data
|
||||
* @param array $queryParams Optional query string parameters
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException If named route does not exist
|
||||
* @throws InvalidArgumentException If required data not provided
|
||||
*/
|
||||
public function relativePathFor($name, array $data = [], array $queryParams = [])
|
||||
{
|
||||
$route = $this->getNamedRoute($name);
|
||||
$pattern = $route->getPattern();
|
||||
|
||||
$routeDatas = $this->routeParser->parse($pattern);
|
||||
// $routeDatas is an array of all possible routes that can be made. There is
|
||||
// one routedata for each optional parameter plus one for no optional parameters.
|
||||
//
|
||||
// The most specific is last, so we look for that first.
|
||||
$routeDatas = array_reverse($routeDatas);
|
||||
|
||||
$segments = [];
|
||||
foreach ($routeDatas as $routeData) {
|
||||
foreach ($routeData as $item) {
|
||||
if (is_string($item)) {
|
||||
// this segment is a static string
|
||||
$segments[] = $item;
|
||||
continue;
|
||||
}
|
||||
|
||||
// This segment has a parameter: first element is the name
|
||||
if (!array_key_exists($item[0], $data)) {
|
||||
// we don't have a data element for this segment: cancel
|
||||
// testing this routeData item, so that we can try a less
|
||||
// specific routeData item.
|
||||
$segments = [];
|
||||
$segmentName = $item[0];
|
||||
break;
|
||||
}
|
||||
$segments[] = $data[$item[0]];
|
||||
}
|
||||
if (!empty($segments)) {
|
||||
// we found all the parameters for this route data, no need to check
|
||||
// less specific ones
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($segments)) {
|
||||
throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName);
|
||||
}
|
||||
$url = implode('', $segments);
|
||||
|
||||
if ($queryParams) {
|
||||
$url .= '?' . http_build_query($queryParams);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build the path for a named route including the base path
|
||||
*
|
||||
* @param string $name Route name
|
||||
* @param array $data Named argument replacement data
|
||||
* @param array $queryParams Optional query string parameters
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException If named route does not exist
|
||||
* @throws InvalidArgumentException If required data not provided
|
||||
*/
|
||||
public function pathFor($name, array $data = [], array $queryParams = [])
|
||||
{
|
||||
$url = $this->relativePathFor($name, $data, $queryParams);
|
||||
|
||||
if ($this->basePath) {
|
||||
$url = $this->basePath . $url;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the path for a named route.
|
||||
*
|
||||
* This method is deprecated. Use pathFor() from now on.
|
||||
*
|
||||
* @param string $name Route name
|
||||
* @param array $data Named argument replacement data
|
||||
* @param array $queryParams Optional query string parameters
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException If named route does not exist
|
||||
* @throws InvalidArgumentException If required data not provided
|
||||
*/
|
||||
public function urlFor($name, array $data = [], array $queryParams = [])
|
||||
{
|
||||
trigger_error('urlFor() is deprecated. Use pathFor() instead.', E_USER_DEPRECATED);
|
||||
return $this->pathFor($name, $data, $queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build index of named routes
|
||||
*/
|
||||
protected function buildNameIndex()
|
||||
{
|
||||
$this->namedRoutes = [];
|
||||
foreach ($this->routes as $route) {
|
||||
$name = $route->getName();
|
||||
if ($name) {
|
||||
$this->namedRoutes[$name] = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1412
File diff suppressed because it is too large
Load Diff
+282
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <[email protected]>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.4.2
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* The view is responsible for rendering a template. The view
|
||||
* should subclass \Slim\View and implement this interface:
|
||||
*
|
||||
* public render(string $template);
|
||||
*
|
||||
* This method should render the specified template and return
|
||||
* the resultant string.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* Data available to the view templates
|
||||
* @var \Slim\Helper\Set
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Path to templates base directory (without trailing slash)
|
||||
* @var string
|
||||
*/
|
||||
protected $templatesDirectory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->data = new \Slim\Helper\Set();
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Data methods
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* Does view data have value with key?
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return $this->data->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return view data value with key
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return $this->data->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set view data value with key
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->data->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set view data value as Closure with key
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function keep($key, Closure $value)
|
||||
{
|
||||
$this->data->keep($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return view data
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->data->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace view data
|
||||
* @param array $data
|
||||
*/
|
||||
public function replace(array $data)
|
||||
{
|
||||
$this->data->replace($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear view data
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->data->clear();
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Legacy data methods
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release
|
||||
*
|
||||
* Get data from view
|
||||
*/
|
||||
public function getData($key = null)
|
||||
{
|
||||
if (!is_null($key)) {
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
} else {
|
||||
return $this->data->all();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release
|
||||
*
|
||||
* Set data for view
|
||||
*/
|
||||
public function setData()
|
||||
{
|
||||
$args = func_get_args();
|
||||
if (count($args) === 1 && is_array($args[0])) {
|
||||
$this->data->replace($args[0]);
|
||||
} elseif (count($args) === 2) {
|
||||
// Ensure original behavior is maintained. DO NOT invoke stored Closures.
|
||||
if (is_object($args[1]) && method_exists($args[1], '__invoke')) {
|
||||
$this->data->set($args[0], $this->data->protect($args[1]));
|
||||
} else {
|
||||
$this->data->set($args[0], $args[1]);
|
||||
}
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATION WARNING! This method will be removed in the next major point release
|
||||
*
|
||||
* Append data to view
|
||||
* @param array $data
|
||||
*/
|
||||
public function appendData($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
|
||||
}
|
||||
$this->data->replace($data);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Resolve template paths
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* Set the base directory that contains view templates
|
||||
* @param string $directory
|
||||
* @throws \InvalidArgumentException If directory is not a directory
|
||||
*/
|
||||
public function setTemplatesDirectory($directory)
|
||||
{
|
||||
$this->templatesDirectory = rtrim($directory, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates base directory
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplatesDirectory()
|
||||
{
|
||||
return $this->templatesDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fully qualified path to template file using templates base directory
|
||||
* @param string $file The template file pathname relative to templates base directory
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplatePathname($file)
|
||||
{
|
||||
return $this->templatesDirectory . DIRECTORY_SEPARATOR . ltrim($file, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Rendering
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* Display template
|
||||
*
|
||||
* This method echoes the rendered template to the current output buffer
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directory
|
||||
* @param array $data Any additonal data to be passed to the template.
|
||||
*/
|
||||
public function display($template, $data = null)
|
||||
{
|
||||
echo $this->fetch($template, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contents of a rendered template file
|
||||
*
|
||||
* @param string $template The template pathname, relative to the template base directory
|
||||
* @param array $data Any additonal data to be passed to the template.
|
||||
* @return string The rendered template
|
||||
*/
|
||||
public function fetch($template, $data = null)
|
||||
{
|
||||
return $this->render($template, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a template file
|
||||
*
|
||||
* NOTE: This method should be overridden by custom view subclasses
|
||||
*
|
||||
* @param string $template The template pathname, relative to the template base directory
|
||||
* @param array $data Any additonal data to be passed to the template.
|
||||
* @return string The rendered template
|
||||
* @throws \RuntimeException If resolved template pathname is not a valid file
|
||||
*/
|
||||
protected function render($template, $data = null)
|
||||
{
|
||||
$templatePathname = $this->getTemplatePathname($template);
|
||||
if (!is_file($templatePathname)) {
|
||||
throw new \RuntimeException("View cannot render `$template` because the template does not exist");
|
||||
}
|
||||
|
||||
$data = array_merge($this->data->all(), (array) $data);
|
||||
extract($data);
|
||||
ob_start();
|
||||
require $templatePathname;
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
$allowedHost = array(
|
||||
"localhost",
|
||||
"denisnotebook",
|
||||
"app.gruppolapastamadre.it",
|
||||
"dev.gruppolapastamadre.it",
|
||||
"old.gruppolapastamadre.it",
|
||||
"management.gruppolapastamadre.it"
|
||||
);
|
||||
|
||||
$dirRicetteDropBox = "IlLievitario/Images/Ricette";
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
// inclusione del file contenente la classe
|
||||
require_once "./include.php";
|
||||
require_once "./myDropBoxObj.php";
|
||||
//include "./SimpleImage.php";
|
||||
|
||||
$app->get('/photos/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 = "jpg";
|
||||
} 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 '<img src="';
|
||||
}
|
||||
echo $dropBoxObj->GetLink($folder . "/" . $imageFileName);
|
||||
if ($createImgTag) {
|
||||
echo '"/>';
|
||||
}
|
||||
});
|
||||
|
||||
$app->get('/photos/: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 = "jpg";
|
||||
} 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 '<img src="';
|
||||
}
|
||||
echo $dropBoxObj->GetLink($folder . "/" . $imageFileName);
|
||||
if ($createImgTag) {
|
||||
echo '"/>';
|
||||
}
|
||||
});
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
require_once "./config.inc.php";
|
||||
|
||||
// inclusione del file contenente la classe
|
||||
require_once "./MySqlClass.php";
|
||||
require_once "./utility.php";
|
||||
require_once "./Middleware/CheckFrom.php";
|
||||
|
||||
require_once 'Slim/Slim.php';
|
||||
|
||||
\Slim\Slim::registerAutoloader();
|
||||
|
||||
$app = new \Slim\Slim();
|
||||
|
||||
date_default_timezone_set('Europe/Rome');
|
||||
|
||||
$app->add( new CheckFromMV() );
|
||||
|
||||
?>
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
$app->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();
|
||||
|
||||
returnJsonWithDecode($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();
|
||||
|
||||
returnJsonWithDecode($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();
|
||||
|
||||
returnJsonWithDecode($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$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";
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->delete('/ricetta/:itemID', function ($itemID) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
// istanza della classe
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "DELETE FROM ricette WHERE ricette.ID = " . $itemID;
|
||||
$retObj = $mysqlconnetion->insertRecord($query);
|
||||
|
||||
$mysqlconnetion->disconnetti();
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricetta/body/:itemID', function ($itemID) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
// istanza della classe
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "SELECT id_categoria, categorie.name AS categoria_name, ricette.ID AS ricetta_id, titolo, procedimento, autore, link_fonte, link_youtube, valutazione, difficolta 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->post('/typeingredients', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$json_data_body = json_decode($app->request()->post('bodydata'));
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$query = "insert into tipo_ingredienti(Name) values ('" . $json_data_body->name . "')";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
$app->post('/ricetta/body', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$json_data_body = json_decode($app->request()->post('bodydata'));
|
||||
$retValue["result"] = true;
|
||||
$retValue["message"] = "";
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
// istanza della classe
|
||||
try {
|
||||
$retNewID = 0;
|
||||
if ($json_data_body->ricettaID != "") {
|
||||
$query = "update ricette SET ID_CATEGORIA = " . $json_data_body->categoria_id .
|
||||
", titolo = '" . htmlentities($json_data_body->titolo, null, "UTF-8") .
|
||||
"', procedimento = '" . str_replace("'", "''", htmlentities($json_data_body->preparazione, null, "UTF-8")) .
|
||||
"', autore = '" . str_replace("'", "''", $json_data_body->autore) .
|
||||
"', link_fonte = '" . $json_data_body->linkFonte .
|
||||
"', Link_youtube = '" . $json_data_body->linkVideo .
|
||||
"', Difficolta = '" . $json_data_body->difficolta .
|
||||
"' where ID = " . $json_data_body->ricettaID;
|
||||
|
||||
$mysqlconnetion->executeQuery($query);
|
||||
$queryDelete = "DELETE FROM ingredienti where ID_RICETTE = " . $json_data_body->ricettaID;
|
||||
$mysqlconnetion->executeQuery($queryDelete);
|
||||
$retNewID = $json_data_body->ricettaID;
|
||||
} else {
|
||||
|
||||
$query = "insert into ricette(ID_CATEGORIA, titolo, procedimento, autore, link_fonte, Link_youtube,Difficolta) values (" .
|
||||
$json_data_body->categoria_id . ",'" . htmlentities($json_data_body->titolo, null, "UTF-8") . "','" . str_replace("'", "''", htmlentities($json_data_body->preparazione, null, "UTF-8")) .
|
||||
"','" . str_replace("'", "''", $json_data_body->autore) . "','" .
|
||||
$json_data_body->linkFonte . "','" . $json_data_body->linkVideo . "', " . $json_data_body->difficolta . ")";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
}
|
||||
|
||||
$pos = 0;
|
||||
foreach ($json_data_body->ingredienti as $arr) {
|
||||
$note = "";
|
||||
if ($arr->note != "") {
|
||||
$note = str_replace("'", "''", htmlentities($arr->note, null, "UTF-8"));
|
||||
}
|
||||
|
||||
$query = "insert into ingredienti(ID_TIPO_INGREDIENTI, ID_RICETTE, Quantita, ID_TIPO_QUANTITA, Note, Posizione) values (" .
|
||||
$arr->ingrediente_id . "," . $retNewID . "," . ($arr->quantita == "" ? "0" : $arr->quantita) . "," . ($arr->tipo_quantita_id == "" ? "NULL" : $arr->tipo_quantita_id) . ",'" . $note . "'," . $pos . ")";
|
||||
|
||||
$mysqlconnetion->insertRecord($query);
|
||||
$pos = $pos + 1;
|
||||
}
|
||||
|
||||
$retValue["message"] = "Ricetta inserita con successo";
|
||||
} catch (Exception $e) {
|
||||
$retValue["message"] = $e->getMessage();
|
||||
}
|
||||
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retValue);
|
||||
});
|
||||
|
||||
$app->get('/photos/', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
|
||||
$query = "SELECT * from ( SELECT id as ricetta_id, `titolo`,`autore`, ".
|
||||
" (select COUNT(*) from immagini where immagini.id_ricette = `ricette`.id) as num_img,".
|
||||
" (select COUNT(*) from immagini where immagini.id_ricette = `ricette`.id and immagini.published = 1) as num_img_pub".
|
||||
" FROM `ricette`".
|
||||
" ) as tmp".
|
||||
" WHERE tmp.num_img> 0";
|
||||
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricetta/:itemID/photos', function ($itemID) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
|
||||
$query = "SELECT id as id_photo, type_format, from_profile_id, uploaded_date, profilo.Name as profile_name, published from immagini" .
|
||||
" INNER JOIN profilo ON profilo.ProfiloID = immagini.from_profile_id".
|
||||
" WHERE id_ricette = " . $itemID;
|
||||
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
require_once "./myDropBoxObj.php";
|
||||
use PHPImageWorkshop\ImageWorkshop;
|
||||
require_once('./PHPImageWorkshop/ImageWorkshop.php'); // Be sure of the path to the class
|
||||
|
||||
date_default_timezone_set("Europe/Rome");
|
||||
|
||||
$dirRicetteDropBox = "IlLievitario/Images/Ricette";
|
||||
|
||||
$tmpFileName = "C:/Users/Denis/Desktop/Chiaravalle/Jpg/DSC_7731.jpg";
|
||||
$ext = pathinfo($tmpFileName, PATHINFO_EXTENSION);
|
||||
|
||||
$idRicette = 5;
|
||||
|
||||
$newID = 125;
|
||||
|
||||
$imageFileName = $newID . "_full_ricetta." . $ext;
|
||||
|
||||
$thumbFileName = $newID . "_thumb_ricetta." . $ext;
|
||||
|
||||
$dropBoxObj = new myDropBox();
|
||||
|
||||
$folder = $dirRicetteDropBox . "/" . $idRicette;
|
||||
/*
|
||||
echo $dropBoxObj->GetLink($folder . "/" . $imageFileName);
|
||||
|
||||
return;
|
||||
*/
|
||||
$layer = ImageWorkshop::initFromPath($tmpFileName);
|
||||
|
||||
echo $layer->getImage()->image_type;
|
||||
return;
|
||||
|
||||
$layer->resizeByLargestSideInPixel(640, true);
|
||||
|
||||
$layer->save(dirname($tmpFileName), $imageFileName);
|
||||
|
||||
$imgData = addslashes(file_get_contents($tmpFileName));
|
||||
|
||||
$layer->resizeByLargestSideInPixel(300, true);
|
||||
|
||||
$layer->save(dirname($tmpFileName), $thumbFileName);
|
||||
|
||||
try {
|
||||
$dropBoxObj->CreateFolder($folder);
|
||||
} catch (DropboxException $ex) {
|
||||
|
||||
}
|
||||
|
||||
$dropBoxObj->UploadFile(dirname($tmpFileName) . "/" . $imageFileName, $folder . "/" . $imageFileName);
|
||||
|
||||
$dropBoxObj->UploadFile(dirname($tmpFileName) . "/" . $thumbFileName, $folder . "/" . $thumbFileName);
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
require_once("./DropBoxPhp/DropboxClient.php");
|
||||
|
||||
class myDropBox {
|
||||
|
||||
private $dropbox = null;
|
||||
|
||||
// costruttore
|
||||
public function __construct() {
|
||||
// you have to create an app at https://www.dropbox.com/developers/apps and enter details below:
|
||||
$this->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. <a href='$auth_url'>Click here.</a>");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private function store_token($token, $name) {
|
||||
if (!file_put_contents("tokens/$name.token", serialize($token)))
|
||||
die('<br />Could not store token! <b>Make sure that the directory `tokens` exists and is writable!</b>');
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
browser.id=Chrome.INTEGRATED
|
||||
copy.src.files=false
|
||||
copy.src.on.open=false
|
||||
copy.src.target=
|
||||
hostname=localhost
|
||||
port=8888
|
||||
router=mdbTester.php
|
||||
run.as=INTERNAL
|
||||
url=http://localhost:8888/
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||
<group/>
|
||||
</open-files>
|
||||
</project-private>
|
||||
@@ -0,0 +1,7 @@
|
||||
include.path=${php.global.include.path}
|
||||
php.version=PHP_53
|
||||
source.encoding=UTF-8
|
||||
src.dir=.
|
||||
tags.asp=false
|
||||
tags.short=false
|
||||
web.root=.
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.php.project</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/php-project/1">
|
||||
<name>Service</name>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
// inclusione del file contenente la classe
|
||||
//include "./MySqlClass.php";
|
||||
//include "./utility.php";
|
||||
|
||||
$app->get('/profile/statusCache', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "select 0 as ID_CATEGORIA, MAX(Data_creazione) as LastDateModified from categorie" .
|
||||
" UNION" .
|
||||
" select ID_CATEGORIA, MAX(Data_creazione) as LastDateModified from ricette" .
|
||||
" GROUP BY ID_CATEGORIA";
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/profile/:keyStore/ricetta/:ricetta_id', function ($keyStore, $ricetta_id) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "select COUNT(*) as Exist FROM blocco_note where ricetta_id = " . $ricetta_id . " AND ProfiloID = '" . $keyStore . "'";
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retObj[0]["Exist"]);
|
||||
});
|
||||
|
||||
$app->post('/profile/ricetta', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$json_data_body = json_decode($app->request()->post('dataPair'));
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "update profilo set BloccoNoteUpdated = CURRENT_TIMESTAMP WHERE ProfiloID = '" . $json_data_body->keyStore . "'";
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$query = "insert into blocco_note(ricetta_id, ProfiloID) values (" . $json_data_body->ricetta_id . ", '" . $json_data_body->keyStore . "')";
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
$app->delete('/profile/:keyStore/ricetta/:ricetta_id', function ($keyStore, $ricetta_id) use ($app) {
|
||||
//$callbackFn = $app->request()->params('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "delete from blocco_note where ricetta_id = " . $ricetta_id . " AND ProfiloID = '" . $keyStore . "'";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
echo $retNewID;
|
||||
//returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
$app->delete('/profile/:keyStore/ricette', function ($keyStore) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "delete from blocco_note where ProfiloID = '" . $keyStore . "'";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
$app->get('/profile/:keyStore/ricette', function ($keyStore) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "select ID as ricetta_id, titolo, autore, valutazione, difficolta from ricette" .
|
||||
" INNER JOIN blocco_note ON blocco_note.ricetta_id = ricette.id" .
|
||||
" where blocco_note.ProfiloID = '" . $keyStore . "' order by titolo, autore";
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
foreach ($retObj as $ele) {
|
||||
$ele["titolo"] = html_entity_decode($ele["titolo"]);
|
||||
}
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/profile/:keyStore', function ($keyStore) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "select ProfiloID, TipoAccesso, RisultatiRicerca, TemaUI, Name, Gender, 0 as NumRicette, BloccoNoteUpdated from profilo" .
|
||||
" where ProfiloID = '" . $keyStore . "'";
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$query = "update profilo set PenultimoAccesso = UltimoAccesso, UltimoAccesso = NOW() where ProfiloID = '" . $keyStore . "'";
|
||||
$mysqlconnetion->insertRecord($query);
|
||||
|
||||
$query = "SELECT COUNT( * ) as NumNotifiche" .
|
||||
" FROM notifiche" .
|
||||
" inner join conferma_lettura_profilo on notifiche.id = conferma_lettura_profilo.id_notifica" .
|
||||
" where conferma_lettura_profilo.id_profilo = '" . $keyStore . "' and notifiche.Type = 1 ".
|
||||
" AND conferma_lettura_profilo.conferma_lettura = 0";
|
||||
|
||||
$retObj2 = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$retObj[0]["NumNotifiche"] = $retObj2[0]["NumNotifiche"];
|
||||
|
||||
$query = "SELECT COUNT( * ) as NumLastRicette ".
|
||||
" FROM notifiche" .
|
||||
" inner join conferma_lettura_profilo on notifiche.id = conferma_lettura_profilo.id_notifica" .
|
||||
" where conferma_lettura_profilo.id_profilo = '" . $keyStore . "' and notifiche.Type = 2" .
|
||||
" AND conferma_lettura_profilo.conferma_lettura = 0" .
|
||||
" ORDER BY CreatoIl desc" .
|
||||
" LIMIT 1";
|
||||
|
||||
$retObj3 = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$retObj[0]["NumLastRicette"] = $retObj3[0]["NumLastRicette"];
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/profile/:keyStore/notification/:id', function ($keyStore, $idNotification) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
|
||||
$query = "SELECT id, titolo, descrizione, type" .
|
||||
" FROM notifiche" .
|
||||
" where id = " . $idNotification;
|
||||
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$query = "UPDATE conferma_lettura_profilo SET conferma_lettura = 1 WHERE id_notifica = " . $idNotification .
|
||||
" AND id_profilo = '" . $keyStore . "'";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/profile/:keyStore/notifications', function ($keyStore) use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
|
||||
$query = "SELECT id, titolo, type, CreatoIl, conferma_lettura_profilo.conferma_lettura" .
|
||||
" FROM notifiche" .
|
||||
" inner join conferma_lettura_profilo on notifiche.id = conferma_lettura_profilo.id_notifica" .
|
||||
" where conferma_lettura_profilo.id_profilo = '" . $keyStore . "' and notifiche.Type = 1" .
|
||||
" UNION" .
|
||||
" (SELECT id, titolo, type, CreatoIl, conferma_lettura_profilo.conferma_lettura" .
|
||||
" FROM notifiche" .
|
||||
" inner join conferma_lettura_profilo on notifiche.id = conferma_lettura_profilo.id_notifica" .
|
||||
" where conferma_lettura_profilo.id_profilo = '" . $keyStore . "' and notifiche.Type = 2" .
|
||||
" ORDER BY CreatoIl desc" .
|
||||
" LIMIT 1" .
|
||||
" )" .
|
||||
" ORDER BY CreatoIl desc";
|
||||
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
returnJson($app, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->post('/profile', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$json_data_body = json_decode($app->request()->post('dataPair'));
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "insert into profilo(ProfiloID, Name, Email, Gender, TipoAccesso, RisultatiRicerca, TemaUI, UltimoAccesso, CreatoIl) values ('" . $json_data_body->keyStore . "', '" . $json_data_body->name . "', '" . $json_data_body->email . "', '" . $json_data_body->gender . "', '" . $json_data_body->type . "', '" . $json_data_body->risRic . "', '" . $json_data_body->tema . "', NOW(), NOW())";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
$app->put('/profile', function () use ($app) {
|
||||
$callbackFn = $app->request()->get('callback');
|
||||
$json_data_body = json_decode($app->request()->post('dataPair'));
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "update profilo set RisultatiRicerca = '" . $json_data_body->risRic . "', TemaUI = '" . $json_data_body->tema . "' where ProfiloID = '" . $json_data_body->keyStore . "'";
|
||||
|
||||
$retNewID = $mysqlconnetion->insertRecord($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
returnJson($app, $callbackFn, $retNewID);
|
||||
});
|
||||
|
||||
?>
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
// inclusione del file contenente la classe
|
||||
require_once "./include.php";
|
||||
|
||||
$app->get('/categories', function ($request, $response, $args) {
|
||||
$callbackFn = $req->getQueryParams()['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();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/typeingredients', function ($request, $response, $args) {
|
||||
$callbackFn = $req->getQueryParams()['callback'];
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$retObj = $mysqlconnetion->queryToObject("select ID as tipo_ingredienti_id, name from tipo_ingredienti order by name");
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/typeqtys', function ($request, $response, $args) {
|
||||
$callbackFn = $req->getQueryParams()['callback'];
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$retObj = $mysqlconnetion->queryToObject("select ID as tipo_quantita_id, name from tipo_quantita");
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/{catID}', function ($request, $response, $args) {
|
||||
$categoryID = $args["catID"];
|
||||
$callbackFn = $req->getQueryParams()['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');
|
||||
}
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/{categoryID}/mostvote[/{numItems}]', function ($request, $response, $args) {
|
||||
$categoryID = $args["categoryID"];
|
||||
$numItems = $args["numItems"];
|
||||
$callbackFn = $req->getQueryParams()['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');
|
||||
}
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/:categoryID/lastinserted(/:numItems)', function ($categoryID, $numItems = 10) use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['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');
|
||||
}
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/lastinserted/:profileID', function ($profileID) use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['callback'];
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
//$mysqlconnetion->connetti();
|
||||
$query = "select ID as ricetta_id, titolo, autore FROM ricette WHERE data_creazione > ( SELECT PenultimoAccesso FROM profilo " .
|
||||
"WHERE `ProfiloID` = '" . $profileID . "' ) order by Data_creazione desc, 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');
|
||||
}
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/search/:numItems/:startItem(/:categoryId(/:difficolta(/:titolo)))',
|
||||
function ($numItems = 10, $startItem = 0, $categoryId = 0, $difficolta = 0, $titolo = "") use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['callback'];
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$queryBase = " from ricette"
|
||||
. " INNER JOIN categorie ON categorie.ID = ricette.id_categoria"
|
||||
. " where 1 = 1";
|
||||
if ($categoryId > 0) {
|
||||
$queryBase = $queryBase . " AND ID_CATEGORIA = " . $categoryId;
|
||||
}
|
||||
if ($titolo != null && $titolo != "") {
|
||||
foreach (explode(" ", htmlentities(urldecode($titolo))) as $ele)
|
||||
$queryBase = $queryBase . " AND titolo like '%" . $ele . "%'";
|
||||
}
|
||||
if ($difficolta > 0) {
|
||||
$queryBase = $queryBase . " AND difficolta = " . $difficolta;
|
||||
}
|
||||
$queryBase = $queryBase . " order by titolo, autore";
|
||||
|
||||
$query = "select ricette.ID as ricetta_id, categorie.name AS categoria_name, titolo, autore, valutazione, difficolta" . $queryBase . " LIMIT " . $numItems * $startItem . " , " . $numItems;
|
||||
$retObj2 = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$query = "select COUNT(*) as TotalRecords" . $queryBase;
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
foreach ($retObj2 as $ele) {
|
||||
$ele["titolo"] = html_entity_decode($ele["titolo"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1');
|
||||
}
|
||||
|
||||
$retObj["records"] = $retObj2;
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricette/authors(/:startWith)',
|
||||
function ($startWith = "") use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['callback'];
|
||||
$mysqlconnetion = new MysqlClass;
|
||||
$query = "select distinct autore from ricette"
|
||||
. " where 1 = 1";
|
||||
|
||||
if ($startWith != null && $startWith != "") {
|
||||
$query = $query . " AND autore like '%" . $startWith . "%'";
|
||||
}
|
||||
|
||||
$query = $query . " order by autore";
|
||||
|
||||
$retObj = $mysqlconnetion->queryToObject($query);
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricetta/body/:itemID', function ($itemID) use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['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);
|
||||
|
||||
foreach ($retObj2 as $ele) {
|
||||
$ele["note"] = html_entity_decode($ele["note"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1');
|
||||
}
|
||||
|
||||
$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();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricetta/header/:itemID', function ($itemID) use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['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();
|
||||
return returnJson($response, $callbackFn, $retObj);
|
||||
});
|
||||
|
||||
$app->get('/ricetta/ingredienti/:itemID', function ($itemID) use ($app) {
|
||||
$callbackFn = $req->getQueryParams()['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);
|
||||
|
||||
foreach ($retObj2 as $ele) {
|
||||
$ele["note"] = html_entity_decode($ele["note"], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1');
|
||||
}
|
||||
|
||||
$mysqlconnetion->disconnetti();
|
||||
|
||||
return returnJson($response, $callbackFn, $retObj2);
|
||||
});
|
||||
?>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
include_once "./include.php";
|
||||
|
||||
$app->group('/api', function () {
|
||||
include "./ricette.php";
|
||||
include "./profile.php";
|
||||
include "./image.php";
|
||||
});
|
||||
|
||||
$app->group('/backend', function () {
|
||||
include "./management.php";
|
||||
include "./image_backend.php";
|
||||
});
|
||||
|
||||
$app->run();
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
if ( ! function_exists( 'exif_imagetype' ) ) {
|
||||
function exif_imagetype ( $filename ) {
|
||||
if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) {
|
||||
return $type;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function utf8json($inArray) {
|
||||
|
||||
if (is_array($inArray)) {
|
||||
static $depth = 0;
|
||||
|
||||
/* our return object */
|
||||
$newArray = array();
|
||||
|
||||
/* safety recursion limit */
|
||||
$depth ++;
|
||||
if ($depth >= '300000') {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* step through inArray */
|
||||
foreach ($inArray as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
/* recurse on array elements */
|
||||
$newArray[$key] = utf8json($val);
|
||||
} else {
|
||||
/* encode string values */
|
||||
$newArray[$key] = utf8_encode($val);
|
||||
}
|
||||
}
|
||||
/* return utf8 encoded array */
|
||||
return $newArray;
|
||||
}
|
||||
/* return utf8 encoded array */
|
||||
return $inArray;
|
||||
}
|
||||
|
||||
function returnJsonWithDecode($response, $callbackFn, $retObj) {
|
||||
$contentType = "";
|
||||
$body = "";
|
||||
if ($callbackFn) {
|
||||
$contentType = 'application/javascript; Charset=UTF-8';
|
||||
$body = $callbackFn . "(" . html_entity_decode(json_encode(utf8json($retObj)), ENT_COMPAT | ENT_HTML401, 'ISO-8859-1') . ")";
|
||||
} else {
|
||||
$contentType = 'application/x-json; Charset=UTF-8';
|
||||
$body = html_entity_decode(json_encode(utf8json($retObj)), ENT_COMPAT | ENT_HTML401, 'ISO-8859-1');
|
||||
}
|
||||
|
||||
return $response->withHeader(
|
||||
'Content-Type',
|
||||
'application/json'
|
||||
)->write($body);
|
||||
}
|
||||
|
||||
function returnJson($response, $callbackFn, $retObj) {
|
||||
$contentType = "";
|
||||
$body = "";
|
||||
if ($callbackFn) {
|
||||
$contentType = 'application/javascript; Charset=UTF-8';
|
||||
$body = $callbackFn . "(" . (json_encode(utf8json($retObj))) . ")";
|
||||
} else {
|
||||
$contentType = 'application/x-json; Charset=UTF-8';
|
||||
$body = (json_encode(utf8json($retObj)));
|
||||
}
|
||||
|
||||
return $response->withHeader(
|
||||
'Content-Type',
|
||||
'application/json'
|
||||
)->write($body);
|
||||
}
|
||||
|
||||
function makeThumbnail($im) {
|
||||
$final_width_of_image = 300;
|
||||
$ox = imagesx($im);
|
||||
$oy = imagesy($im);
|
||||
|
||||
$nx = $final_width_of_image;
|
||||
$ny = floor($oy * ($final_width_of_image / $ox));
|
||||
|
||||
$nm = imagecreatetruecolor($nx, $ny);
|
||||
|
||||
imagecopyresized($nm, $im, 0, 0, 0, 0, $nx, $ny, $ox, $oy);
|
||||
|
||||
return $nm;
|
||||
}
|
||||
|
||||
function getContentFromResources($res) {
|
||||
ob_start(); //Start output buffer.
|
||||
imagejpeg($res); //This will normally output the image, but because of ob_start(), it won't.
|
||||
$contents = ob_get_contents(); //Instead, output above is saved to $contents
|
||||
ob_end_clean(); //End the output buffer.
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
function resizeImage($dropBoxObj, $layer, $size, $dir, $fileName, $dirDropBox)
|
||||
{
|
||||
$fullPath = $dir . "/" . $fileName;
|
||||
$layer->resizeByLargestSideInPixel($size, true);
|
||||
$layer->save($dir, $fileName);
|
||||
|
||||
try {
|
||||
$dropBoxObj->CreateFolder($dirDropBox);
|
||||
} catch (DropboxException $ex) {
|
||||
}
|
||||
|
||||
$dropBoxObj->UploadFile($fullPath, $dirDropBox . "/" . $fileName);
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user