|
|
|
<?php
|
|
|
|
// Copyright 2014-2016 RealFaviconGenerator
|
|
|
|
|
|
|
|
define( 'RFG_PACKAGE_URL', 'package_url' );
|
|
|
|
define( 'RFG_COMPRESSION', 'compression' );
|
|
|
|
define( 'RFG_HTML_CODE', 'html_code' );
|
|
|
|
define( 'RFG_FILES_URLS', 'files_url' );
|
|
|
|
define( 'RFG_FILES_IN_ROOT', 'files_in_root' );
|
|
|
|
define( 'RFG_FILES_PATH', 'files_path' );
|
|
|
|
define( 'RFG_PREVIEW_PICTURE_URL', 'preview_picture_url' );
|
|
|
|
define( 'RFG_CUSTOM_PARAMETER', 'custom_parameter' );
|
|
|
|
define( 'RFG_VERSION', 'version' );
|
|
|
|
define( 'RFG_NON_INTERACTIVE_API_REQUEST', 'non_interactive_api_request' );
|
|
|
|
|
|
|
|
define( 'RFG_FAVICON_PRODUCTION_PACKAGE_PATH', 'favicon_production_package_path' );
|
|
|
|
define( 'RFG_FAVICON_COMPRESSED_PACKAGE_PATH', 'favicon_compressed_package_path' );
|
|
|
|
define( 'RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH', 'favicon_uncompressed_package_path' );
|
|
|
|
define( 'RFG_PREVIEW_PATH', 'preview_path' );
|
|
|
|
|
|
|
|
class Favicon_By_RealFaviconGenerator_Api_Response {
|
|
|
|
|
|
|
|
private $params = array();
|
|
|
|
|
|
|
|
public function __construct( $json ) {
|
|
|
|
if ( $json == NULL ) {
|
|
|
|
throw new InvalidArgumentException( "No response from RealFaviconGenerator" );
|
|
|
|
}
|
|
|
|
|
|
|
|
$response = json_decode( $json, true );
|
|
|
|
|
|
|
|
if ( $response == NULL ) {
|
|
|
|
throw new InvalidArgumentException( "JSON could not be parsed" );
|
|
|
|
}
|
|
|
|
|
|
|
|
$response = $this->getParam( $response, 'favicon_generation_result' );
|
|
|
|
$result = $this->getParam( $response, 'result' );
|
|
|
|
$status = $this->getParam( $result, 'status' );
|
|
|
|
|
|
|
|
if ( $status != 'success' ) {
|
|
|
|
$msg = $this->getParam( $result, 'error_message', false );
|
|
|
|
$msg = $msg != NULL ? $msg : 'An error occured';
|
|
|
|
throw new InvalidArgumentException( $msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
$favicon = $this->getParam( $response, 'favicon' );
|
|
|
|
$this->params[RFG_PACKAGE_URL] = $this->getParam( $favicon, 'package_url' );
|
|
|
|
$this->params[RFG_COMPRESSION] = $this->getParam( $favicon, 'compression' ) == 'true';
|
|
|
|
$this->params[RFG_HTML_CODE] = $this->getParam( $favicon, 'html_code' );
|
|
|
|
$this->params[RFG_FILES_URLS] = $this->getParam( $favicon, 'files_urls' );
|
|
|
|
|
|
|
|
$filesLoc = $this->getParam( $response, 'files_location' );
|
|
|
|
$this->params[RFG_FILES_IN_ROOT] = $this->getParam( $filesLoc, 'type' ) == 'root';
|
|
|
|
$this->params[RFG_FILES_PATH] = $this->params[RFG_FILES_IN_ROOT] ? '/' : $this->getParam( $filesLoc, 'path' );
|
|
|
|
|
|
|
|
$this->params[RFG_PREVIEW_PICTURE_URL] = $this->getParam( $response, 'preview_picture_url', false );
|
|
|
|
|
|
|
|
$this->params[RFG_CUSTOM_PARAMETER] = $this->getParam( $response, 'custom_parameter', false );
|
|
|
|
$this->params[RFG_VERSION] = $this->getParam($response, 'version', false );
|
|
|
|
|
|
|
|
$this->params[RFG_NON_INTERACTIVE_API_REQUEST] = $this->getParam($response, 'non_interactive_request', false );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For example: <code>"http://realfavicongenerator.net/files/1234f5d2s34f3ds2/package.zip"</code>
|
|
|
|
*/
|
|
|
|
public function getPackageUrl() {
|
|
|
|
return $this->params[RFG_PACKAGE_URL];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For example: <code>array( "http://realfavicongenerator.net/files/1234f5d2s34f3ds2/apple-touch-icon.png", ... )</code>
|
|
|
|
*/
|
|
|
|
public function getFilesURLs() {
|
|
|
|
return $this->params[RFG_FILES_URLS];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For example: <code>"<link ..."</code>
|
|
|
|
*/
|
|
|
|
public function getHtmlCode() {
|
|
|
|
return $this->params[RFG_HTML_CODE];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* <code>true</code> if the user chose to compress the pictures, <code>false</code> otherwise.
|
|
|
|
*/
|
|
|
|
public function isCompressed() {
|
|
|
|
return $this->params[RFG_COMPRESSION];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* <code>true</code> if the favicon files are to be stored in the root directory of the target web site, <code>false</code> otherwise.
|
|
|
|
*/
|
|
|
|
public function isFilesInRoot() {
|
|
|
|
return $this->params[RFG_FILES_IN_ROOT];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicate where the favicon files should be stored in the target web site. For example: <code>"/"</code>, <code>"/path/to/icons"</code>.
|
|
|
|
*/
|
|
|
|
public function getFilesLocation() {
|
|
|
|
return $this->params[RFG_FILES_PATH];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For example: <code>"http://realfavicongenerator.net/files/1234f5d2s34f3ds2/preview.png"</code>
|
|
|
|
*/
|
|
|
|
public function getPreviewUrl() {
|
|
|
|
return $this->params[RFG_PREVIEW_PICTURE_URL];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the customer parameter, as it was transmitted during the invocation of the API.
|
|
|
|
*/
|
|
|
|
public function getCustomParameter() {
|
|
|
|
return $this->params[RFG_CUSTOM_PARAMETER];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return version of RealFaviconGenerator used to generate the favicon. Save this value to later check for updates.
|
|
|
|
*/
|
|
|
|
public function getVersion() {
|
|
|
|
return $this->params[RFG_VERSION];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the non-interactive API request that matches the current interactive request.
|
|
|
|
*/
|
|
|
|
public function getNonInteractiveAPIRequest() {
|
|
|
|
return $this->params[RFG_NON_INTERACTIVE_API_REQUEST];
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getParam( $params, $paramName, $throwIfNotFound = true ) {
|
|
|
|
if ( isset( $params[$paramName] ) ) {
|
|
|
|
return $params[$paramName];
|
|
|
|
}
|
|
|
|
else if ( $throwIfNotFound ) {
|
|
|
|
throw new InvalidArgumentException( "Cannot find parameter " . $paramName );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Download and extract the files referenced by the response sent back by RealFaviconGenerator.
|
|
|
|
*
|
|
|
|
* Warning: as this method does HTTP accesses, calling it can take a few seconds. Better invoke it
|
|
|
|
* in an Ajax call, to not slow down the user experience.
|
|
|
|
*/
|
|
|
|
public function downloadAndUnpack( $outputDirectory = NULL ) {
|
|
|
|
global $wp_filesystem;
|
|
|
|
if ( $outputDirectory == NULL ) {
|
|
|
|
$outputDirectory = get_temp_dir();
|
|
|
|
}
|
|
|
|
|
|
|
|
$outputDirectory = $this->append_directory_separator( $outputDirectory );
|
|
|
|
|
|
|
|
if ( $this->getPackageUrl() != NULL ) {
|
|
|
|
$extractedPath = $outputDirectory . 'favicon_package';
|
|
|
|
if ( ! file_exists( $extractedPath ) ) {
|
|
|
|
if ( mkdir( $extractedPath, 0755, true ) !== true ) {
|
|
|
|
throw new InvalidArgumentException(
|
|
|
|
sprintf( __( 'Cannot create directory %s to store the favicon package content', FBRFG_PLUGIN_SLUG), $extractedPath ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->downloadZipFile( $outputDirectory, $extractedPath, $this->getPackageUrl() );
|
|
|
|
}
|
|
|
|
catch(Exception $e) {
|
|
|
|
// Zip file download failed, try getting files directly
|
|
|
|
$this->downloadFilesDirectly( $extractedPath, array() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $this->getPreviewUrl() != NULL ) {
|
|
|
|
$previewPath = $outputDirectory . 'favicon_preview.png';
|
|
|
|
$this->downloadFile( $previewPath, $this->getPreviewUrl() );
|
|
|
|
$this->params[RFG_PREVIEW_PATH] = $previewPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function downloadFilesDirectly( $outputDirectory, $filesURLs ) {
|
|
|
|
foreach($this->getFilesURLs() as $fileURL ) {
|
|
|
|
$parts = parse_url( $fileURL );
|
|
|
|
$filePath = $outputDirectory . DIRECTORY_SEPARATOR .
|
|
|
|
basename( $parts['path'] );
|
|
|
|
$this->downloadFile( $filePath, $fileURL );
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->params[RFG_FAVICON_PRODUCTION_PACKAGE_PATH] = $outputDirectory;
|
|
|
|
if ( $this->isCompressed() ) {
|
|
|
|
$this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH] = $extractedPath;
|
|
|
|
$this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH] = NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH] = NULL;
|
|
|
|
$this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH] = $extractedPath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function downloadZipFile( $packageDirectory, $extractedPath, $packageUrl ) {
|
|
|
|
$packagePath = $packageDirectory . 'favicon_package.zip';
|
|
|
|
$this->downloadFile( $packagePath, $packageUrl );
|
|
|
|
|
|
|
|
$ret = WP_Filesystem();
|
|
|
|
$result = unzip_file( $packagePath, $extractedPath );
|
|
|
|
if ( $result !== true ) {
|
|
|
|
$explanation = ( is_wp_error( $result ) )
|
|
|
|
? $result->get_error_message()
|
|
|
|
: __( 'Unknown reason', Favicon_By_RealFaviconGenerator_Common::PLUGIN_SLUG );
|
|
|
|
if ( get_class($wp_filesystem) != 'WP_Filesystem_Direct' ) {
|
|
|
|
$explanation .= ' ' . __( "Apparently WordPress has no direct access to the file system (it uses another mean such as FTP). " .
|
|
|
|
"This may be the root cause of this issue.", Favicon_By_RealFaviconGenerator_Common::PLUGIN_SLUG );
|
|
|
|
}
|
|
|
|
throw new InvalidArgumentException(
|
|
|
|
sprintf( __( 'Error while unziping the favicon package %s to directory %s', Favicon_By_RealFaviconGenerator_Common::PLUGIN_SLUG ),
|
|
|
|
$packagePath, $extractedPath ) . ': ' . $explanation );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $this->isCompressed() ) {
|
|
|
|
// As of today, when the user chooses the compress the picture,
|
|
|
|
// the package is provided in two flavors, in two distinct directories.
|
|
|
|
// Later, only the compressed version will be provided. Thus, the following code
|
|
|
|
// handles both scenarios.
|
|
|
|
if ( is_dir( $extractedPath . DIRECTORY_SEPARATOR . 'compressed' ) ) {
|
|
|
|
$this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH] = $extractedPath .
|
|
|
|
DIRECTORY_SEPARATOR . 'compressed';
|
|
|
|
} else {
|
|
|
|
$this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH] = $extractedPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( is_dir( $extractedPath . DIRECTORY_SEPARATOR . 'uncompressed' ) ) {
|
|
|
|
$this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH] = $extractedPath .
|
|
|
|
DIRECTORY_SEPARATOR . 'uncompressed';
|
|
|
|
} else {
|
|
|
|
$this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH] = $extractedPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->params[RFG_FAVICON_PRODUCTION_PACKAGE_PATH] = $this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH] = NULL;
|
|
|
|
$this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH] = $extractedPath;
|
|
|
|
$this->params[RFG_FAVICON_PRODUCTION_PACKAGE_PATH] = $this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Directory where the compressed files are stored. Method <code>downloadAndUnpack</code> must be called first in order to populate this field.
|
|
|
|
* Can be <code>NULL</code>.
|
|
|
|
*/
|
|
|
|
public function getCompressedPackagePath() {
|
|
|
|
return $this->params[RFG_FAVICON_COMPRESSED_PACKAGE_PATH];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Directory where the uncompressed files are stored. Method <code>downloadAndUnpack</code> must be called first in order to populate this field.
|
|
|
|
* Can be <code>NULL</code>.
|
|
|
|
*/
|
|
|
|
public function getUncompressedPackagePath() {
|
|
|
|
return $this->params[RFG_FAVICON_UNCOMPRESSED_PACKAGE_PATH];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Directory where the production favicon files are stored.
|
|
|
|
* These are the files to deployed to the targeted web site. When the user asked for compression,
|
|
|
|
* this is the path to the compressed folder. Else, this is the path to the regular files folder.
|
|
|
|
* Method <code>downloadAndUnpack</code> must be called first in order to populate this field.
|
|
|
|
*/
|
|
|
|
public function getProductionPackagePath() {
|
|
|
|
return $this->params[RFG_FAVICON_PRODUCTION_PACKAGE_PATH];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Path to the preview picture.
|
|
|
|
*/
|
|
|
|
public function getPreviewPath() {
|
|
|
|
return $this->params[RFG_PREVIEW_PATH];
|
|
|
|
}
|
|
|
|
|
|
|
|
private function downloadFile( $localPath, $url ) {
|
|
|
|
$resp = wp_remote_get( $url, array( 'filename' => $localPath, 'stream' => true ) );
|
|
|
|
if ( ( $resp == NULL ) || ( $resp == false ) || ( is_wp_error( $resp ) ) || ( $resp['response'] == NULL ) ||
|
|
|
|
( $resp['response']['code'] == NULL ) || ( $resp['response']['code'] != 200 ) ) {
|
|
|
|
$explanation = is_wp_error( $resp ) ? ( ': ' . $resp->get_error_message() ) : '' ;
|
|
|
|
throw new InvalidArgumentException(
|
|
|
|
sprintf( __( 'Cannot download file at %s', Favicon_By_RealFaviconGenerator_Common::PLUGIN_SLUG ), $url ) . $explanation );
|
|
|
|
}
|
|
|
|
if ( ( ! file_exists( $localPath ) ) || ( filesize( $localPath ) <= 0 ) ) {
|
|
|
|
throw new InvalidArgumentException( __( 'Cannot store downloaded file locally', Favicon_By_RealFaviconGenerator_Common::PLUGIN_SLUG ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function append_directory_separator( $filename ) {
|
|
|
|
return $filename .
|
|
|
|
( ( $this->ends_with( $filename, DIRECTORY_SEPARATOR ))
|
|
|
|
? ''
|
|
|
|
: DIRECTORY_SEPARATOR );
|
|
|
|
}
|
|
|
|
|
|
|
|
// See http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php#answer-10473026
|
|
|
|
public function ends_with( $haystack, $needle ) {
|
|
|
|
return $needle === "" ||
|
|
|
|
( ( $temp = strlen( $haystack ) - strlen( $needle ) ) >= 0
|
|
|
|
&& strpos( $haystack, $needle, $temp ) !== false );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|