Skip to content

Commit

Permalink
Release version 4.0.0 (#84)
Browse files Browse the repository at this point in the history
Merge pull request #84 from short-pixel-optimizer/updates
  • Loading branch information
pdobrescu authored Sep 5, 2022
2 parents c134385 + ea989e4 commit fdf3ff5
Show file tree
Hide file tree
Showing 39 changed files with 3,658 additions and 791 deletions.
2 changes: 1 addition & 1 deletion build/shortpixel/autoload.php
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__);

2 changes: 1 addition & 1 deletion build/shortpixel/composer.json
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"}}}
18 changes: 18 additions & 0 deletions build/shortpixel/filesystem/composer.json
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 build/shortpixel/filesystem/src/Controller/FileSystemController.php
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;
}

}
}
Loading

0 comments on commit fdf3ff5

Please sign in to comment.