-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #84 from short-pixel-optimizer/updates
- Loading branch information
Showing
39 changed files
with
3,658 additions
and
791 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<?php | ||
require_once (dirname(__FILE__) . "/PackageLoader.php"); | ||
require_once (__DIR__ . "/PackageLoader.php"); | ||
$loader = new EnableMediaReplace\Build\PackageLoader(); | ||
$loader->load(__DIR__); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src"}}} | ||
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\FileSystem":"filesystem\/src"}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "shortpixel/filesystem", | ||
"description": "ShortPixel FileSystem", | ||
"version": 1.0, | ||
"type": "library", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Bas", | ||
"email": "[email protected]" | ||
} | ||
], | ||
"minimum-stability": "dev", | ||
"require": {}, | ||
"autoload": { | ||
"psr-4": { "ShortPixel\\FileSystem\\" : "src" } | ||
} | ||
} |
311 changes: 311 additions & 0 deletions
311
build/shortpixel/filesystem/src/Controller/FileSystemController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,311 @@ | ||
<?php | ||
namespace EnableMediaReplace\FileSystem\Controller; | ||
use EnableMediaReplace\ShortpixelLogger\ShortPixelLogger as Log; | ||
|
||
use EnableMediaReplace\FileSystem\Model\File\DirectoryModel as DirectoryModel; | ||
use EnableMediaReplace\FileSystem\Model\File\FileModel as FileModel; | ||
|
||
|
||
/** Controller for FileSystem operations | ||
* | ||
* This controller is used for -compound- ( complex ) FS operations, using the provided models File en Directory. | ||
* USE via \wpSPIO()->filesystem(); | ||
*/ | ||
Class FileSystemController | ||
{ | ||
|
||
public function __construct() | ||
{ | ||
|
||
} | ||
|
||
/** Get FileModel for a certain path. This can exist or not | ||
* | ||
* @param String Path Full Path to the file | ||
* @return FileModel FileModel Object. If file does not exist, not all values are set. | ||
*/ | ||
public function getFile($path) | ||
{ | ||
return new FileModel($path); | ||
} | ||
|
||
|
||
|
||
/** Get DirectoryModel for a certain path. This can exist or not | ||
* | ||
* @param String $path Full Path to the Directory. | ||
* @return DirectoryModel Object with status set on current directory. | ||
*/ | ||
public function getDirectory($path) | ||
{ | ||
return new DirectoryModel($path); | ||
} | ||
|
||
|
||
|
||
|
||
/** This function returns the WordPress Basedir for uploads ( without date and such ) | ||
* Normally this would point to /wp-content/uploads. | ||
* @returns DirectoryModel | ||
*/ | ||
public function getWPUploadBase() | ||
{ | ||
$upload_dir = wp_upload_dir(null, false); | ||
|
||
return $this->getDirectory($upload_dir['basedir']); | ||
} | ||
|
||
/** This function returns the Absolute Path of the WordPress installation where the **CONTENT** directory is located. | ||
* Normally this would be the same as ABSPATH, but there are installations out there with -cough- alternative approaches | ||
* @returns DirectoryModel Either the ABSPATH or where the WP_CONTENT_DIR is located | ||
*/ | ||
public function getWPAbsPath() | ||
{ | ||
$wpContentAbs = str_replace( 'wp-content', '', WP_CONTENT_DIR); | ||
if (ABSPATH == $wpContentAbs) | ||
$abspath = ABSPATH; | ||
else | ||
$abspath = $wpContentAbs; | ||
|
||
if (defined('UPLOADS')) // if this is set, lead. | ||
$abspath = trailingslashit(ABSPATH) . UPLOADS; | ||
|
||
$abspath = apply_filters('shortpixel/filesystem/abspath', $abspath ); | ||
|
||
return $this->getDirectory($abspath); | ||
} | ||
|
||
|
||
/** Utility function that tries to convert a file-path to a webURL. | ||
* | ||
* If possible, rely on other better methods to find URL ( e.g. via WP functions ). | ||
*/ | ||
public function pathToUrl(FileModel $file) | ||
{ | ||
$filepath = $file->getFullPath(); | ||
$directory = $file->getFileDir(); | ||
|
||
$is_multi_site = $this->env->is_multisite; | ||
$is_main_site = $this->env->is_mainsite; | ||
|
||
// stolen from wp_get_attachment_url | ||
if ( ( $uploads = wp_get_upload_dir() ) && (false === $uploads['error'] || strlen(trim($uploads['error'])) == 0 ) ) { | ||
// Check that the upload base exists in the file location. | ||
if ( 0 === strpos( $filepath, $uploads['basedir'] ) ) { // Simple as it should, filepath and basedir share. | ||
// Replace file location with url location. | ||
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath ); | ||
} | ||
// Multisite backups are stored under uploads/ShortpixelBackups/etc , but basedir would include uploads/sites/2 etc, not matching above | ||
// If this is case, test if removing the last two directories will result in a 'clean' uploads reference. | ||
// This is used by getting preview path ( backup pathToUrl) in bulk and for comparer.. | ||
elseif ($is_multi_site && ! $is_main_site && 0 === strpos($filepath, dirname(dirname($uploads['basedir']))) ) | ||
{ | ||
|
||
$url = str_replace( dirname(dirname($uploads['basedir'])), dirname(dirname($uploads['baseurl'])), $filepath ); | ||
$homeUrl = home_url(); | ||
|
||
// The result didn't end in a full URL because URL might have less subdirs ( dirname dirname) . | ||
// This happens when site has blogs.dir (sigh) on a subdomain . Try to substitue the ABSPATH root with the home_url | ||
if (strpos($url, $homeUrl) === false) | ||
{ | ||
$url = str_replace( trailingslashit(ABSPATH), trailingslashit($homeUrl), $filepath); | ||
} | ||
|
||
} elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) { | ||
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads) | ||
$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $filepath ) ) . wp_basename( $filepath ); | ||
} else { | ||
// It's a newly-uploaded file, therefore $file is relative to the basedir. | ||
$url = $uploads['baseurl'] . "/$filepath"; | ||
} | ||
} | ||
|
||
$wp_home_path = (string) $this->getWPAbsPath(); | ||
// If the whole WP homepath is still in URL, assume the replace when wrong ( not replaced w/ URL) | ||
// This happens when file is outside of wp_uploads_dir | ||
if (strpos($url, $wp_home_path) !== false) | ||
{ | ||
// This is SITE URL, for the same reason it should be home_url in FILEMODEL. The difference is when the site is running on a subdirectory | ||
// (1) ** This is a fix for a real-life issue, do not change if this causes issues, another fix is needed then. | ||
// (2) ** Also a real life fix when a path is /wwwroot/assets/sites/2/ etc, in get site url, the home URL is the site URL, without appending the sites stuff. Fails on original image. | ||
if ($is_multi_site && ! $is_main_site) | ||
{ | ||
$wp_home_path = wp_normalize_path(trailingslashit($uploads['basedir'])); | ||
$home_url = trailingslashit($uploads['baseurl']); | ||
} | ||
else | ||
$home_url = trailingslashit(get_site_url()); // (1) | ||
$url = str_replace($wp_home_path, $home_url, $filepath); | ||
} | ||
|
||
// can happen if there are WP path errors. | ||
if (is_null($url)) | ||
return false; | ||
|
||
$parsed = parse_url($url); // returns array, null, or false. | ||
|
||
// Some hosts set the content dir to a relative path instead of a full URL. Api can't handle that, so add domain and such if this is the case. | ||
if ( !isset($parsed['scheme']) ) {//no absolute URLs used -> we implement a hack | ||
|
||
if (isset($parsed['host'])) // This is for URL's for // without http or https. hackhack. | ||
{ | ||
$scheme = is_ssl() ? 'https:' : 'http:'; | ||
return $scheme. $url; | ||
} | ||
else | ||
{ | ||
// From Metafacade. Multiple solutions /hacks. | ||
$home_url = trailingslashit((function_exists("is_multisite") && is_multisite()) ? trim(network_site_url("/")) : trim(home_url())); | ||
return $home_url . ltrim($url,'/');//get the file URL | ||
} | ||
} | ||
|
||
if (! is_null($parsed) && $parsed !== false) | ||
return $url; | ||
|
||
return false; | ||
} | ||
|
||
/** Utility function to check if a path is an URL | ||
* Checks if this path looks like an URL. | ||
* @param $path String Path to check | ||
* @return Boolean If path seems domain. | ||
*/ | ||
public function pathIsUrl($path) | ||
{ | ||
$is_http = (substr($path, 0, 4) == 'http') ? true : false; | ||
$is_https = (substr($path, 0, 5) == 'https') ? true : false; | ||
$is_neutralscheme = (substr($path, 0, 2) == '//') ? true : false; // when URL is relative like //wp-content/etc | ||
$has_urldots = (strpos($path, '://') !== false) ? true : false; // Like S3 offloads | ||
|
||
if ($is_http || $is_https || $is_neutralscheme || $has_urldots) | ||
return true; | ||
else | ||
return false; | ||
} | ||
|
||
/** Sort files / directories in a certain way. | ||
* Future dev to include options via arg. | ||
*/ | ||
public function sortFiles($array, $args = array() ) | ||
{ | ||
if (count($array) == 0) | ||
return $array; | ||
|
||
// what are we sorting. | ||
$class = get_class($array[0]); | ||
$is_files = ($class == 'EnableMediaReplace\FileModel') ? true : false; // if not files, then dirs. | ||
|
||
usort($array, function ($a, $b) use ($is_files) | ||
{ | ||
if ($is_files) | ||
return strcmp($a->getFileName(), $b->getFileName()); | ||
else { | ||
return strcmp($a->getName(), $b->getName()); | ||
} | ||
} | ||
); | ||
|
||
return $array; | ||
|
||
} | ||
|
||
public function downloadFile($url, $destinationPath) | ||
{ | ||
|
||
//$downloadTimeout = defined(SHORTPIXEL_MAX_EXECUTION_TIME) ? max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15) :; | ||
$max_exec = intval(ini_get('max_execution_time')); | ||
if ($max_exec === 0) // max execution time of zero means infinite. Quantify. | ||
$max_exec = 60; | ||
elseif($max_exec < 0) // some hosts like to set negative figures on this. Ignore that. | ||
$max_exec = 30; | ||
|
||
$downloadTimeout = $max_exec; | ||
|
||
|
||
$destinationFile = $this->getFile($destinationPath); | ||
|
||
$args_for_get = array( | ||
'stream' => true, | ||
'filename' => $destinationPath, | ||
); | ||
|
||
$response = wp_remote_get( $url, $args_for_get ); | ||
|
||
if(is_wp_error( $response )) { | ||
Log::addError('Download file failed', array($url, $response->get_error_messages(), $response->get_error_codes() )); | ||
|
||
// Try to get it then via this way. | ||
$response = download_url($url, $downloadTimeout); | ||
if (!is_wp_error($response)) // response when alright is a tmp filepath. But given path can't be trusted since that can be reason for fail. | ||
{ | ||
$tmpFile = $this->getFile($response); | ||
$result = $tmpFile->move($destinationFile); | ||
|
||
} // download_url .. | ||
else { | ||
Log::addError('Secondary download failed', array($url, $response->get_error_messages(), $response->get_error_codes() )); | ||
} | ||
} | ||
else { // success, at least the download. | ||
$destinationFile = $this->getFile($response['filename']); | ||
} | ||
|
||
Log::addDebug('Remote Download attempt result', array($url, $destinationPath)); | ||
if ($destinationFile->exists()) | ||
return true; | ||
else | ||
return false; | ||
} | ||
|
||
|
||
|
||
/** Get all files from a directory tree, starting at given dir. | ||
* @param DirectoryModel $dir to recursive into | ||
* @param Array $filters Collection of optional filters as accepted by FileFilter in directoryModel | ||
* @return Array Array of FileModel Objects | ||
**/ | ||
public function getFilesRecursive(DirectoryModel $dir, $filters = array() ) | ||
{ | ||
$fileArray = array(); | ||
|
||
if (! $dir->exists()) | ||
return $fileArray; | ||
|
||
$files = $dir->getFiles($filters); | ||
$fileArray = array_merge($fileArray, $files); | ||
|
||
$subdirs = $dir->getSubDirectories(); | ||
|
||
foreach($subdirs as $subdir) | ||
{ | ||
$fileArray = array_merge($fileArray, $this->getFilesRecursive($subdir, $filters)); | ||
} | ||
|
||
return $fileArray; | ||
} | ||
|
||
// Url very sparingly. | ||
public function url_exists($url) | ||
{ | ||
if (! function_exists('curl_init')) | ||
{ | ||
return null; | ||
} | ||
|
||
$ch = curl_init($url); | ||
curl_setopt($ch, CURLOPT_NOBODY, true); | ||
curl_exec($ch); | ||
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
curl_close($ch); | ||
|
||
if ($responseCode == 200) | ||
{ | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.