Skip to content

Commit fdf3ff5

Browse files
authored
Release version 4.0.0 (#84)
Merge pull request #84 from short-pixel-optimizer/updates
2 parents c134385 + ea989e4 commit fdf3ff5

39 files changed

+3658
-791
lines changed

build/shortpixel/autoload.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
2-
require_once (dirname(__FILE__) . "/PackageLoader.php");
2+
require_once (__DIR__ . "/PackageLoader.php");
33
$loader = new EnableMediaReplace\Build\PackageLoader();
44
$loader->load(__DIR__);
55

build/shortpixel/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src"}}}
1+
{"name":"EnableMediaReplace\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"EnableMediaReplace\\ShortPixelLogger":"log\/src","EnableMediaReplace\\Notices":"notices\/src","EnableMediaReplace\\FileSystem":"filesystem\/src"}}}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "shortpixel/filesystem",
3+
"description": "ShortPixel FileSystem",
4+
"version": 1.0,
5+
"type": "library",
6+
"license": "MIT",
7+
"authors": [
8+
{
9+
"name": "Bas",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"minimum-stability": "dev",
14+
"require": {},
15+
"autoload": {
16+
"psr-4": { "ShortPixel\\FileSystem\\" : "src" }
17+
}
18+
}
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
<?php
2+
namespace EnableMediaReplace\FileSystem\Controller;
3+
use EnableMediaReplace\ShortpixelLogger\ShortPixelLogger as Log;
4+
5+
use EnableMediaReplace\FileSystem\Model\File\DirectoryModel as DirectoryModel;
6+
use EnableMediaReplace\FileSystem\Model\File\FileModel as FileModel;
7+
8+
9+
/** Controller for FileSystem operations
10+
*
11+
* This controller is used for -compound- ( complex ) FS operations, using the provided models File en Directory.
12+
* USE via \wpSPIO()->filesystem();
13+
*/
14+
Class FileSystemController
15+
{
16+
17+
public function __construct()
18+
{
19+
20+
}
21+
22+
/** Get FileModel for a certain path. This can exist or not
23+
*
24+
* @param String Path Full Path to the file
25+
* @return FileModel FileModel Object. If file does not exist, not all values are set.
26+
*/
27+
public function getFile($path)
28+
{
29+
return new FileModel($path);
30+
}
31+
32+
33+
34+
/** Get DirectoryModel for a certain path. This can exist or not
35+
*
36+
* @param String $path Full Path to the Directory.
37+
* @return DirectoryModel Object with status set on current directory.
38+
*/
39+
public function getDirectory($path)
40+
{
41+
return new DirectoryModel($path);
42+
}
43+
44+
45+
46+
47+
/** This function returns the WordPress Basedir for uploads ( without date and such )
48+
* Normally this would point to /wp-content/uploads.
49+
* @returns DirectoryModel
50+
*/
51+
public function getWPUploadBase()
52+
{
53+
$upload_dir = wp_upload_dir(null, false);
54+
55+
return $this->getDirectory($upload_dir['basedir']);
56+
}
57+
58+
/** This function returns the Absolute Path of the WordPress installation where the **CONTENT** directory is located.
59+
* Normally this would be the same as ABSPATH, but there are installations out there with -cough- alternative approaches
60+
* @returns DirectoryModel Either the ABSPATH or where the WP_CONTENT_DIR is located
61+
*/
62+
public function getWPAbsPath()
63+
{
64+
$wpContentAbs = str_replace( 'wp-content', '', WP_CONTENT_DIR);
65+
if (ABSPATH == $wpContentAbs)
66+
$abspath = ABSPATH;
67+
else
68+
$abspath = $wpContentAbs;
69+
70+
if (defined('UPLOADS')) // if this is set, lead.
71+
$abspath = trailingslashit(ABSPATH) . UPLOADS;
72+
73+
$abspath = apply_filters('shortpixel/filesystem/abspath', $abspath );
74+
75+
return $this->getDirectory($abspath);
76+
}
77+
78+
79+
/** Utility function that tries to convert a file-path to a webURL.
80+
*
81+
* If possible, rely on other better methods to find URL ( e.g. via WP functions ).
82+
*/
83+
public function pathToUrl(FileModel $file)
84+
{
85+
$filepath = $file->getFullPath();
86+
$directory = $file->getFileDir();
87+
88+
$is_multi_site = $this->env->is_multisite;
89+
$is_main_site = $this->env->is_mainsite;
90+
91+
// stolen from wp_get_attachment_url
92+
if ( ( $uploads = wp_get_upload_dir() ) && (false === $uploads['error'] || strlen(trim($uploads['error'])) == 0 ) ) {
93+
// Check that the upload base exists in the file location.
94+
if ( 0 === strpos( $filepath, $uploads['basedir'] ) ) { // Simple as it should, filepath and basedir share.
95+
// Replace file location with url location.
96+
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath );
97+
}
98+
// Multisite backups are stored under uploads/ShortpixelBackups/etc , but basedir would include uploads/sites/2 etc, not matching above
99+
// If this is case, test if removing the last two directories will result in a 'clean' uploads reference.
100+
// This is used by getting preview path ( backup pathToUrl) in bulk and for comparer..
101+
elseif ($is_multi_site && ! $is_main_site && 0 === strpos($filepath, dirname(dirname($uploads['basedir']))) )
102+
{
103+
104+
$url = str_replace( dirname(dirname($uploads['basedir'])), dirname(dirname($uploads['baseurl'])), $filepath );
105+
$homeUrl = home_url();
106+
107+
// The result didn't end in a full URL because URL might have less subdirs ( dirname dirname) .
108+
// This happens when site has blogs.dir (sigh) on a subdomain . Try to substitue the ABSPATH root with the home_url
109+
if (strpos($url, $homeUrl) === false)
110+
{
111+
$url = str_replace( trailingslashit(ABSPATH), trailingslashit($homeUrl), $filepath);
112+
}
113+
114+
} elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) {
115+
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
116+
$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $filepath ) ) . wp_basename( $filepath );
117+
} else {
118+
// It's a newly-uploaded file, therefore $file is relative to the basedir.
119+
$url = $uploads['baseurl'] . "/$filepath";
120+
}
121+
}
122+
123+
$wp_home_path = (string) $this->getWPAbsPath();
124+
// If the whole WP homepath is still in URL, assume the replace when wrong ( not replaced w/ URL)
125+
// This happens when file is outside of wp_uploads_dir
126+
if (strpos($url, $wp_home_path) !== false)
127+
{
128+
// 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
129+
// (1) ** This is a fix for a real-life issue, do not change if this causes issues, another fix is needed then.
130+
// (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.
131+
if ($is_multi_site && ! $is_main_site)
132+
{
133+
$wp_home_path = wp_normalize_path(trailingslashit($uploads['basedir']));
134+
$home_url = trailingslashit($uploads['baseurl']);
135+
}
136+
else
137+
$home_url = trailingslashit(get_site_url()); // (1)
138+
$url = str_replace($wp_home_path, $home_url, $filepath);
139+
}
140+
141+
// can happen if there are WP path errors.
142+
if (is_null($url))
143+
return false;
144+
145+
$parsed = parse_url($url); // returns array, null, or false.
146+
147+
// 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.
148+
if ( !isset($parsed['scheme']) ) {//no absolute URLs used -> we implement a hack
149+
150+
if (isset($parsed['host'])) // This is for URL's for // without http or https. hackhack.
151+
{
152+
$scheme = is_ssl() ? 'https:' : 'http:';
153+
return $scheme. $url;
154+
}
155+
else
156+
{
157+
// From Metafacade. Multiple solutions /hacks.
158+
$home_url = trailingslashit((function_exists("is_multisite") && is_multisite()) ? trim(network_site_url("/")) : trim(home_url()));
159+
return $home_url . ltrim($url,'/');//get the file URL
160+
}
161+
}
162+
163+
if (! is_null($parsed) && $parsed !== false)
164+
return $url;
165+
166+
return false;
167+
}
168+
169+
/** Utility function to check if a path is an URL
170+
* Checks if this path looks like an URL.
171+
* @param $path String Path to check
172+
* @return Boolean If path seems domain.
173+
*/
174+
public function pathIsUrl($path)
175+
{
176+
$is_http = (substr($path, 0, 4) == 'http') ? true : false;
177+
$is_https = (substr($path, 0, 5) == 'https') ? true : false;
178+
$is_neutralscheme = (substr($path, 0, 2) == '//') ? true : false; // when URL is relative like //wp-content/etc
179+
$has_urldots = (strpos($path, '://') !== false) ? true : false; // Like S3 offloads
180+
181+
if ($is_http || $is_https || $is_neutralscheme || $has_urldots)
182+
return true;
183+
else
184+
return false;
185+
}
186+
187+
/** Sort files / directories in a certain way.
188+
* Future dev to include options via arg.
189+
*/
190+
public function sortFiles($array, $args = array() )
191+
{
192+
if (count($array) == 0)
193+
return $array;
194+
195+
// what are we sorting.
196+
$class = get_class($array[0]);
197+
$is_files = ($class == 'EnableMediaReplace\FileModel') ? true : false; // if not files, then dirs.
198+
199+
usort($array, function ($a, $b) use ($is_files)
200+
{
201+
if ($is_files)
202+
return strcmp($a->getFileName(), $b->getFileName());
203+
else {
204+
return strcmp($a->getName(), $b->getName());
205+
}
206+
}
207+
);
208+
209+
return $array;
210+
211+
}
212+
213+
public function downloadFile($url, $destinationPath)
214+
{
215+
216+
//$downloadTimeout = defined(SHORTPIXEL_MAX_EXECUTION_TIME) ? max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15) :;
217+
$max_exec = intval(ini_get('max_execution_time'));
218+
if ($max_exec === 0) // max execution time of zero means infinite. Quantify.
219+
$max_exec = 60;
220+
elseif($max_exec < 0) // some hosts like to set negative figures on this. Ignore that.
221+
$max_exec = 30;
222+
223+
$downloadTimeout = $max_exec;
224+
225+
226+
$destinationFile = $this->getFile($destinationPath);
227+
228+
$args_for_get = array(
229+
'stream' => true,
230+
'filename' => $destinationPath,
231+
);
232+
233+
$response = wp_remote_get( $url, $args_for_get );
234+
235+
if(is_wp_error( $response )) {
236+
Log::addError('Download file failed', array($url, $response->get_error_messages(), $response->get_error_codes() ));
237+
238+
// Try to get it then via this way.
239+
$response = download_url($url, $downloadTimeout);
240+
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.
241+
{
242+
$tmpFile = $this->getFile($response);
243+
$result = $tmpFile->move($destinationFile);
244+
245+
} // download_url ..
246+
else {
247+
Log::addError('Secondary download failed', array($url, $response->get_error_messages(), $response->get_error_codes() ));
248+
}
249+
}
250+
else { // success, at least the download.
251+
$destinationFile = $this->getFile($response['filename']);
252+
}
253+
254+
Log::addDebug('Remote Download attempt result', array($url, $destinationPath));
255+
if ($destinationFile->exists())
256+
return true;
257+
else
258+
return false;
259+
}
260+
261+
262+
263+
/** Get all files from a directory tree, starting at given dir.
264+
* @param DirectoryModel $dir to recursive into
265+
* @param Array $filters Collection of optional filters as accepted by FileFilter in directoryModel
266+
* @return Array Array of FileModel Objects
267+
**/
268+
public function getFilesRecursive(DirectoryModel $dir, $filters = array() )
269+
{
270+
$fileArray = array();
271+
272+
if (! $dir->exists())
273+
return $fileArray;
274+
275+
$files = $dir->getFiles($filters);
276+
$fileArray = array_merge($fileArray, $files);
277+
278+
$subdirs = $dir->getSubDirectories();
279+
280+
foreach($subdirs as $subdir)
281+
{
282+
$fileArray = array_merge($fileArray, $this->getFilesRecursive($subdir, $filters));
283+
}
284+
285+
return $fileArray;
286+
}
287+
288+
// Url very sparingly.
289+
public function url_exists($url)
290+
{
291+
if (! function_exists('curl_init'))
292+
{
293+
return null;
294+
}
295+
296+
$ch = curl_init($url);
297+
curl_setopt($ch, CURLOPT_NOBODY, true);
298+
curl_exec($ch);
299+
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
300+
curl_close($ch);
301+
302+
if ($responseCode == 200)
303+
{
304+
return true;
305+
}
306+
else {
307+
return false;
308+
}
309+
310+
}
311+
}

0 commit comments

Comments
 (0)