This commit is contained in:
2024-03-05 22:58:01 -06:00
parent f2edb49d22
commit 58806aba64
262 changed files with 31855 additions and 3 deletions

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Yani Iliev
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,233 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Main template engine file
*
* PHP version 5
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @category Templates
* @package Bandar
* @author Yani Iliev <yani@iliev.me>
* @copyright 2013 Yani Iliev
* @license https://raw.github.com/yani-/bandar/master/LICENSE The MIT License (MIT)
* @version GIT: 3.0.0
* @link https://github.com/yani-/bandar/
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
/**
* Define EOL for CLI and Web
*/
if (!defined('BANDAR_EOL')) {
define('BANDAR_EOL', php_sapi_name() === 'cli' ? PHP_EOL : '<br />');
}
/**
* Include exceptions
*/
require_once
dirname(__FILE__) .
DIRECTORY_SEPARATOR .
'Exceptions' .
DIRECTORY_SEPARATOR .
'TemplateDoesNotExistException.php';
/**
* Bandar Main class
*
* @category Templates
* @package Bandar
* @author Yani Iliev <yani@iliev.me>
* @copyright 2013 Yani Iliev
* @license https://raw.github.com/yani-/bandar/master/LICENSE The MIT License (MIT)
* @version Release: 2.0.1
* @link https://github.com/yani-/bandar/
*/
class Bandar
{
/**
* Path to template files
*
* @var string|null
*/
public static $templatesPath = null;
/**
* Template file to output
* @var string|null
*/
public static $template = null;
/**
* Outputs the passed string if Bandar is in debug mode
*
* @param string $str Debug string to output
*
* @return void
*/
public static function debug($str)
{
/**
* if debug flag is on, output the string
*/
if (defined('BANDAR_DEBUG') && BANDAR_DEBUG) {
echo $str;
}
}
/**
* Retrieves templatesPath from BANDAR_TEMPLATES_PATH constant
*
* @throws TemplatesPathNotSetException If BANDAR_TEMPLATES_PATH is not defined
*
* @return string|null Templates path
*/
public static function getTemplatesPathFromConstant()
{
self::debug(
'Calling getTemplatesPathFromConstant' . BANDAR_EOL
);
if (defined('BANDAR_TEMPLATES_PATH')) {
return realpath(BANDAR_TEMPLATES_PATH) . DIRECTORY_SEPARATOR;
}
return null;
}
/**
* Setter for template
*
* @param string $template Template file
*
* @throws TemplateDoesNotExistException If template file is not found
*
* @return null
*/
public static function setTemplate($template, $path = false)
{
self::debug(
'Calling setTemplate with' . BANDAR_EOL .
'$template = ' . $template . BANDAR_EOL .
'type of $template is ' . gettype($template) . BANDAR_EOL
);
if ($path) {
$template = realpath($path) . DIRECTORY_SEPARATOR . $template;
} else {
$template = self::getTemplatesPathFromConstant() . $template;
}
$template = realpath($template . '.php');
/**
* Check if passed template exist
*/
if (self::templateExists($template)) {
self::$template = $template;
} else {
throw new TemplateDoesNotExistException;
}
}
/**
* Checks if template exists by using file_exists
*
* @param string $template Template file
*
* @return boolean
*/
public static function templateExists($template)
{
self::debug(
'Calling templateExists with ' . BANDAR_EOL .
'$template = ' . $template . BANDAR_EOL .
'type of $template is ' . gettype($template) . BANDAR_EOL
);
return (!is_dir($template) && is_readable($template));
}
/**
* Renders a passed template
*
* @param string $template Template name
* @param array $args Variables to pass to the template file
*
* @return string Contents of the template
*/
public static function render($template, $args=array(), $path = false)
{
self::debug(
'Calling render with' .
'$template = ' . $template . BANDAR_EOL .
'type of $template is ' . gettype($template) . BANDAR_EOL .
'$args = ' . print_r($args, true) . BANDAR_EOL .
'type of $args is ' . gettype($args) . BANDAR_EOL
);
self::setTemplate($template, $path);
/**
* Extracting passed aguments
*/
extract($args);
ob_start();
/**
* Including the view
*/
include self::$template;
return ob_get_flush();
}
/**
* Returns the content of a passed template
*
* @param string $template Template name
* @param array $args Variables to pass to the template file
*
* @return string Contents of the template
*/
public static function getTemplateContent($template, $args=array(), $path = false)
{
self::debug(
'Calling render with' .
'$template = ' . $template . BANDAR_EOL .
'type of $template is ' . gettype($template) . BANDAR_EOL .
'$args = ' . print_r($args, true) . BANDAR_EOL .
'type of $args is ' . gettype($args) . BANDAR_EOL
);
self::setTemplate($template, $path);
/**
* Extracting passed aguments
*/
extract($args);
ob_start();
/**
* Including the view
*/
include self::$template;
$content = ob_get_contents();
ob_end_clean();
return $content;
}
}

View File

@ -0,0 +1,54 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Contains TemplateDoesNotExistException class to be used in main Bandar class
*
* PHP version 5
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @category Exceptions
* @package Bandar
* @author Yani Iliev <yani@iliev.me>
* @copyright 2013 Yani Iliev
* @license https://raw.github.com/yani-/bandar/master/LICENSE The MIT License (MIT)
* @version GIT: 3.0.0
* @link https://github.com/yani-/bandar/
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
/**
* TemplateDoesNotExistException
*
* @category Exceptions
* @package Bandar
* @author Yani Iliev <yani@iliev.me>
* @copyright 2013 Yani Iliev
* @license https://raw.github.com/yani-/bandar/master/LICENSE The MIT License (MIT)
* @version Release: 2.0.1
* @link https://github.com/yani-/bandar/
*/
class TemplateDoesNotExistException extends Exception
{
}

View File

@ -0,0 +1,257 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
abstract class Ai1wm_Archiver {
/**
* Filename including path to the file
*
* @type string
*/
protected $file_name = null;
/**
* Handle to the file
*
* @type resource
*/
protected $file_handle = null;
/**
* Header block format of a file
*
* Field Name Offset Length Contents
* name 0 255 filename (no path, no slash)
* size 255 14 size of file contents
* mtime 269 12 last modification time
* prefix 281 4096 path name, no trailing slashes
*
* @type array
*/
protected $block_format = array(
'a255', // filename
'a14', // size of file contents
'a12', // last time modified
'a4096', // path
);
/**
* End of file block string
*
* @type string
*/
protected $eof = null;
/**
* Default constructor
*
* Initializes filename and end of file block
*
* @param string $file_name Archive file
* @param bool $write Read/write mode
*/
public function __construct( $file_name, $write = false ) {
$this->file_name = $file_name;
// Initialize end of file block
$this->eof = pack( 'a4377', '' );
// Open archive file
if ( $write ) {
// Open archive file for writing
if ( ( $this->file_handle = @fopen( $file_name, 'cb' ) ) === false ) {
throw new Ai1wm_Not_Accessible_Exception( sprintf( __( 'Unable to open file for writing. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Seek to end of archive file
if ( @fseek( $this->file_handle, 0, SEEK_END ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to end of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
} else {
// Open archive file for reading
if ( ( $this->file_handle = @fopen( $file_name, 'rb' ) ) === false ) {
throw new Ai1wm_Not_Accessible_Exception( sprintf( __( 'Unable to open file for reading. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
}
}
/**
* Set current file pointer
*
* @param int $offset Archive offset
*
* @throws \Ai1wm_Not_Seekable_Exception
*
* @return void
*/
public function set_file_pointer( $offset ) {
if ( @fseek( $this->file_handle, $offset, SEEK_SET ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $offset ) );
}
}
/**
* Get current file pointer
*
* @throws \Ai1wm_Not_Tellable_Exception
*
* @return int
*/
public function get_file_pointer() {
if ( ( $offset = @ftell( $this->file_handle ) ) === false ) {
throw new Ai1wm_Not_Tellable_Exception( sprintf( __( 'Unable to tell offset of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
return $offset;
}
/**
* Appends end of file block to the archive file
*
* @throws \Ai1wm_Not_Seekable_Exception
* @throws \Ai1wm_Not_Writable_Exception
* @throws \Ai1wm_Quota_Exceeded_Exception
*
* @return void
*/
protected function append_eof() {
// Seek to end of archive file
if ( @fseek( $this->file_handle, 0, SEEK_END ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to end of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Write end of file block
if ( ( $file_bytes = @fwrite( $this->file_handle, $this->eof ) ) !== false ) {
if ( strlen( $this->eof ) !== $file_bytes ) {
throw new Ai1wm_Quota_Exceeded_Exception( sprintf( __( 'Out of disk space. Unable to write end of block to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
} else {
throw new Ai1wm_Not_Writable_Exception( sprintf( __( 'Unable to write end of block to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
}
/**
* Replace forward slash with current directory separator
*
* @param string $path Path
*
* @return string
*/
protected function replace_forward_slash_with_directory_separator( $path ) {
return str_replace( '/', DIRECTORY_SEPARATOR, $path );
}
/**
* Replace current directory separator with forward slash
*
* @param string $path Path
*
* @return string
*/
protected function replace_directory_separator_with_forward_slash( $path ) {
return str_replace( DIRECTORY_SEPARATOR, '/', $path );
}
/**
* Escape Windows directory separator
*
* @param string $path Path
*
* @return string
*/
protected function escape_windows_directory_separator( $path ) {
return preg_replace( '/[\\\\]+/', '\\\\\\\\', $path );
}
/**
* Validate archive file
*
* @return bool
*/
public function is_valid() {
// Failed detecting the current file pointer offset
if ( ( $offset = @ftell( $this->file_handle ) ) === false ) {
return false;
}
// Failed seeking the beginning of EOL block
if ( @fseek( $this->file_handle, -4377, SEEK_END ) === -1 ) {
return false;
}
// Trailing block does not match EOL: file is incomplete
if ( @fread( $this->file_handle, 4377 ) !== $this->eof ) {
return false;
}
// Failed returning to original offset
if ( @fseek( $this->file_handle, $offset, SEEK_SET ) === -1 ) {
return false;
}
return true;
}
/**
* Truncates the archive file
*
* @return void
*/
public function truncate() {
if ( ( $offset = @ftell( $this->file_handle ) ) === false ) {
throw new Ai1wm_Not_Tellable_Exception( sprintf( __( 'Unable to tell offset of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
if ( @filesize( $this->file_name ) > $offset ) {
if ( @ftruncate( $this->file_handle, $offset ) === false ) {
throw new Ai1wm_Not_Truncatable_Exception( sprintf( __( 'Unable to truncate file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
}
}
/**
* Closes the archive file
*
* We either close the file or append the end of file block if complete argument is set to true
*
* @param bool $complete Flag to append end of file block
*
* @return void
*/
public function close( $complete = false ) {
// Are we done appending to the file?
if ( true === $complete ) {
$this->append_eof();
}
if ( @fclose( $this->file_handle ) === false ) {
throw new Ai1wm_Not_Closable_Exception( sprintf( __( 'Unable to close file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
}
}

View File

@ -0,0 +1,219 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Compressor extends Ai1wm_Archiver {
/**
* Overloaded constructor that opens the passed file for writing
*
* @param string $file_name File to use as archive
*/
public function __construct( $file_name ) {
parent::__construct( $file_name, true );
}
/**
* Add a file to the archive
*
* @param string $file_name File to add to the archive
* @param string $new_file_name Write the file with a different name
* @param int $file_written File written (in bytes)
* @param int $file_offset File offset (in bytes)
*
* @throws \Ai1wm_Not_Seekable_Exception
* @throws \Ai1wm_Not_Writable_Exception
* @throws \Ai1wm_Quota_Exceeded_Exception
*
* @return bool
*/
public function add_file( $file_name, $new_file_name = '', &$file_written = 0, &$file_offset = 0 ) {
global $ai1wm_params;
$file_written = 0;
// Replace forward slash with current directory separator in file name
$file_name = ai1wm_replace_forward_slash_with_directory_separator( $file_name );
// Escape Windows directory separator in file name
$file_name = ai1wm_escape_windows_directory_separator( $file_name );
// Flag to hold if file data has been processed
$completed = true;
// Start time
$start = microtime( true );
// Open the file for reading in binary mode (fopen may return null for quarantined files)
if ( ( $file_handle = @fopen( $file_name, 'rb' ) ) ) {
$file_bytes = 0;
// Get header block
if ( ( $block = $this->get_file_block( $file_name, $new_file_name ) ) ) {
// Write header block
if ( $file_offset === 0 ) {
if ( ( $file_bytes = @fwrite( $this->file_handle, $block ) ) !== false ) {
if ( strlen( $block ) !== $file_bytes ) {
throw new Ai1wm_Quota_Exceeded_Exception( sprintf( __( 'Out of disk space. Unable to write header to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
} else {
throw new Ai1wm_Not_Writable_Exception( sprintf( __( 'Unable to write header to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
}
// Set file offset
if ( @fseek( $file_handle, $file_offset, SEEK_SET ) !== -1 ) {
// Read the file in 512KB chunks
while ( false === @feof( $file_handle ) ) {
// Read the file in chunks of 512KB
if ( ( $file_content = @fread( $file_handle, 512000 ) ) !== false ) {
// Don't encrypt package.json
if ( isset( $ai1wm_params['options']['encrypt_backups'] ) && basename( $file_name ) !== 'package.json' ) {
$file_content = ai1wm_encrypt_string( $file_content, $ai1wm_params['options']['encrypt_password'] );
}
if ( ( $file_bytes = @fwrite( $this->file_handle, $file_content ) ) !== false ) {
if ( strlen( $file_content ) !== $file_bytes ) {
throw new Ai1wm_Quota_Exceeded_Exception( sprintf( __( 'Out of disk space. Unable to write content to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
} else {
throw new Ai1wm_Not_Writable_Exception( sprintf( __( 'Unable to write content to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Set file written
$file_written += $file_bytes;
}
// Time elapsed
if ( ( $timeout = apply_filters( 'ai1wm_completed_timeout', 10 ) ) ) {
if ( ( microtime( true ) - $start ) > $timeout ) {
$completed = false;
break;
}
}
}
}
// Set file offset
$file_offset += $file_written;
// Write file size to file header
if ( ( $block = $this->get_file_size_block( $file_offset ) ) ) {
// Seek to beginning of file size
if ( @fseek( $this->file_handle, - $file_offset - 4096 - 12 - 14, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( __( 'Your PHP is 32-bit. In order to export your file, please change your PHP version to 64-bit and try again. <a href="https://help.servmask.com/knowledgebase/php-32bit/" target="_blank">Technical details</a>', AI1WM_PLUGIN_NAME ) );
}
// Write file size to file header
if ( ( $file_bytes = @fwrite( $this->file_handle, $block ) ) !== false ) {
if ( strlen( $block ) !== $file_bytes ) {
throw new Ai1wm_Quota_Exceeded_Exception( sprintf( __( 'Out of disk space. Unable to write size to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
} else {
throw new Ai1wm_Not_Writable_Exception( sprintf( __( 'Unable to write size to file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Seek to end of file content
if ( @fseek( $this->file_handle, + $file_offset + 4096 + 12, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( __( 'Your PHP is 32-bit. In order to export your file, please change your PHP version to 64-bit and try again. <a href="https://help.servmask.com/knowledgebase/php-32bit/" target="_blank">Technical details</a>', AI1WM_PLUGIN_NAME ) );
}
}
}
// Close the handle
@fclose( $file_handle );
}
return $completed;
}
/**
* Generate binary block header for a file
*
* @param string $file_name Filename to generate block header for
* @param string $new_file_name Write the file with a different name
*
* @return string
*/
private function get_file_block( $file_name, $new_file_name = '' ) {
$block = '';
// Get stats about the file
if ( ( $stat = @stat( $file_name ) ) !== false ) {
// Filename of the file we are accessing
if ( empty( $new_file_name ) ) {
$name = ai1wm_basename( $file_name );
} else {
$name = ai1wm_basename( $new_file_name );
}
// Size in bytes of the file
$size = $stat['size'];
// Last time the file was modified
$date = $stat['mtime'];
// Replace current directory separator with backward slash in file path
if ( empty( $new_file_name ) ) {
$path = ai1wm_replace_directory_separator_with_forward_slash( ai1wm_dirname( $file_name ) );
} else {
$path = ai1wm_replace_directory_separator_with_forward_slash( ai1wm_dirname( $new_file_name ) );
}
// Concatenate block format parts
$format = implode( '', $this->block_format );
// Pack file data into binary string
$block = pack( $format, $name, $size, $date, $path );
}
return $block;
}
/**
* Generate file size binary block header for a file
*
* @param int $file_size File size
*
* @return string
*/
public function get_file_size_block( $file_size ) {
$block = '';
// Pack file data into binary string
if ( isset( $this->block_format[1] ) ) {
$block = pack( $this->block_format[1], $file_size );
}
return $block;
}
}

View File

@ -0,0 +1,650 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Extractor extends Ai1wm_Archiver {
/**
* Total files count
*
* @type int
*/
protected $total_files_count = null;
/**
* Total files size
*
* @type int
*/
protected $total_files_size = null;
/**
* Overloaded constructor that opens the passed file for reading
*
* @param string $file_name File to use as archive
*/
public function __construct( $file_name ) {
// Call parent, to initialize variables
parent::__construct( $file_name );
}
public function list_files() {
$files = array();
// Seek to beginning of archive file
if ( @fseek( $this->file_handle, 0, SEEK_SET ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to beginning of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Loop over files
while ( $block = @fread( $this->file_handle, 4377 ) ) {
// End block has been reached
if ( $block === $this->eof ) {
continue;
}
// Get file data from the block
if ( ( $data = $this->get_data_from_block( $block ) ) ) {
// Store the position where the file begins - used for downloading from archive directly
$data['offset'] = @ftell( $this->file_handle );
// Skip file content, so we can move forward to the next file
if ( @fseek( $this->file_handle, $data['size'], SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $data['size'] ) );
}
$files[] = $data;
}
}
return $files;
}
/**
* Get the total files count in an archive
*
* @return int
*/
public function get_total_files_count() {
if ( is_null( $this->total_files_count ) ) {
// Total files count
$this->total_files_count = 0;
// Total files size
$this->total_files_size = 0;
// Seek to beginning of archive file
if ( @fseek( $this->file_handle, 0, SEEK_SET ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to beginning of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Loop over files
while ( $block = @fread( $this->file_handle, 4377 ) ) {
// End block has been reached
if ( $block === $this->eof ) {
continue;
}
// Get file data from the block
if ( ( $data = $this->get_data_from_block( $block ) ) ) {
// We have a file, increment the count
$this->total_files_count += 1;
// We have a file, increment the size
$this->total_files_size += $data['size'];
// Skip file content so we can move forward to the next file
if ( @fseek( $this->file_handle, $data['size'], SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $data['size'] ) );
}
}
}
}
return $this->total_files_count;
}
/**
* Get the total files size in an archive
*
* @return int
*/
public function get_total_files_size() {
if ( is_null( $this->total_files_size ) ) {
// Total files count
$this->total_files_count = 0;
// Total files size
$this->total_files_size = 0;
// Seek to beginning of archive file
if ( @fseek( $this->file_handle, 0, SEEK_SET ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to beginning of file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Loop over files
while ( $block = @fread( $this->file_handle, 4377 ) ) {
// End block has been reached
if ( $block === $this->eof ) {
continue;
}
// Get file data from the block
if ( ( $data = $this->get_data_from_block( $block ) ) ) {
// We have a file, increment the count
$this->total_files_count += 1;
// We have a file, increment the size
$this->total_files_size += $data['size'];
// Skip file content so we can move forward to the next file
if ( @fseek( $this->file_handle, $data['size'], SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $data['size'] ) );
}
}
}
}
return $this->total_files_size;
}
/**
* Extract one file to location
*
* @param string $location Destination path
* @param array $exclude_files Exclude files by name
* @param array $exclude_extensions Exclude files by extension
* @param array $old_paths Old replace paths
* @param array $new_paths New replace paths
* @param int $file_written File written (in bytes)
* @param int $file_offset File offset (in bytes)
*
* @throws \Ai1wm_Not_Directory_Exception
* @throws \Ai1wm_Not_Seekable_Exception
*
* @return bool
*/
public function extract_one_file_to( $location, $exclude_files = array(), $exclude_extensions = array(), $old_paths = array(), $new_paths = array(), &$file_written = 0, &$file_offset = 0 ) {
if ( false === is_dir( $location ) ) {
throw new Ai1wm_Not_Directory_Exception( sprintf( __( 'Location is not a directory: %s', AI1WM_PLUGIN_NAME ), $location ) );
}
// Replace forward slash with current directory separator in location
$location = ai1wm_replace_forward_slash_with_directory_separator( $location );
// Flag to hold if file data has been processed
$completed = true;
// Seek to file offset to archive file
if ( $file_offset > 0 ) {
if ( @fseek( $this->file_handle, - $file_offset - 4377, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, - $file_offset - 4377 ) );
}
}
// Read file header block
if ( ( $block = @fread( $this->file_handle, 4377 ) ) ) {
// We reached end of file, set the pointer to the end of the file so that feof returns true
if ( $block === $this->eof ) {
// Seek to end of archive file minus 1 byte
@fseek( $this->file_handle, 1, SEEK_END );
// Read 1 character
@fgetc( $this->file_handle );
} else {
// Get file header data from the block
if ( ( $data = $this->get_data_from_block( $block ) ) ) {
// Set file name
$file_name = $data['filename'];
// Set file size
$file_size = $data['size'];
// Set file mtime
$file_mtime = $data['mtime'];
// Set file path
$file_path = $data['path'];
// Set should exclude file
$should_exclude_file = false;
// Should we skip this file by name?
for ( $i = 0; $i < count( $exclude_files ); $i++ ) {
if ( strpos( $file_name . DIRECTORY_SEPARATOR, ai1wm_replace_forward_slash_with_directory_separator( $exclude_files[ $i ] ) . DIRECTORY_SEPARATOR ) === 0 ) {
$should_exclude_file = true;
break;
}
}
// Should we skip this file by extension?
for ( $i = 0; $i < count( $exclude_extensions ); $i++ ) {
if ( strrpos( $file_name, $exclude_extensions[ $i ] ) === strlen( $file_name ) - strlen( $exclude_extensions[ $i ] ) ) {
$should_exclude_file = true;
break;
}
}
// Do we have a match?
if ( $should_exclude_file === false ) {
// Replace extract paths
for ( $i = 0; $i < count( $old_paths ); $i++ ) {
if ( strpos( $file_path . DIRECTORY_SEPARATOR, ai1wm_replace_forward_slash_with_directory_separator( $old_paths[ $i ] ) . DIRECTORY_SEPARATOR ) === 0 ) {
$file_name = substr_replace( $file_name, ai1wm_replace_forward_slash_with_directory_separator( $new_paths[ $i ] ), 0, strlen( ai1wm_replace_forward_slash_with_directory_separator( $old_paths[ $i ] ) ) );
$file_path = substr_replace( $file_path, ai1wm_replace_forward_slash_with_directory_separator( $new_paths[ $i ] ), 0, strlen( ai1wm_replace_forward_slash_with_directory_separator( $old_paths[ $i ] ) ) );
break;
}
}
// Escape Windows directory separator in file path
if ( path_is_absolute( $file_path ) ) {
$file_path = ai1wm_escape_windows_directory_separator( $file_path );
} else {
$file_path = ai1wm_escape_windows_directory_separator( $location . DIRECTORY_SEPARATOR . $file_path );
}
// Escape Windows directory separator in file name
if ( path_is_absolute( $file_name ) ) {
$file_name = ai1wm_escape_windows_directory_separator( $file_name );
} else {
$file_name = ai1wm_escape_windows_directory_separator( $location . DIRECTORY_SEPARATOR . $file_name );
}
// Check if location doesn't exist, then create it
if ( false === is_dir( $file_path ) ) {
@mkdir( $file_path, $this->get_permissions_for_directory(), true );
}
$file_written = 0;
// We have a match, let's extract the file
if ( ( $completed = $this->extract_to( $file_name, $file_size, $file_mtime, $file_written, $file_offset ) ) ) {
$file_offset = 0;
}
} else {
// We don't have a match, skip file content
if ( @fseek( $this->file_handle, $file_size, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $file_size ) );
}
}
}
}
}
return $completed;
}
/**
* Extract specific files from archive
*
* @param string $location Location where to extract files
* @param array $include_files Include files by name
* @param array $exclude_files Exclude files by name
* @param array $exclude_extensions Exclude files by extension
* @param int $file_written File written (in bytes)
* @param int $file_offset File offset (in bytes)
*
* @throws \Ai1wm_Not_Directory_Exception
* @throws \Ai1wm_Not_Seekable_Exception
*
* @return bool
*/
public function extract_by_files_array( $location, $include_files = array(), $exclude_files = array(), $exclude_extensions = array(), &$file_written = 0, &$file_offset = 0 ) {
if ( false === is_dir( $location ) ) {
throw new Ai1wm_Not_Directory_Exception( sprintf( __( 'Location is not a directory: %s', AI1WM_PLUGIN_NAME ), $location ) );
}
// Replace forward slash with current directory separator in location
$location = ai1wm_replace_forward_slash_with_directory_separator( $location );
// Flag to hold if file data has been processed
$completed = true;
// Start time
$start = microtime( true );
// Seek to file offset to archive file
if ( $file_offset > 0 ) {
if ( @fseek( $this->file_handle, - $file_offset - 4377, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, - $file_offset - 4377 ) );
}
}
// We read until we reached the end of the file, or the files we were looking for were found
while ( ( $block = @fread( $this->file_handle, 4377 ) ) ) {
// We reached end of file, set the pointer to the end of the file so that feof returns true
if ( $block === $this->eof ) {
// Seek to end of archive file minus 1 byte
@fseek( $this->file_handle, 1, SEEK_END );
// Read 1 character
@fgetc( $this->file_handle );
} else {
// Get file header data from the block
if ( ( $data = $this->get_data_from_block( $block ) ) ) {
// Set file name
$file_name = $data['filename'];
// Set file size
$file_size = $data['size'];
// Set file mtime
$file_mtime = $data['mtime'];
// Set file path
$file_path = $data['path'];
// Set should include file
$should_include_file = false;
// Should we extract this file by name?
for ( $i = 0; $i < count( $include_files ); $i++ ) {
if ( strpos( $file_name . DIRECTORY_SEPARATOR, ai1wm_replace_forward_slash_with_directory_separator( $include_files[ $i ] ) . DIRECTORY_SEPARATOR ) === 0 ) {
$should_include_file = true;
break;
}
}
// Should we skip this file name?
for ( $i = 0; $i < count( $exclude_files ); $i++ ) {
if ( strpos( $file_name . DIRECTORY_SEPARATOR, ai1wm_replace_forward_slash_with_directory_separator( $exclude_files[ $i ] ) . DIRECTORY_SEPARATOR ) === 0 ) {
$should_include_file = false;
break;
}
}
// Should we skip this file by extension?
for ( $i = 0; $i < count( $exclude_extensions ); $i++ ) {
if ( strrpos( $file_name, $exclude_extensions[ $i ] ) === strlen( $file_name ) - strlen( $exclude_extensions[ $i ] ) ) {
$should_include_file = false;
break;
}
}
// Do we have a match?
if ( $should_include_file === true ) {
// Escape Windows directory separator in file path
$file_path = ai1wm_escape_windows_directory_separator( $location . DIRECTORY_SEPARATOR . $file_path );
// Escape Windows directory separator in file name
$file_name = ai1wm_escape_windows_directory_separator( $location . DIRECTORY_SEPARATOR . $file_name );
// Check if location doesn't exist, then create it
if ( false === is_dir( $file_path ) ) {
@mkdir( $file_path, $this->get_permissions_for_directory(), true );
}
$file_written = 0;
// We have a match, let's extract the file and remove it from the array
if ( ( $completed = $this->extract_to( $file_name, $file_size, $file_mtime, $file_written, $file_offset ) ) ) {
$file_offset = 0;
}
} else {
// We don't have a match, skip file content
if ( @fseek( $this->file_handle, $file_size, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $file_size ) );
}
}
// Time elapsed
if ( ( $timeout = apply_filters( 'ai1wm_completed_timeout', 10 ) ) ) {
if ( ( microtime( true ) - $start ) > $timeout ) {
$completed = false;
break;
}
}
}
}
}
return $completed;
}
/**
* Extract file to
*
* @param string $file_name File name
* @param array $file_size File size (in bytes)
* @param array $file_mtime File modified time (in seconds)
* @param int $file_written File written (in bytes)
* @param int $file_offset File offset (in bytes)
*
* @throws \Ai1wm_Not_Seekable_Exception
* @throws \Ai1wm_Not_Readable_Exception
* @throws \Ai1wm_Quota_Exceeded_Exception
*
* @return bool
*/
private function extract_to( $file_name, $file_size, $file_mtime, &$file_written = 0, &$file_offset = 0 ) {
global $ai1wm_params;
$file_written = 0;
// Flag to hold if file data has been processed
$completed = true;
// Start time
$start = microtime( true );
// Seek to file offset to archive file
if ( $file_offset > 0 ) {
if ( @fseek( $this->file_handle, $file_offset, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $file_size ) );
}
}
// Set file size
$file_size -= $file_offset;
// Should the extract overwrite the file if it exists? (fopen may return null for quarantined files)
if ( ( $file_handle = @fopen( $file_name, ( $file_offset === 0 ? 'wb' : 'ab' ) ) ) ) {
$file_bytes = 0;
// Is the filesize more than 0 bytes?
while ( $file_size > 0 ) {
// Read the file in chunks of 512KB
$chunk_size = $file_size > 512000 ? 512000 : $file_size;
if ( ! empty( $ai1wm_params['decryption_password'] ) && basename( $file_name ) !== 'package.json' ) {
if ( $file_size > 512000 ) {
$chunk_size += ai1wm_crypt_iv_length() * 2;
$chunk_size = $chunk_size > $file_size ? $file_size : $chunk_size;
}
}
// Read data chunk by chunk from archive file
if ( $chunk_size > 0 ) {
$file_content = null;
// Read the file in chunks of 512KB from archiver
if ( ( $file_content = @fread( $this->file_handle, $chunk_size ) ) === false ) {
throw new Ai1wm_Not_Readable_Exception( sprintf( __( 'Unable to read content from file. File: %s', AI1WM_PLUGIN_NAME ), $this->file_name ) );
}
// Remove the amount of bytes we read
$file_size -= $chunk_size;
if ( ! empty( $ai1wm_params['decryption_password'] ) && basename( $file_name ) !== 'package.json' ) {
$file_content = ai1wm_decrypt_string( $file_content, $ai1wm_params['decryption_password'], $file_name );
}
// Write file contents
if ( ( $file_bytes = @fwrite( $file_handle, $file_content ) ) !== false ) {
if ( strlen( $file_content ) !== $file_bytes ) {
throw new Ai1wm_Quota_Exceeded_Exception( sprintf( __( 'Out of disk space. Unable to write content to file. File: %s', AI1WM_PLUGIN_NAME ), $file_name ) );
}
}
// Set file written
$file_written += $chunk_size;
}
// Time elapsed
if ( ( $timeout = apply_filters( 'ai1wm_completed_timeout', 10 ) ) ) {
if ( ( microtime( true ) - $start ) > $timeout ) {
$completed = false;
break;
}
}
}
// Set file offset
$file_offset += $file_written;
// Close the handle
@fclose( $file_handle );
// Let's apply last modified date
@touch( $file_name, $file_mtime );
// All files should chmoded to 644
@chmod( $file_name, $this->get_permissions_for_file() );
} else {
// We don't have file permissions, skip file content
if ( @fseek( $this->file_handle, $file_size, SEEK_CUR ) === -1 ) {
throw new Ai1wm_Not_Seekable_Exception( sprintf( __( 'Unable to seek to offset of file. File: %s Offset: %d', AI1WM_PLUGIN_NAME ), $this->file_name, $file_size ) );
}
}
return $completed;
}
/**
* Get file header data from the block
*
* @param string $block Binary file header
*
* @return array
*/
private function get_data_from_block( $block ) {
$data = false;
// prepare our array keys to unpack
$format = array(
$this->block_format[0] . 'filename/',
$this->block_format[1] . 'size/',
$this->block_format[2] . 'mtime/',
$this->block_format[3] . 'path',
);
$format = implode( '', $format );
// Unpack file header data
if ( ( $data = unpack( $format, $block ) ) ) {
// Set file details
$data['filename'] = trim( $data['filename'] );
$data['size'] = trim( $data['size'] );
$data['mtime'] = trim( $data['mtime'] );
$data['path'] = trim( $data['path'] );
// Set file name
$data['filename'] = ( $data['path'] === '.' ? $data['filename'] : $data['path'] . DIRECTORY_SEPARATOR . $data['filename'] );
// Set file path
$data['path'] = ( $data['path'] === '.' ? '' : $data['path'] );
// Replace forward slash with current directory separator in file name
$data['filename'] = ai1wm_replace_forward_slash_with_directory_separator( $data['filename'] );
// Replace forward slash with current directory separator in file path
$data['path'] = ai1wm_replace_forward_slash_with_directory_separator( $data['path'] );
}
return $data;
}
/**
* Check if file has reached end of file
* Returns true if file has reached eof, false otherwise
*
* @return bool
*/
public function has_reached_eof() {
return @feof( $this->file_handle );
}
/**
* Check if file has reached end of file
* Returns true if file has NOT reached eof, false otherwise
*
* @return bool
*/
public function has_not_reached_eof() {
return ! @feof( $this->file_handle );
}
/**
* Get directory permissions
*
* @return int
*/
public function get_permissions_for_directory() {
if ( defined( 'FS_CHMOD_DIR' ) ) {
return FS_CHMOD_DIR;
}
return 0755;
}
/**
* Get file permissions
*
* @return int
*/
public function get_permissions_for_file() {
if ( defined( 'FS_CHMOD_FILE' ) ) {
return FS_CHMOD_FILE;
}
return 0644;
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
if ( defined( 'WP_CLI' ) ) {
class Ai1wm_WP_CLI_Command extends WP_CLI_Command {
public function __invoke() {
if ( is_multisite() ) {
WP_CLI::error_multi_line(
array(
__( 'WordPress Multisite is supported via our All-in-One WP Migration Multisite Extension.', AI1WM_PLUGIN_NAME ),
__( 'You can get a copy of it here: https://servmask.com/products/multisite-extension', AI1WM_PLUGIN_NAME ),
)
);
exit;
}
WP_CLI::error_multi_line(
array(
__( 'WordPress CLI is supported via our All-in-One WP Migration Unlimited Extension.', AI1WM_PLUGIN_NAME ),
__( 'You can get a copy of it here: https://servmask.com/products/unlimited-extension', AI1WM_PLUGIN_NAME ),
)
);
exit;
}
}
}

View File

@ -0,0 +1,140 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Cron {
/**
* Schedules a hook which will be executed by the WordPress
* actions core on a specific interval
*
* @param string $hook Event hook
* @param string $recurrence How often the event should reoccur
* @param integer $timestamp Preferred timestamp (when the event shall be run)
* @param array $args Arguments to pass to the hook function(s)
* @return mixed
*/
public static function add( $hook, $recurrence, $timestamp, $args = array() ) {
$schedules = wp_get_schedules();
// Schedule event
if ( isset( $schedules[ $recurrence ] ) && ( $current = $schedules[ $recurrence ] ) ) {
if ( $timestamp <= ( $current_timestamp = time() ) ) {
while ( $timestamp <= $current_timestamp ) {
$timestamp += $current['interval'];
}
}
return wp_schedule_event( $timestamp, $recurrence, $hook, $args );
}
}
/**
* Un-schedules all previously-scheduled cron jobs using a particular
* hook name or a specific combination of hook name and arguments.
*
* @param string $hook Event hook
* @return boolean
*/
public static function clear( $hook ) {
$cron = get_option( AI1WM_CRON, array() );
if ( empty( $cron ) ) {
return false;
}
foreach ( $cron as $timestamp => $hooks ) {
if ( isset( $hooks[ $hook ] ) ) {
unset( $cron[ $timestamp ][ $hook ] );
// Unset empty timestamps
if ( empty( $cron[ $timestamp ] ) ) {
unset( $cron[ $timestamp ] );
}
}
}
return update_option( AI1WM_CRON, $cron );
}
/**
* Checks whether cronjob already exists
*
* @param string $hook Event hook
* @param array $args Event callback arguments
* @return boolean
*/
public static function exists( $hook, $args = array() ) {
$cron = get_option( AI1WM_CRON, array() );
if ( empty( $cron ) ) {
return false;
}
foreach ( $cron as $timestamp => $hooks ) {
if ( empty( $args ) ) {
if ( isset( $hooks[ $hook ] ) ) {
return true;
}
} else {
if ( isset( $hooks[ $hook ][ md5( serialize( $args ) ) ] ) ) {
return true;
}
}
}
return false;
}
/**
* Deletes cron event(s) if it exists
*
* @param string $hook Event hook
* @param array $args Event callback arguments
* @return boolean
*/
public static function delete( $hook, $args = array() ) {
$cron = get_option( AI1WM_CRON, array() );
if ( empty( $cron ) ) {
return false;
}
$key = md5( serialize( $args ) );
foreach ( $cron as $timestamp => $hooks ) {
if ( isset( $cron[ $timestamp ][ $hook ][ $key ] ) ) {
unset( $cron[ $timestamp ][ $hook ][ $key ] );
}
if ( isset( $cron[ $timestamp ][ $hook ] ) && empty( $cron[ $timestamp ][ $hook ] ) ) {
unset( $cron[ $timestamp ][ $hook ] );
}
if ( empty( $cron[ $timestamp ] ) ) {
unset( $cron[ $timestamp ] );
}
}
return update_option( AI1WM_CRON, $cron );
}
}

View File

@ -0,0 +1,140 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Database_Mysql extends Ai1wm_Database {
/**
* Run MySQL query
*
* @param string $input SQL query
* @return mixed
*/
public function query( $input ) {
if ( ! ( $result = mysql_query( $input, $this->wpdb->dbh ) ) ) {
$mysql_errno = 0;
// Get MySQL error code
if ( ! empty( $this->wpdb->dbh ) ) {
if ( is_resource( $this->wpdb->dbh ) ) {
$mysql_errno = mysql_errno( $this->wpdb->dbh );
} else {
$mysql_errno = 2006;
}
}
// MySQL server has gone away, try to reconnect
if ( empty( $this->wpdb->dbh ) || 2006 === $mysql_errno ) {
if ( ! $this->wpdb->check_connection( false ) ) {
throw new Ai1wm_Database_Exception( __( 'Error reconnecting to the database. <a href="https://help.servmask.com/knowledgebase/mysql-error-reconnecting/" target="_blank">Technical details</a>', AI1WM_PLUGIN_NAME ), 503 );
}
$result = mysql_query( $input, $this->wpdb->dbh );
}
}
return $result;
}
/**
* Escape string input for mysql query
*
* @param string $input String to escape
* @return string
*/
public function escape( $input ) {
return mysql_real_escape_string( $input, $this->wpdb->dbh );
}
/**
* Return the error code for the most recent function call
*
* @return integer
*/
public function errno() {
return mysql_errno( $this->wpdb->dbh );
}
/**
* Return a string description of the last error
*
* @return string
*/
public function error() {
return mysql_error( $this->wpdb->dbh );
}
/**
* Return server version
*
* @return string
*/
public function version() {
return mysql_get_server_info( $this->wpdb->dbh );
}
/**
* Return the result from MySQL query as associative array
*
* @param resource $result MySQL resource
* @return array
*/
public function fetch_assoc( $result ) {
return mysql_fetch_assoc( $result );
}
/**
* Return the result from MySQL query as row
*
* @param resource $result MySQL resource
* @return array
*/
public function fetch_row( $result ) {
return mysql_fetch_row( $result );
}
/**
* Return the number for rows from MySQL results
*
* @param resource $result MySQL resource
* @return integer
*/
public function num_rows( $result ) {
return mysql_num_rows( $result );
}
/**
* Free MySQL result memory
*
* @param resource $result MySQL resource
* @return boolean
*/
public function free_result( $result ) {
return mysql_free_result( $result );
}
}

View File

@ -0,0 +1,145 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Database_Mysqli extends Ai1wm_Database {
/**
* Run MySQL query
*
* @param string $input SQL query
* @return mixed
*/
public function query( $input ) {
if ( ! mysqli_real_query( $this->wpdb->dbh, $input ) ) {
$mysqli_errno = 0;
// Get MySQL error code
if ( ! empty( $this->wpdb->dbh ) ) {
if ( $this->wpdb->dbh instanceof mysqli ) {
$mysqli_errno = mysqli_errno( $this->wpdb->dbh );
} else {
$mysqli_errno = 2006;
}
}
// MySQL server has gone away, try to reconnect
if ( empty( $this->wpdb->dbh ) || 2006 === $mysqli_errno ) {
if ( ! $this->wpdb->check_connection( false ) ) {
throw new Ai1wm_Database_Exception( __( 'Error reconnecting to the database. <a href="https://help.servmask.com/knowledgebase/mysql-error-reconnecting/" target="_blank">Technical details</a>', AI1WM_PLUGIN_NAME ), 503 );
}
mysqli_real_query( $this->wpdb->dbh, $input );
}
}
// Copy results from the internal mysqlnd buffer into the PHP variables fetched
if ( defined( 'MYSQLI_STORE_RESULT_COPY_DATA' ) ) {
return mysqli_store_result( $this->wpdb->dbh, MYSQLI_STORE_RESULT_COPY_DATA );
}
return mysqli_store_result( $this->wpdb->dbh );
}
/**
* Escape string input for mysql query
*
* @param string $input String to escape
* @return string
*/
public function escape( $input ) {
return mysqli_real_escape_string( $this->wpdb->dbh, $input );
}
/**
* Return the error code for the most recent function call
*
* @return integer
*/
public function errno() {
return mysqli_errno( $this->wpdb->dbh );
}
/**
* Return a string description of the last error
*
* @return string
*/
public function error() {
return mysqli_error( $this->wpdb->dbh );
}
/**
* Return server version
*
* @return string
*/
public function version() {
return mysqli_get_server_info( $this->wpdb->dbh );
}
/**
* Return the result from MySQL query as associative array
*
* @param resource $result MySQL resource
* @return array
*/
public function fetch_assoc( $result ) {
return mysqli_fetch_assoc( $result );
}
/**
* Return the result from MySQL query as row
*
* @param resource $result MySQL resource
* @return array
*/
public function fetch_row( $result ) {
return mysqli_fetch_row( $result );
}
/**
* Return the number for rows from MySQL results
*
* @param resource $result MySQL resource
* @return integer
*/
public function num_rows( $result ) {
return mysqli_num_rows( $result );
}
/**
* Free MySQL result memory
*
* @param resource $result MySQL resource
* @return boolean
*/
public function free_result( $result ) {
return mysqli_free_result( $result );
}
}

View File

@ -0,0 +1,184 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Database_Utility {
/**
* Get MySQLClient to be used for DB manipulation
*
* @return Ai1wm_Database
*/
public static function create_client() {
global $wpdb;
if ( PHP_MAJOR_VERSION >= 7 ) {
return new Ai1wm_Database_Mysqli( $wpdb );
}
if ( empty( $wpdb->use_mysqli ) ) {
return new Ai1wm_Database_Mysql( $wpdb );
}
return new Ai1wm_Database_Mysqli( $wpdb );
}
/**
* Replace all occurrences of the search string with the replacement string.
* This function is case-sensitive.
*
* @param array $from List of string we're looking to replace.
* @param array $to What we want it to be replaced with.
* @param string $data Data to replace.
* @return mixed The original string with all elements replaced as needed.
*/
public static function replace_values( $from = array(), $to = array(), $data = '' ) {
if ( ! empty( $from ) && ! empty( $to ) ) {
return strtr( $data, array_combine( $from, $to ) );
}
return $data;
}
/**
* Take a serialized array and unserialize it replacing elements as needed and
* unserializing any subordinate arrays and performing the replace on those too.
* This function is case-sensitive.
*
* @param array $from List of string we're looking to replace.
* @param array $to What we want it to be replaced with.
* @param mixed $data Used to pass any subordinate arrays back to in.
* @param bool $serialized Does the array passed via $data need serializing.
* @return mixed The original array with all elements replaced as needed.
*/
public static function replace_serialized_values( $from = array(), $to = array(), $data = '', $serialized = false ) {
try {
// Some unserialized data cannot be re-serialized eg. SimpleXMLElements
if ( is_serialized( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
$data = self::replace_serialized_values( $from, $to, $unserialized, true );
} elseif ( is_array( $data ) ) {
$tmp = array();
foreach ( $data as $key => $value ) {
$tmp[ $key ] = self::replace_serialized_values( $from, $to, $value, false );
}
$data = $tmp;
unset( $tmp );
} elseif ( is_object( $data ) ) {
if ( ! ( $data instanceof __PHP_Incomplete_Class ) ) {
$tmp = $data;
$props = get_object_vars( $data );
foreach ( $props as $key => $value ) {
if ( ! empty( $tmp->$key ) ) {
$tmp->$key = self::replace_serialized_values( $from, $to, $value, false );
}
}
$data = $tmp;
unset( $tmp );
}
} else {
if ( is_string( $data ) ) {
if ( ! empty( $from ) && ! empty( $to ) ) {
$data = strtr( $data, array_combine( $from, $to ) );
}
}
}
if ( $serialized ) {
return serialize( $data );
}
} catch ( Exception $e ) {
}
return $data;
}
/**
* Escape MySQL special characters
*
* @param string $data Data to escape
* @return string
*/
public static function escape_mysql( $data ) {
return strtr(
$data,
array_combine(
array( "\x00", "\n", "\r", '\\', "'", '"', "\x1a" ),
array( '\\0', '\\n', '\\r', '\\\\', "\\'", '\\"', '\\Z' )
)
);
}
/**
* Unescape MySQL special characters
*
* @param string $data Data to unescape
* @return string
*/
public static function unescape_mysql( $data ) {
return strtr(
$data,
array_combine(
array( '\\0', '\\n', '\\r', '\\\\', "\\'", '\\"', '\\Z' ),
array( "\x00", "\n", "\r", '\\', "'", '"', "\x1a" )
)
);
}
/**
* Encode base64 characters
*
* @param string $data Data to encode
* @return string
*/
public static function base64_encode( $data ) {
return base64_encode( $data );
}
/**
* Encode base64 characters
*
* @param string $data Data to decode
* @return string
*/
public static function base64_decode( $data ) {
return base64_decode( $data );
}
/**
* Validate base64 data
*
* @param string $data Data to validate
* @return boolean
*/
public static function base64_validate( $data ) {
return base64_encode( base64_decode( $data ) ) === $data;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Directory {
/**
* Create directory (recursively)
*
* @param string $path Path to the directory
* @return boolean
*/
public static function create( $path ) {
if ( @is_dir( $path ) ) {
return true;
}
return @mkdir( $path, 0777, true );
}
/**
* Delete directory (recursively)
*
* @param string $path Path to the directory
* @return boolean
*/
public static function delete( $path ) {
if ( @is_dir( $path ) ) {
try {
// Iterate over directory
$iterator = new Ai1wm_Recursive_Directory_Iterator( $path );
// Recursively iterate over directory
$iterator = new Ai1wm_Recursive_Iterator_Iterator( $iterator, RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
// Remove files and directories
foreach ( $iterator as $item ) {
if ( $item->isDir() ) {
@rmdir( $item->getPathname() );
} else {
@unlink( $item->getPathname() );
}
}
} catch ( Exception $e ) {
}
return @rmdir( $path );
}
return false;
}
}

View File

@ -0,0 +1,75 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_File_Htaccess {
/**
* Create .htaccess file (ServMask)
*
* @param string $path Path to file
* @return boolean
*/
public static function create( $path ) {
return Ai1wm_File::create(
$path,
implode(
PHP_EOL,
array(
'<IfModule mod_mime.c>',
'AddType application/octet-stream .wpress',
'</IfModule>',
'<IfModule mod_dir.c>',
'DirectoryIndex index.php',
'</IfModule>',
'<IfModule mod_autoindex.c>',
'Options -Indexes',
'</IfModule>',
)
)
);
}
/**
* Create .htaccess file (LiteSpeed)
*
* @param string $path Path to file
* @return boolean
*/
public static function litespeed( $path ) {
return Ai1wm_File::create_with_markers(
$path,
'LiteSpeed',
array(
'<IfModule Litespeed>',
'SetEnv noabort 1',
'</IfModule>',
)
);
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_File_Index {
/**
* Create index file
*
* @param string $path Path to file
* @return boolean
*/
public static function create( $path ) {
return Ai1wm_File::create( $path, 'Kangaroos cannot jump here' );
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_File_Robots {
/**
* Create robots.txt file
*
* @param string $path Path to file
* @return boolean
*/
public static function create( $path ) {
return Ai1wm_File::create(
$path,
implode(
PHP_EOL,
array(
'User-agent: *',
'Disallow: /ai1wm-backups/',
'Disallow: /wp-content/ai1wm-backups/',
)
)
);
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_File_Webconfig {
/**
* Create web.config file
*
* @param string $path Path to file
* @return boolean
*/
public static function create( $path ) {
return Ai1wm_File::create(
$path,
implode(
PHP_EOL,
array(
'<configuration>',
'<system.webServer>',
'<staticContent>',
'<mimeMap fileExtension=".wpress" mimeType="application/octet-stream" />',
'</staticContent>',
'<defaultDocument>',
'<files>',
'<add value="index.php" />',
'</files>',
'</defaultDocument>',
'<directoryBrowse enabled="false" />',
'</system.webServer>',
'</configuration>',
)
)
);
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_File {
/**
* Create a file with content
*
* @param string $path Path to the file
* @param string $content Content of the file
* @return boolean
*/
public static function create( $path, $content ) {
if ( ! @file_exists( $path ) ) {
if ( ! @is_writable( dirname( $path ) ) ) {
return false;
}
if ( ! @touch( $path ) ) {
return false;
}
} elseif ( ! @is_writable( $path ) ) {
return false;
}
// No changes were added
if ( function_exists( 'md5_file' ) ) {
if ( @md5_file( $path ) === md5( $content ) ) {
return true;
}
}
$is_written = false;
if ( ( $handle = @fopen( $path, 'w' ) ) !== false ) {
if ( @fwrite( $handle, $content ) !== false ) {
$is_written = true;
}
@fclose( $handle );
}
return $is_written;
}
/**
* Create a file with marker and content
*
* @param string $path Path to the file
* @param string $marker Name of the marker
* @param string $content Content of the file
* @return boolean
*/
public static function create_with_markers( $path, $marker, $content ) {
return @insert_with_markers( $path, $marker, $content );
}
/**
* Delete a file by path
*
* @param string $path Path to the file
* @return boolean
*/
public static function delete( $path ) {
if ( ! @file_exists( $path ) ) {
return false;
}
return @unlink( $path );
}
}

View File

@ -0,0 +1,72 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Recursive_Exclude_Filter extends RecursiveFilterIterator {
protected $exclude = array();
public function __construct( RecursiveIterator $iterator, $exclude = array() ) {
parent::__construct( $iterator );
if ( is_array( $exclude ) ) {
foreach ( $exclude as $path ) {
$this->exclude[] = ai1wm_replace_forward_slash_with_directory_separator( $path );
}
}
}
#[\ReturnTypeWillChange]
public function accept() {
if ( in_array( ai1wm_replace_forward_slash_with_directory_separator( $this->getInnerIterator()->getSubPathname() ), $this->exclude ) ) {
return false;
}
if ( in_array( ai1wm_replace_forward_slash_with_directory_separator( $this->getInnerIterator()->getPathname() ), $this->exclude ) ) {
return false;
}
if ( in_array( ai1wm_replace_forward_slash_with_directory_separator( $this->getInnerIterator()->getPath() ), $this->exclude ) ) {
return false;
}
if ( strpos( $this->getInnerIterator()->getSubPathname(), "\n" ) !== false ) {
return false;
}
if ( strpos( $this->getInnerIterator()->getSubPathname(), "\r" ) !== false ) {
return false;
}
return true;
}
#[\ReturnTypeWillChange]
public function getChildren() {
return new self( $this->getInnerIterator()->getChildren(), $this->exclude );
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Recursive_Extension_Filter extends RecursiveFilterIterator {
protected $include = array();
public function __construct( RecursiveIterator $iterator, $include = array() ) {
parent::__construct( $iterator );
if ( is_array( $include ) ) {
$this->include = $include;
}
}
#[\ReturnTypeWillChange]
public function accept() {
if ( $this->getInnerIterator()->isFile() ) {
if ( ! in_array( pathinfo( $this->getInnerIterator()->getFilename(), PATHINFO_EXTENSION ), $this->include ) ) {
return false;
}
}
return true;
}
#[\ReturnTypeWillChange]
public function getChildren() {
return new self( $this->getInnerIterator()->getChildren(), $this->include );
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Recursive_Directory_Iterator extends RecursiveDirectoryIterator {
public function __construct( $path ) {
parent::__construct( $path );
// Skip current and parent directory
$this->skipdots();
}
#[\ReturnTypeWillChange]
public function rewind() {
parent::rewind();
// Skip current and parent directory
$this->skipdots();
}
#[\ReturnTypeWillChange]
public function next() {
parent::next();
// Skip current and parent directory
$this->skipdots();
}
/**
* Returns whether current entry is a directory and not '.' or '..'
*
* Explicitly set allow links flag, because RecursiveDirectoryIterator::FOLLOW_SYMLINKS
* is not supported by <= PHP 5.3.0
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function hasChildren( $allow_links = true ) {
return parent::hasChildren( $allow_links );
}
protected function skipdots() {
while ( $this->isDot() ) {
parent::next();
}
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Copyright (C) 2014-2023 ServMask Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
* ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
* ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
* ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
* ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
* ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
*/
if ( ! defined( 'ABSPATH' ) ) {
die( 'Kangaroos cannot jump here' );
}
class Ai1wm_Recursive_Iterator_Iterator extends RecursiveIteratorIterator {
}