filestack/FilestackClient.php
<?php
namespace Filestack;
use GuzzleHttp\Client;
use Filestack\FilestackConfig;
use Filestack\UploadProcessor;
/**
* Filestack client object. This is the main object to
* make functional calls to the Filestack API.
*/
class FilestackClient
{
use Mixins\CommonMixin;
use Mixins\TransformationMixin;
public $api_key;
public $security;
private $upload_processor;
/**
* FilestackClient constructor
*
* @param string $api_key your Filestack API Key
* @param FilestackSecurity $security Filestack security object if
* security settings is turned on
* @param GuzzleHttp\Client $http_client DI http client, will instantiate
* one if not passed in
* @param UploadProcessor $upload_processor DI upload_processor object
* @param string $cname Domain to use for all URLs.
* __Requires the custom CNAME
* addon__. If this is enabled then
* you must also set up your own
* OAuth applications for each
* cloud source you wish to use in
* the picker.
*/
public function __construct($api_key, $security = null, $http_client = null,
$upload_processor = null, $cname = null)
{
$this->api_key = $api_key;
$this->security = $security;
if (is_null($http_client)) {
$http_client = new Client();
}
$this->http_client = $http_client; // CommonMixin
if (is_null($upload_processor)) {
$upload_processor = new UploadProcessor($api_key, $security, $http_client);
}
$this->upload_processor = $upload_processor;
$this->cname = $cname;
}
/**
* Catchall function, throws Filestack Exception if method is not valid
*
* @throws FilestackException method not found in allowed lists
*/
public function __call($method, $args)
{
throw new FilestackException("$method() is not a valid method.", 400);
return $this;
}
/**
* Get the cdn url of a filestack file
*
*/
public function getCdnUrl($handle)
{
$url = sprintf('%s/%s', $this->getCustomUrl(FilestackConfig::CDN_URL), $handle);
return $url;
}
/**
* Get the content of file
*
* @param string $url Filestack file url or handle
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return string (file content)
*/
public function getContent($url)
{
if (!$this->isUrl($url)) { // CommonMixin
$url = $this->getCdnUrl($url);
}
// call CommonMixin function
$result = $this->sendGetContent($url, $this->security);
return $result;
}
/**
* Get metadata of a file
*
* @param string $url Filestack file url or handle
* @param array $fields optional, specific fields to retrieve.
* possible fields are:
* mimetype, filename, size, width, height,
* location, path, container, exif,
* uploaded (timestamp), writable,
* cloud, source_url
*
* @throws FilestackException if API call fails
*
* @return array
*/
public function getMetaData($url, $fields = [])
{
if (!$this->isUrl($url)) { // CommonMixin
$url = $this->getCdnUrl($url);
}
// call CommonMixin function
$result = $this->sendGetMetaData($url, $fields, $this->security);
return $result;
}
/**
* Get sfw (safe for work) flag of a filelink
*
* @param string $handle Filestack filelink handle
*
* @throws FilestackException if API call fails
*
* @return json
*/
public function getSafeForWork($handle)
{
// call CommonMixin function
$result = $this->sendGetSafeForWork($handle, $this->security);
return $result;
}
/**
* Get tags of a filelink
*
* @param string $handle Filestack filelink handle
*
* @throws FilestackException if API call fails
*
* @return json
*/
public function getTags($handle)
{
// call CommonMixin function
$result = $this->sendGetTags($handle, $this->security);
return $result;
}
/**
* Set this Filelink's transform_url to include the collage task
*
* @param array $sources An array of Filestack file handles or external
* urls. These are the images that will comprise
* the other images in the collage. The order in
* which they appear in the array dictates how the
* images will be arranged.
* @param int $width width of result image (1 to 10000)
* @param int $height height of result image (1 to 10000)
* @param string $color Border color for the collage. This can be a
* word or hex value, e.g. ('red' or 'FF0000')
* @param string $fit auto or crop. Allows you to control how the
* images in the collage are manipulated so that
* the final collage image will match the height
* and width parameters you set more closely.
* Using crop will produce a result that is closest
* to the height and width parameters you set.
* @param int $margin Sets the size of the border between and around
* the images. Range is 1 to 100.
* @param bool $auto_rotate Setting this parameter to true automatically
* rotates all the images in the collage according
* to their exif orientation data.
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack/Filelink or contents
*/
public function collage($sources, $width, $height, $store_options = [],
$color = 'white', $fit = 'auto', $margin = 10, $auto_rotate = false)
{
// slice off first source as the filelink
$first_source = array_shift($sources);
$process_attrs = [
'f' => json_encode($sources),
'w' => $width,
'h' => $height,
'c' => $color,
'i' => $fit,
'm' => $margin,
'a' => $auto_rotate
];
$transform_tasks = [
'collage' => $process_attrs
];
if (!empty($store_options)) {
$transform_tasks['store'] = $store_options;
}
// call TransformationMixin function
$result = $this->sendTransform($first_source, $transform_tasks, $this->security);
return $result;
}
/**
* Convert url or filelink handle to another audio format. IMPORTANT: To use
* this function, you must setup webhooks to notify you when the transcoding
* has completed. See our online documentation for more details:
* https://www.filestack.com/docs/audio-transformations
*
* @param string $resource url or file handle
* @param string $format The format to which you would like to
* convert to. e.g (aac, hls, mp3, m4a, oga)
* @param array $options Array of options.
* access: public or private
* Indicates that the file should be stored in
* a way that allows public access going directly
* to the underlying file store. For instance,
* if the file is stored on S3, this will allow
* the S3 url to be used directly. This has no
* impact on the ability of users to read from
* the Filestack file URL. Defaults to 'private'.
* audio_bitrate: Sets the audio bitrate for the
* audio file that is generated by the transcoding
* process. Must be an integer between 0 and 999.
* audio_channels: Set the number of audio channels
* for the audio file that is generated by the
* transcoding process. Can be an integer between
* 1 and 12. Default is same as source audio.
* audio_sample_rate: Set the audio sample rate
* for the audio file that is generated by the
* transcoding process. Can be an integer between
* 0 and 99999. Default is 44100.
* clip_length: Set the length of the audio file
* that is generated by the transcoding process.
* Format is hours:minutes:seconds e.g. (00:00:20)
* clip_offset: Set the point to begin the audio
* clip from. For example, clip_offset:00:00:10
* will start the audio transcode 10 seconds
* into the source audio file. Format is
* hours:minutes:seconds, e.g. (00:00:10)
* container: The bucket or container in the specified
* file store where the file should end up.
* extname: Set the file extension for the audio
* file that is generated by the transcoding
* process, e.g. ('.mp4', '.webm')
* filename: Set the filename of the audio file
* that is generated by the transcoding process.
* force: (bool) set to true to restart completed
* or pending audio encoding if a transcoding
* fails, and you make the same request again
* location: The custom storage service to store
* the converted file to, options incude 'S3',
* 'azure', 'gcs', 'rackspace', and 'dropbox'
* path: The path to store the file at within the
* specified file store. For S3, this is the
* key where the file will be stored at. By
* default, Filestack stores the file at the
* root at a unique id, followed by an underscore,
* followed by the filename, for example
* "3AB239102DB_myaudio.mp3"
* title: Set the title in the file metadata.
* @param bool $force set to true to restart completed
* or pending audio encoding if a transcoding
* fails, and you make the same request again
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return string (uuid of conversion task)
*/
public function convertAudio($resource, $format, $options = [], $force = false)
{
$transform_tasks = [
'video_convert' => $options
];
// set filetype
$transform_tasks['video_convert']['p'] = $format;
// call TransformationMixin function
$result = $this->sendVideoConvert($resource, $transform_tasks,
$this->security, $force);
return $result;
}
/**
* Convert audio file from url or filelink handle to another format. To see
* which format can be converted, see:
* https://www.filestack.com/docs/image-transformations/conversion
*
* @param string $resource url or file handle
* @param string $filetype The format to which you would like to
* convert the file. e.g (doc, docx, html, jpg,
* ods, odt, pdf, png, svg, txt, webp)
* @param array $options Array of options.
* background: Set a background color when
* converting transparent .png files into other
* file types. Can be a word or hex value, e.g.
* ('white' or 'FFFFFF')
* colorspace: RGB, CMYK or Input
* By default we convert all the images to the
* RGB color model in order to be web friendly.
* However, we have added an option to preserve
* the original colorspace. This will work for * JPEGs and TIFFs.
* compress: (bool) You can take advantage of
* Filestack's image compression which utilizes
* JPEGtran and OptiPNG. The value for this parameter
* is boolean. If you want to compress your image
* then the value should be true. Compression
* is off/false by default.
* density: (int, 1 to 500). You can adjust the
* density when converting documents like PowerPoint,
* PDF, AI and EPS files to image formats like
* JPG or PNG. This can improve the resolution
* of the output image.
* docinfo: (bool) Set this to true to get information
* about a document, such as the number of pages
* and the dimensions of the file.
* page: (int, 1 to 10000) If you are converting
* a file that contains multiple pages such as
* PDF or powerpoint file, you can extract a
* specific page using the page parameter.
* pageformat: set the page size used for the layout
* of the resultant document. This parameter can
* be used when converting the format of one
* document into PDF, PNG, or JPG. Possible values:
* 'A3', 'A4', 'A5', 'B4','B5',
* 'letter', 'legal', 'tabloid'
* pageorientation: portrait or landscape
* determine the orientation of the resulting
* document. This parameter can be used when
* converting the format of one document into
* PDF, PNG, or JPG.
* quality: (int, 1 to 100, or 'input')
* You can change the quality (and reduce the
* file size) of JPEG images by using the quality
* parameter. The quality is set to 100 by default.
* A quality setting of 80 provides a nice balance
* between file size reduction and image quality.
* If the quality is instead set to "input" the
* image will not be recompressed and the input
* compression level of the jpg will be used.
* secure: (bool) This parameter applies to conversions
* of HTML and SVG sources. When the secure parameter
* is set to true, the HTML or SVG file will be
* stripped of any insecure tags (HTML sanitization).
* Default setting is false.
* strip: (bool) Set to true to remove any metadata
* embedded in an image.
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack/Filelink
*/
public function convertFile($resource, $filetype, $options = [])
{
$transform_tasks = [
'output' => $options
];
// set filetype
$transform_tasks['output']['f'] = $filetype;
// call TransformationMixin function
$result = $this->sendTransform($resource, $transform_tasks, $this->security);
return $result;
}
/**
* Convert a video file from url or filelink handle to another video format.
* IMPORTANT: To use this function, you must setup webhooks to notify you
* when the transcoding has completed. See our online docs for more details:
* https://www.filestack.com/docs/video-transformations
*
* @param string $resource url or file handle
* @param string $format The format to which you would like to
* convert to. e.g (aac, h264, h264.hi,
* hls.variant, hls.variant.audio, m4a, mp3,
* oga, ogg, ogg.hi, webm, webm.hi)
* @param array $options Array of options.
* access: public or private
* Indicates that the file should be stored in
* a way that allows public access going directly
* to the underlying file store. For instance,
* if the file is stored on S3, this will allow
* the S3 url to be used directly. This has no
* impact on the ability of users to read from
* the Filestack file URL. Defaults to 'private'.
* aspect_mode: set the aspect mode (default: letterbox)
* 'preserve` - Original size and ratio is preserved.
* 'constrain' - Aspect ratio is maintained,
* No black bars are added to the output.
* 'crop' - Fills frame size and crops the rest
* 'letterbox' - Adds black bars to defined height
* 'pad' - Adds black bars to output to match
* defined frame size
* audio_bitrate: Sets the audio bitrate for the
* audio file that is generated by the transcoding
* process. Must be an integer between 0 and 999.
* audio_channels: Set the number of audio channels
* for the audio file that is generated by the
* transcoding process. Can be an integer between
* 1 and 12. Default is same as source audio.
* audio_sample_rate: Set the audio sample rate
* for the audio file that is generated by the
* transcoding process. Can be an integer between
* 0 and 99999. Default is 44100.
* clip_length: Set the length of the video file
* that is generated by the transcoding process.
* Format is hours:minutes:seconds e.g. (00:00:20)
* clip_offset: Set the point to begin the video
* clip from. For example, clip_offset:00:00:10
* will start the audio transcode 10 seconds
* into the source audio file. Format is
* hours:minutes:seconds, e.g. (00:00:10)
* container: The bucket or container in the specified
* file store where the file should end up.
* extname: Set the file extension for the audio
* file that is generated by the transcoding
* process, e.g. ('.mp4', '.webm')
* fps: Specify the frames per second of the video
* that is generated by the transcoding process.
* Must be an integer between 1 and 300 Default
* is to copy the original fps of the source file.
* filename: Set the filename of the audio file
* that is generated by the transcoding process.
* keyframe_interval: Adds a key frame every 250
* frames to the video that is generated by the
* transcoding process. Default is 250.
* location: The custom storage service to store
* the converted file to, options incude 'S3',
* 'azure', 'gcs', 'rackspace', and 'dropbox'
* path: The path to store the file at within the
* specified file store. For S3, this is the
* key where the file will be stored at. By
* default, Filestack stores the file at the
* root at a unique id, followed by an underscore,
* followed by the filename, for example
* "3AB239102DB_myaudio.mp3"
* title: Set the title in the file metadata.
* two_pass: Specify that the transcoding process
* should do two passes to improve video quality.
* Defaults to false.
* width: Set the width in pixels of the video
* that is generated by the transcoding process.
* height: Set the height in pixels of the video
* that is generated by the transcoding process.
* upscale: Upscale the video resolution to match
* your profile. Defaults to true.
* video_bitrate: Specify the video bitrate for
* the video that is generated by the transcoding
* process. Must be an integer between 1 and 5000.
* watermark_bottom: The distance from the bottom
* of the video frame to place the watermark
* on the video. (0 to 9999)
* watermark_left: The distance from the left side
* of the video frame to place the watermark
* on the video. (0 to 9999)
* watermark_right: The distance from the left side
* of the video frame to place the watermark
* on the video. (0 to 9999)
* watermark_left: The distance from the top * of the video frame to place the watermark
* on the video. (0 to 9999)
* watermark_width: Resize the width of the watermark
* watermark_height: Resize the height of the watermark
* watermark_url: The Filestack handle or URL of
* the image file to use as a watermark on the
* transcoded video.
* @param bool $force set to true to restart completed
* or pending audio encoding if a transcoding
* fails, and you make the same request again
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return string (uuid of conversion task)
*/
public function convertVideo($resource, $format, $options = [], $force = false)
{
$transform_tasks = [
'video_convert' => $options
];
// set filetype
$transform_tasks['video_convert']['p'] = $format;
// call TransformationMixin function
$result = $this->sendVideoConvert($resource, $transform_tasks, $this->security, $force);
return $result;
}
/**
* Debug transform tasks
*
* @param string $resource url or file handle
* @param array $transform_tasks Transformation tasks to debug
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return json response
*/
public function debug($resource, $transform_tasks)
{
// call TransformationMixin functions
$tasks_str = $this->createTransformStr($transform_tasks);
$transform_url = $this->createTransformUrl(
$this->api_key,
'image',
$resource,
$tasks_str,
$this->security
);
$json_response = $this->sendDebug($transform_url, $this->api_key, $this->security);
return $json_response;
}
/**
* Delete a file from cloud storage
*
* @param string $handle Filestack file handle to delete
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return bool (true = delete success, false = failed)
*/
public function delete($handle)
{
// call CommonMixin function
$result = $this->sendDelete($handle, $this->api_key, $this->security);
return $result;
}
/**
* Download a file, saving it to specified destination
*
* @param string $url Filestack file url or handle
* @param string $destination destination filepath to save to, can
* be foldername (defaults to stored filename)
*
* @throws FilestackException if API call fails
*
* @return bool (true = download success, false = failed)
*/
public function download($url, $destination)
{
if (!$this->isUrl($url)) { // CommonMixin
$url = $this->getCdnUrl($url);
}
// call CommonMixin function
$result = $this->sendDownload($url, $destination, $this->security);
return $result;
}
/**
* Overwrite a file in cloud storage
*
* @param string $filepath real path to file
* @param string $handle Filestack file handle to overwrite
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack\Filelink
*/
public function overwrite($filepath, $handle)
{
$filelink = $this->sendOverwrite($filepath, $handle,
$this->api_key, $this->security);
return $filelink;
}
/**
* Take a screenshot of a URL
*
* @param string $url URL to screenshot
* @param string $store_options optional store values
* @param string $agent desktop or mobile
* @param string $mode all or window
* @param int $width Designate the width of the browser window. The
* width is 1024 by default, but can be set to
* anywhere between 1 to 1920.
* @param int $height Designate the height of the browser window.
* The height is 768 by default, but can be set
* to anywhere between 1 to 1080.
* @param int $delay Tell URL Screenshot to wait x milliseconds before
* capturing the webpage. Sometimes pages take
* longer to load, so you may need to delay the
* capture in order to make sure the page is
* rendered before the screenshot is taken. The
* delay must be an integer between 0 and 10000.
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack/Filelink
*/
public function screenshot($url, $store_options = [],
$agent = 'desktop', $mode = 'all', $width = 1024, $height = 768, $delay = 0)
{
$process_attrs = [
'a' => $agent,
'm' => $mode,
'w' => $width,
'h' => $height,
'd' => $delay
];
$transform_tasks = [
'urlscreenshot' => $process_attrs
];
if (!empty($store_options)) {
$transform_tasks['store'] = $store_options;
}
// call TransformationMixin function
$result = $this->sendTransform($url, $transform_tasks, $this->security);
return $result;
}
/**
* Applied array of transformation tasks to a url
*
* @param string $url url to transform
* @param array $transform_tasks array of transformation tasks and
* optional attributes per task
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack\Filelink or file content
*/
public function transform($url, $transform_tasks)
{
// call TransformationMixin
$result = $this->sendTransform($url, $transform_tasks, $this->security);
return $result;
}
/**
* Upload a file to desired cloud service, defaults to Filestack's S3
* storage.
*
* @param string $filepath path to file
* @param array $options location: specify location, possible
* values are:
* S3, gcs, azure, rackspace, dropbox
* filename: explicitly set the filename
* to store as
* mimetype: explicitly set the mimetype
* intelligent: set to true to use the
* Intelligent Ingestion flow
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack\Filelink or file content
*/
public function upload($filepath, $options = [])
{
if (!file_exists($filepath)) {
throw new FilestackException("File not found", 400);
}
$location = 's3';
if (array_key_exists('location', $options)) {
$location = $options['location'];
}
$filename = basename($filepath);
if (array_key_exists('filename', $options)) {
$filename = $options['filename'];
}
$mimetype = mime_content_type($filepath);
if (array_key_exists('mimetype', $options)) {
$mimetype = $options['mimetype'];
}
$metadata = [
'filepath' => $filepath,
'filename' => $filename,
'filesize' => filesize($filepath),
'mimetype' => $mimetype,
'location' => $location,
];
// register job
$upload_data = $this->upload_processor->registerUploadTask($this->api_key,
$metadata, $this->security);
// Intelligent Ingestion option
if (array_key_exists('intelligent', $options) &&
$this->upload_processor->intelligenceEnabled($upload_data)) {
$this->upload_processor->setIntelligent($options['intelligent']);
}
$result = $this->upload_processor->run($this->api_key,
$metadata,
$upload_data);
$filelink = $result['filelink'];
return $filelink;
}
/**
* Upload a url to desired cloud service, defaults to Filestack's S3
* storage. Set $options['location'] to specify location, possible values are:
* S3, gcs, azure, rackspace, dropbox
*
* @param string $url url of file to upload
* @param string $api_key Filestack API Key
* @param array $options extra optional params. e.g.
* location (string, storage location),
* filename (string, custom filename),
* mimetype (string, file mimetype),
* path (string, path in cloud container),
* container (string, container in bucket),
* access (string, public|private),
* base64decode (bool, true|false)
*
* @throws FilestackException if API call fails
*
* @return Filestack\Filelink
*/
public function uploadUrl($resource, $options = [])
{
// lowercase all options
$options = array_change_key_case($options, CASE_LOWER);
// set filename to original file if one does not exists
if (!array_key_exists('filename', $options)) {
$options['filename'] = basename($resource);
}
// set location to S3 if not passed in
$location = 'S3';
if (array_key_exists('location', $options)) {
$location = $options['location'];
}
// build endpoint url
$url = sprintf('%s/store/%s?key=%s',
$this->getCustomUrl(FilestackConfig::API_URL),
$location,
$this->api_key);
foreach ($options as $key => $value) {
$url .= "&$key=$value";
}
// append security if exists
if ($this->security) {
$url = $this->security->signUrl($url);
}
// send post request
$data = ['form_params' => ['url' => $resource]];
$response = $this->sendRequest('POST', $url, $data);
$filelink = $this->handleResponseCreateFilelink($response);
return $filelink;
}
/**
* Bundle an array of files into a zip file. This task takes the file or files
* that are passed in the array and compresses them into a zip file. Sources can
* be handles, urls, or a mix of both
*
* @param array $sources Filestack handles and urls to zip
* @param array $store_options Optional store options
*
* @throws FilestackException if API call fails, e.g 404 file not found
*
* @return Filestack/Filelink or file content
*/
public function zip($sources, $store_options = [])
{
$transform_tasks = [
'zip' => []
];
if (!empty($store_options)) {
$transform_tasks['store'] = $store_options;
}
$sources_str = '[' . implode(',', $sources) . ']';
// call TransformationMixin
$result = $this->sendTransform($sources_str, $transform_tasks, $this->security);
return $result;
}
}