diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb887de --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/bin/ +/vendor/ +/composer.lock +/composer.phar +/example/output.pdf + +/.idea/ \ No newline at end of file diff --git a/ConvertAPI.php b/ConvertAPI.php deleted file mode 100644 index c903214..0000000 --- a/ConvertAPI.php +++ /dev/null @@ -1,212 +0,0 @@ -. -# - -namespace ConvertAPI; - - /** - * Abstract class for interacting with the convertapi.com APIs. Should be - * extended in order to support each of the available convertapi.com conversion - * methods. - * - * @see http://convertapi.com/ - */ -abstract class ConvertAPI { - - /** - * API key to use when making requests to convertapi.com APIs. - */ - public $apiKey = null; - - /** - * Additional parameters to send to convertapi.com when carrying out a Word to - * PDF conversion. - */ - protected $_additionalParameters = array(); - - /** - * An array of valid input file formats, or a string representing a URL. Will - * be checked before conversion and therefore must be populated by concrete - * classes. - */ - protected $_validInputFormats = array(); - - /* Magic methods. */ - - /** - * Constructor. Optionally sets the API key to use for calls to convertapi.com. - * - * @param string $apiKey Optional convertapi.com API key to use. - */ - public function __construct($apiKey = null) { - - if (!isset($this->_apiUrl)) { - throw new \Exception('Child classes of ConvertAPI must specify a value for $this->_apiUrl.'); - } - - if ($apiKey != null) { - $this->apiKey = $apiKey; - } - - } - - /* Public methods. */ - /** - * Concrete classes must provide a convert method: a method which sends the - * request to convertapi.com and deals with the response. - * - * @param string $inputFilename Full path of file to convert. - * @param string $outputFilename Full path of file to write with converted document. - */ - public function convert($inputFilename, $outputFilename = null) { - - // Check input file (if it's an array of local file extensions)... - $urlInput = false; - if (is_array($this->_validInputFormats)) { - $inputFilenameChunks = explode('.', $inputFilename); - if (in_array(array_pop($inputFilenameChunks), $this->_validInputFormats)) { - if (!is_readable($inputFilename)) { - throw new \Exception('Input file is not readable.'); - } - } else { - throw new \Exception('Invalid input file type.'); - } - } else if ($this->_validInputFormats == 'url') { - if (preg_match('/^https?:\/\//', $inputFilename)) { - $urlInput = true; - } else { - throw new \Exception('Invalid input URL.'); - } - } else { - throw new \Exception('Invalid input format identifier.'); - } - - // Check output file... - if ($outputFilename !== null) { - if (!((file_exists($outputFilename) && is_writable($outputFilename)) || is_writable(dirname($outputFilename)))) { - throw new \Exception('Output file target is not writable.'); - } - } - - // Do conversion... - try { - $convertResponse = $this->_apiRequest($inputFilename, $urlInput); - if ($outputFilename !== null) { - if (file_put_contents($outputFilename, $convertResponse['document'])) { - unset($convertResponse['document']); - return $convertResponse; - } else { - throw new \Exception('Error writing output file.'); - } - } else { - return $convertResponse['document']; - } - } catch (\Exception $e) { - throw $e; - } - - } - - /* Protected methods. */ - - /** - * Send a request to the API. - * - * @param string $filename Full path of file to convert. - * @return array Array containing request details and binary data. See above. - */ - protected function _apiRequest($filename, $urlInput = false) { - - - if (function_exists('curl_init')) { - - // Set the source filename or URL... - if ($urlInput == true) { - $postFields = array('CUrl' => $filename); - } else { - if (is_readable($filename)) { - $postFields = array('File' => '@'.$filename); - } else { - throw new \Exception('File does not exist or is not readable.'); - } - } - - // Build the rest of the post fields array... - if ($this->apiKey !== null) { - $postFields['ApiKey'] = $this->apiKey; - } - if (isset($this->_additionalParameters) && is_array($this->_additionalParameters)) { - foreach ($this->_additionalParameters AS $key => $value) { - if ($value !== null) { - $postFields[$key] = $value; - } - } - } - - // Carry out the cURL request... - $curlHandle = curl_init(); - curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curlHandle, CURLOPT_POST, true); - curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $postFields); - curl_setopt($curlHandle, CURLOPT_URL, $this->_apiUrl); - curl_setopt($curlHandle, CURLOPT_HEADER, true); - $curlReturn = curl_exec($curlHandle); - - // Split the response into headers and body (usually document)... - $curlReturnArray = explode("\r\n\r\n", $curlReturn); - - // Check headers and return the document... - $headers = explode("\r\n", $curlReturnArray[1]); - if ($headers[0] == 'HTTP/1.1 200 OK') { - $returnArray = array('document' => $curlReturnArray[2]); - foreach ($headers AS $headerLine) { - $headerParts = explode(': ', $headerLine); - switch ($headerParts[0]) { - case 'InputFormat': $returnArray['input'] = $headerParts[1]; break; - case 'OutputFormat': $returnArray['output'] = $headerParts[1]; break; - case 'CreditsCost': $returnArray['cost'] = $headerParts[1]; break; - case 'FileSize': $returnArray['size'] = $headerParts[1]; break; - } - } - return $returnArray; - } else { - throw new \Exception('Error converting document: '.trim(array_shift(explode("\n", $curlReturnArray[1])))); - } - - } else { - throw new \Exception('Unable to init cURL. Check PHP is compiled with cURL support.'); - } - - } - - /* Abstract methods. */ - - /** - * Magic setter method. Concrete classes must define this to handle the - * _additionalParametersvariable. It should check and set all valid additional - * parameters for the given API. - * - * @param string $name Name of the additional parameter to set. - * @param string $value Value to set the parameter to. - */ - abstract public function __set($name, $value); - -} diff --git a/Abstract2Image.php b/ConvertAPI/Abstract2Image.php similarity index 100% rename from Abstract2Image.php rename to ConvertAPI/Abstract2Image.php diff --git a/Abstract2PDF.php b/ConvertAPI/Abstract2PDF.php similarity index 100% rename from Abstract2PDF.php rename to ConvertAPI/Abstract2PDF.php diff --git a/Abstract2PowerPoint.php b/ConvertAPI/Abstract2PowerPoint.php similarity index 100% rename from Abstract2PowerPoint.php rename to ConvertAPI/Abstract2PowerPoint.php diff --git a/ConvertAPI/ConvertAPI.php b/ConvertAPI/ConvertAPI.php new file mode 100644 index 0000000..7e1448d --- /dev/null +++ b/ConvertAPI/ConvertAPI.php @@ -0,0 +1,224 @@ +. +# + +namespace ConvertAPI; + +/** + * Abstract class for interacting with the convertapi.com APIs. Should be + * extended in order to support each of the available convertapi.com conversion + * methods. + * + * @see http://convertapi.com/ + */ +abstract class ConvertAPI { + + /** + * API key to use when making requests to convertapi.com APIs. + */ + public $apiKey = null; + + /** + * Additional parameters to send to convertapi.com when carrying out a Word to + * PDF conversion. + */ + protected $_additionalParameters = array(); + + /** + * An array of valid input file formats, or a string representing a URL. Will + * be checked before conversion and therefore must be populated by concrete + * classes. + */ + protected $_validInputFormats = array(); + + /* Magic methods. */ + + /** + * Constructor. Optionally sets the API key to use for calls to convertapi.com. + * + * @param string $apiKey Optional convertapi.com API key to use. + * @throws \Exception + */ + public function __construct($apiKey = null) { + + if (!isset($this->_apiUrl)) { + throw new \Exception('Child classes of ConvertAPI must specify a value for $this->_apiUrl.'); + } + + if (!isset($this->_https)) { + throw new \Exception('Child classes of ConvertAPI must specify a value for $this->_https.'); + } + + $schema = $this->_https ? 'https:' : 'http:'; + $this->_apiUrl = $schema . $this->_apiUrl; + + if ($apiKey != null) { + $this->apiKey = $apiKey; + } + + } + + /* Public methods. */ + /** + * Concrete classes must provide a convert method: a method which sends the + * request to convertapi.com and deals with the response. + * + * @param string $inputFilename Full path of file to convert. + * @param string $outputFilename Full path of file to write with converted document. + * @param array $postFields Basic post options for api request. + * @return Array|bool Returns curl info if $outputFilename = null or true + * @throws \Exception + */ + public function convert($inputFilename, $outputFilename = null, $postFields = array()) { + // Check input file (if it's an array of local file extensions)... + $urlInput = false; + if (is_array($this->_validInputFormats)) { + $inputFilenameChunks = explode('.', $inputFilename); + if (in_array(array_pop($inputFilenameChunks), $this->_validInputFormats)) { + if (!is_readable($inputFilename)) { + throw new \Exception('Input file is not readable.'); + } + } else { + throw new \Exception('Invalid input file type.'); + } + } else if ($this->_validInputFormats == 'url') { + if (preg_match('/^https?:\/\//', $inputFilename)) { + $urlInput = true; + } else { + throw new \Exception('Invalid input URL.'); + } + } else { + throw new \Exception('Invalid input format identifier.'); + } + + // Do conversion... + try { + $convertResponse = $this->_apiRequest($inputFilename, $outputFilename, $urlInput, $postFields); + return $convertResponse; + } catch (\Exception $e) { + throw $e; + } + + } + + /* Protected methods. */ + + /** + * Send a request to the API. + * + * @param string $inputFile Full path of file to convert. + * @param string|bool $outputFile + * @param string|bool $urlInput + * @param array $postFields Basic post options for api request. + * @return array|string Array containing request details and binary data or path to file. See above. + * @throws \Exception + */ + protected function _apiRequest($inputFile, $outputFile = false , $urlInput = false, $postFields = array()) { + if (function_exists('curl_init')) { + // Set the source filename or URL... + if ($urlInput == true) { + $postFields['CUrl'] = $inputFile; + } else { + if (is_readable($inputFile)) { + $postFields['File'] = new \CurlFile($inputFile); + } else { + throw new \Exception('File does not exist or is not readable.'); + } + } + + // Build the rest of the post fields array... + if ($this->apiKey !== null) { + $postFields['ApiKey'] = $this->apiKey; + } + if (isset($this->_additionalParameters) && is_array($this->_additionalParameters)) { + foreach ($this->_additionalParameters AS $key => $value) { + if ($value !== null) { + $postFields[$key] = $value; + } + } + } + + // Carry out the cURL request... + $curlHandle = curl_init(); + curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curlHandle, CURLOPT_POST, true); + curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $postFields); + curl_setopt($curlHandle, CURLOPT_URL, $this->_apiUrl); + + if ($outputFile) { + // Check output file... + + if (!((file_exists($outputFile) && is_writable($outputFile)) || is_writable(dirname($outputFile)))) { + throw new \Exception('Output file target is not writable.'); + } + + $outFile = fopen($outputFile, 'w'); + curl_setopt($curlHandle, CURLOPT_FILE, $outFile); + curl_setopt($curlHandle, CURLOPT_HEADER, false); + } else { + curl_setopt($curlHandle, CURLOPT_HEADER, true); + } + $curlReturn = curl_exec($curlHandle); + + if ($outputFile) { + return $curlReturn; + } + + // Split the response into headers and body (usually document)... + $curlReturnArray = explode("\r\n\r\n", $curlReturn); + + // Check headers and return the document... + $headers = explode("\r\n", $curlReturnArray[1]); + if ($headers[0] == 'HTTP/1.1 200 OK') { + $returnArray = array('document' => $curlReturnArray[2]); + foreach ($headers AS $headerLine) { + $headerParts = explode(': ', $headerLine); + switch ($headerParts[0]) { + case 'InputFormat': $returnArray['input'] = $headerParts[1]; break; + case 'OutputFormat': $returnArray['output'] = $headerParts[1]; break; + case 'CreditsCost': $returnArray['cost'] = $headerParts[1]; break; + case 'FileSize': $returnArray['size'] = $headerParts[1]; break; + } + } + return $returnArray; + } else { + throw new \Exception('Error converting document: '.trim(array_shift(explode("\n", $curlReturnArray[1])))); + } + + } else { + throw new \Exception('Unable to init cURL. Check PHP is compiled with cURL support.'); + } + + } + + /* Abstract methods. */ + + /** + * Magic setter method. Concrete classes must define this to handle the + * _additionalParametersvariable. It should check and set all valid additional + * parameters for the given API. + * + * @param string $name Name of the additional parameter to set. + * @param string $value Value to set the parameter to. + */ + abstract public function __set($name, $value); + +} \ No newline at end of file diff --git a/Email2PDF.php b/ConvertAPI/Email2PDF.php similarity index 86% rename from Email2PDF.php rename to ConvertAPI/Email2PDF.php index d622cdd..e7b943c 100644 --- a/Email2PDF.php +++ b/ConvertAPI/Email2PDF.php @@ -12,10 +12,12 @@ */ class Email2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Email2Pdf'; + protected $_apiUrl = '//do.convertapi.com/Email2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/Excel2PDF.php b/ConvertAPI/Excel2PDF.php similarity index 86% rename from Excel2PDF.php rename to ConvertAPI/Excel2PDF.php index bca7c4a..11e3564 100644 --- a/Excel2PDF.php +++ b/ConvertAPI/Excel2PDF.php @@ -12,10 +12,12 @@ */ class Excel2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Excel2Pdf'; + protected $_apiUrl = '//do.convertapi.com/Excel2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/Jnt2PDF.php b/ConvertAPI/Jnt2PDF.php similarity index 85% rename from Jnt2PDF.php rename to ConvertAPI/Jnt2PDF.php index 672e526..2695972 100644 --- a/Jnt2PDF.php +++ b/ConvertAPI/Jnt2PDF.php @@ -12,10 +12,12 @@ */ class Jnt2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Jnt2Pdf'; + protected $_apiUrl = '//do.convertapi.com/Jnt2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/Lotus2PDF.php b/ConvertAPI/Lotus2PDF.php similarity index 87% rename from Lotus2PDF.php rename to ConvertAPI/Lotus2PDF.php index 85aa590..2f274a1 100644 --- a/Lotus2PDF.php +++ b/ConvertAPI/Lotus2PDF.php @@ -12,10 +12,12 @@ */ class Email2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Lotus2Pdf'; + protected $_apiUrl = '//do.convertapi.com/Lotus2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/OpenOffice2PDF.php b/ConvertAPI/OpenOffice2PDF.php similarity index 91% rename from OpenOffice2PDF.php rename to ConvertAPI/OpenOffice2PDF.php index 370abe9..71d155f 100644 --- a/OpenOffice2PDF.php +++ b/ConvertAPI/OpenOffice2PDF.php @@ -12,10 +12,12 @@ */ class OpenOffice2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/OpenOffice2Pdf'; + protected $_apiUrl = '//do.convertapi.com/OpenOffice2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/Pdf2Image.php b/ConvertAPI/Pdf2Image.php similarity index 84% rename from Pdf2Image.php rename to ConvertAPI/Pdf2Image.php index c6e5852..96b02b1 100644 --- a/Pdf2Image.php +++ b/ConvertAPI/Pdf2Image.php @@ -12,10 +12,12 @@ */ class Pdf2Image extends Abstract2Image { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Pdf2Image'; + protected $_apiUrl = '//do.convertapi.com/Pdf2Image'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/Pdf2PowerPoint.php b/ConvertAPI/Pdf2PowerPoint.php similarity index 85% rename from Pdf2PowerPoint.php rename to ConvertAPI/Pdf2PowerPoint.php index 9f19145..3099d3f 100644 --- a/Pdf2PowerPoint.php +++ b/ConvertAPI/Pdf2PowerPoint.php @@ -12,10 +12,12 @@ */ class Pdf2PowerPoint extends Abstract2PowerPoint { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/Pdf2PowerPoint'; + protected $_apiUrl = '//do.convertapi.com/Pdf2PowerPoint'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/PostScript2PDF.php b/ConvertAPI/PostScript2PDF.php similarity index 84% rename from PostScript2PDF.php rename to ConvertAPI/PostScript2PDF.php index f318f16..a571623 100644 --- a/PostScript2PDF.php +++ b/ConvertAPI/PostScript2PDF.php @@ -12,10 +12,12 @@ */ class PostScript2Pdf extends Abstract2Pdf { + protected $_https = true; + /** * URL of the appropriate convertapi.com API. */ - protected $_apiUrl = 'http://do.convertapi.com/PostScript2Pdf'; + protected $_apiUrl = '//do.convertapi.com/PostScript2Pdf'; /** * An array of valid input file formats for this conversion. Overrides the diff --git a/ConvertAPI/PowerPoint2Image.php b/ConvertAPI/PowerPoint2Image.php new file mode 100644 index 0000000..3f0d25e --- /dev/null +++ b/ConvertAPI/PowerPoint2Image.php @@ -0,0 +1,29 @@ += 5.4", + "lib-curl": "*" + }, + "autoload": { + "psr-0": { "ConvertAPI\\": "." } + } +} diff --git a/example/example.php b/example/example.php index c82c014..9f59b2a 100644 --- a/example/example.php +++ b/example/example.php @@ -1,12 +1,12 @@ convert(__DIR__.'/input.txt', __DIR__.'/output.pdf'); } catch (Exception $e) { var_dump($e->getMessage());