Initial commit
This commit is contained in:
commit
f9f65dc84d
23 files changed
+5074
No files matched your search
@@ -0,0 +1,64 @@
|
|||||||
|
#sistContainer {
|
||||||
|
margin-right: 310px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sistContent {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
min-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sistSidebar {
|
||||||
|
float: right;
|
||||||
|
margin-right: -310px;
|
||||||
|
width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate page */
|
||||||
|
|
||||||
|
.export-log {
|
||||||
|
height: 200px;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid #DFDFDF;
|
||||||
|
color: #000;
|
||||||
|
background: #fff;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.export-log pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 3px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Options page */
|
||||||
|
|
||||||
|
.tab-pane, tr.delivery-method {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-pane.active, tr.delivery-method.active {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
|
||||||
|
select:disabled, select.disabled {
|
||||||
|
border-color: rgba(222,222,222,.75);
|
||||||
|
background: rgba(255,255,255,.5);
|
||||||
|
color: rgba(51,51,51,.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-block {
|
||||||
|
display: block;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: #737373;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mailchimp Form CSS */
|
||||||
|
|
||||||
|
/* Mailchimp original CSS at:
|
||||||
|
http://cdn-images.mailchimp.com/embedcode/slim-081711.css
|
||||||
|
*/
|
||||||
|
#mc_embed_signup input {border:1px solid #999; -webkit-appearance:none;}
|
||||||
|
#mc_embed_signup input:focus {border-color:#333;}
|
||||||
|
#mc_embed_signup .clear {clear:none; display:inline;}
|
||||||
|
#mc_embed_signup input.email {display:block; padding:8px 0; margin:0 4% 10px 0; text-indent:5px; width:58%; min-width:130px; width:100%;}
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static URL fetcher class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static_Archive_Creator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to the archive directory
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $archive_dir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export log (list of processed urls)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $export_log = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The slug (id) used for the plugin
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $slug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The protocol used for the destination URL
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $destination_scheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The host for the destination URL
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $destination_host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The directory where static files should be saved
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $temp_files_dir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional urls to add to the archive
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $additional_urls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $url URI resource
|
||||||
|
*/
|
||||||
|
public function __construct( $slug, $destination_scheme, $destination_host, $temp_files_dir, $additional_urls ) {
|
||||||
|
$this->slug = $slug;
|
||||||
|
$this->destination_scheme = $destination_scheme;
|
||||||
|
$this->destination_host = $destination_host;
|
||||||
|
$this->temp_files_dir = $temp_files_dir;
|
||||||
|
$this->additional_urls = $additional_urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of URLs in the archive
|
||||||
|
*
|
||||||
|
* @param array $export_log URLs that were successfully added to the archive
|
||||||
|
*/
|
||||||
|
public function get_export_log() {
|
||||||
|
return $this->export_log;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a static version of the site
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function create_archive() {
|
||||||
|
global $blog_id;
|
||||||
|
// TODO: Do ajax calls instead of just running forever and ever
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
// Create archive directory
|
||||||
|
$current_user = wp_get_current_user();
|
||||||
|
$archive_name = join( '-', array( $this->slug, $blog_id, time(), $current_user->user_login ) );
|
||||||
|
$this->archive_dir = trailingslashit( $this->temp_files_dir . $archive_name );
|
||||||
|
|
||||||
|
if ( ! file_exists( $this->archive_dir ) ) {
|
||||||
|
wp_mkdir_p( $this->archive_dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add URLs to queue
|
||||||
|
$origin_url = home_url();
|
||||||
|
$destination_url = $this->destination_scheme . '://' . $this->destination_host;
|
||||||
|
$urls_queue = array_unique( array_merge(
|
||||||
|
array( trailingslashit( $origin_url ) ),
|
||||||
|
// using preg_split to intelligently break at newlines
|
||||||
|
// see: http://stackoverflow.com/questions/1483497/how-to-put-string-in-array-split-by-new-line
|
||||||
|
preg_split( "/\r\n|\n|\r/", $this->additional_urls )
|
||||||
|
) );
|
||||||
|
|
||||||
|
while ( count( $urls_queue ) ) {
|
||||||
|
$current_url = array_shift( $urls_queue );
|
||||||
|
|
||||||
|
$response = Simply_Static_Url_Fetcher::fetch( $current_url );
|
||||||
|
|
||||||
|
// If we get a WP_Error then somehow our request failed (e.g. space in URL)
|
||||||
|
// TODO: Keep a queue of failed urls too
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url_parts = parse_url( $response->url );
|
||||||
|
$path = $url_parts['path'];
|
||||||
|
$is_html = $response->is_html();
|
||||||
|
|
||||||
|
// If we get a 30x redirect...
|
||||||
|
if ( in_array( $response->code, array( 301, 302, 303, 307 ) ) ) {
|
||||||
|
|
||||||
|
$redirect_url = $response->get_redirect_url();
|
||||||
|
|
||||||
|
// WP likes to 301 redirect `/path` to `/path/` -- we want to
|
||||||
|
// check for this and just add the trailing slashed version
|
||||||
|
if ( $redirect_url === trailingslashit( $current_url ) ) {
|
||||||
|
|
||||||
|
$urls_queue = $this->add_url_to_queue( $urls_queue, $redirect_url );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/// convert our potentially relative URL to an absolute URL
|
||||||
|
$redirect_url = sist_relative_to_absolute_url( $redirect_url, $current_url );
|
||||||
|
|
||||||
|
if ( $redirect_url ) {
|
||||||
|
|
||||||
|
// check if this is a local URL
|
||||||
|
if ( sist_is_local_url( $redirect_url ) ) {
|
||||||
|
|
||||||
|
// add the redirected page to the queue
|
||||||
|
$urls_queue = $this->add_url_to_queue( $urls_queue, $redirect_url );
|
||||||
|
// and update the URL
|
||||||
|
$redirect_url = str_replace( $origin_url, $destination_url, $redirect_url );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$view = new Simply_Static_View();
|
||||||
|
|
||||||
|
$content = $view->set_template( 'redirect' )
|
||||||
|
->assign( 'redirect_url', $redirect_url )
|
||||||
|
->render_to_string();
|
||||||
|
|
||||||
|
$this->save_url_to_file( $path, $content, $is_html );
|
||||||
|
|
||||||
|
$this->export_log[] = $current_url;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a 200 for the response code? Move on.
|
||||||
|
// TODO: Keep a queue of failed urls too
|
||||||
|
if ( $response->code != 200 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->export_log[] = $current_url;
|
||||||
|
|
||||||
|
// Fetch all URLs from the page and add them to the queue...
|
||||||
|
$urls = $response->extract_urls();
|
||||||
|
foreach ( $urls as $url ) {
|
||||||
|
$urls_queue = $this->add_url_to_queue( $urls_queue, $url );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the origin URL with the destination URL
|
||||||
|
$response->replace_url( $origin_url, $destination_url );
|
||||||
|
|
||||||
|
// Save the page to our archive
|
||||||
|
$content = $response->body;
|
||||||
|
$this->save_url_to_file( $path, $content, $is_html );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a URL to the processing queue if we haven't already processed it and
|
||||||
|
* if it's not in the queue to be processed
|
||||||
|
*
|
||||||
|
* @param array $urls_queue Queue of URLs to be processed
|
||||||
|
* @param string $url URL to add to the processing queue
|
||||||
|
* @return array Queue of URLs to be processed
|
||||||
|
*/
|
||||||
|
private function add_url_to_queue( $urls_queue, $url ) {
|
||||||
|
if ( ! in_array( $url, $this->export_log ) && ! in_array( $url, $urls_queue ) ) {
|
||||||
|
$urls_queue[] = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $urls_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ZIP file using the archive directory
|
||||||
|
*
|
||||||
|
* @return string|WP_Error $temporary_zip The path to the archive zip file
|
||||||
|
*/
|
||||||
|
public function create_zip() {
|
||||||
|
$temporary_zip = untrailingslashit( $this->archive_dir ) . '.tmp';
|
||||||
|
$zip_archive = new ZipArchive();
|
||||||
|
|
||||||
|
if ( $zip_archive->open( $temporary_zip, ZIPARCHIVE::CREATE ) !== true ) {
|
||||||
|
return new WP_Error( 'create_zip_failed', __( 'Unable to create ZIP archive', $this->slug ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->archive_dir ) );
|
||||||
|
foreach ( $iterator as $file_name => $file_object ) {
|
||||||
|
$base_name = basename( $file_name );
|
||||||
|
|
||||||
|
if ( $base_name != '.' && $base_name != '..' ) {
|
||||||
|
if ( ! $zip_archive->addFile( realpath( $file_name ), str_replace( $this->archive_dir, '', $file_name ) ) ) {
|
||||||
|
return new WP_Error( 'cannot_add_file_to_zip', sprintf( __( "Could not add file: %s", $this->slug ), $file_name ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip_archive->close();
|
||||||
|
$zip_file = untrailingslashit( $this->archive_dir ) . '.zip';
|
||||||
|
rename( $temporary_zip, $zip_file );
|
||||||
|
|
||||||
|
$archive_url = str_replace( plugin_dir_path( dirname( __FILE__ ) ), plugin_dir_url( dirname( __FILE__ ) ), $zip_file );
|
||||||
|
|
||||||
|
return $archive_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish to AWS S3 bucket
|
||||||
|
*
|
||||||
|
* @return boolean|WP_Error
|
||||||
|
*/
|
||||||
|
public function publish_to_s3( $bucket, $aws_access_key_id, $aws_secret_access_key, $aws_s3_region = 'us-east-1', $aws_s3_endpoint = 's3.amazonaws.com' ) {
|
||||||
|
$directory_iterator = new RecursiveDirectoryIterator( $this->archive_dir, RecursiveDirectoryIterator::SKIP_DOTS );
|
||||||
|
$recursive_iterator = new RecursiveIteratorIterator( $directory_iterator, RecursiveIteratorIterator::SELF_FIRST );
|
||||||
|
|
||||||
|
S3::$useExceptions = true;
|
||||||
|
$useSSL = true;
|
||||||
|
$endpoint = $aws_s3_endpoint;
|
||||||
|
if ( preg_match( '#^https://#i', $endpoint ) ) {
|
||||||
|
$useSSL = true;
|
||||||
|
$endpoint = preg_replace( '#^https://#i', '', $endpoint );
|
||||||
|
} elseif ( preg_match( '#^http://#i', $endpoint ) ) {
|
||||||
|
$useSSL = false;
|
||||||
|
$endpoint = preg_replace( '#^http://#i', '', $endpoint );
|
||||||
|
}
|
||||||
|
$endpoint = untrailingslashit( $endpoint );
|
||||||
|
if ( empty( $endpoint ) ) {
|
||||||
|
$endpoint = 's3.amazonaws.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
$s3 = new S3( $aws_access_key_id, $aws_secret_access_key, $useSSL, $endpoint, $aws_s3_region );
|
||||||
|
S3::setRegion( $aws_s3_region );
|
||||||
|
|
||||||
|
foreach ( $recursive_iterator as $item ) {
|
||||||
|
if (!$item->isDir()) {
|
||||||
|
$path = $recursive_iterator->getSubPathName();
|
||||||
|
try {
|
||||||
|
$s3->putObject( S3::inputFile( $item->getRealPath() ), $bucket, $path, S3::ACL_PUBLIC_READ );
|
||||||
|
} catch (any $err) {
|
||||||
|
return new WP_Error( 'cannot_publish_to_s3', sprintf( __( "Could not publish file to S3: %s: %s", $this->slug, $err ), $path ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy static files to a local directory
|
||||||
|
*
|
||||||
|
* @return boolean|WP_Error
|
||||||
|
*/
|
||||||
|
public function copy_static_files( $local_dir ) {
|
||||||
|
$directory_iterator = new RecursiveDirectoryIterator( $this->archive_dir, RecursiveDirectoryIterator::SKIP_DOTS );
|
||||||
|
$recursive_iterator = new RecursiveIteratorIterator( $directory_iterator, RecursiveIteratorIterator::SELF_FIRST );
|
||||||
|
|
||||||
|
foreach ( $recursive_iterator as $item ) {
|
||||||
|
$path = $local_dir . $recursive_iterator->getSubPathName();
|
||||||
|
$success = $item->isDir() ? wp_mkdir_p( $path ) : copy( $item, $path );
|
||||||
|
if ( ! $success ) {
|
||||||
|
return new WP_Error( 'cannot_create_file_or_dir', sprintf( __( "Could not create file or directory: %s", $this->slug ), $path ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete generated static files
|
||||||
|
*
|
||||||
|
* @param $archive_dir The archive directory path
|
||||||
|
* @return boolean|WP_Error
|
||||||
|
*/
|
||||||
|
public function delete_static_files() {
|
||||||
|
$directory_iterator = new RecursiveDirectoryIterator( $this->archive_dir, FilesystemIterator::SKIP_DOTS );
|
||||||
|
$recursive_iterator = new RecursiveIteratorIterator( $directory_iterator, RecursiveIteratorIterator::CHILD_FIRST );
|
||||||
|
|
||||||
|
// recurse through the entire directory and delete all files / subdirectories
|
||||||
|
foreach ( $recursive_iterator as $item ) {
|
||||||
|
$success = $item->isDir() ? rmdir( $item ) : unlink( $item );
|
||||||
|
if ( ! $success ) {
|
||||||
|
return new WP_Error( 'cannot_delete_file_or_dir', sprintf( __( "Could not delete temporary file or directory: %s", $this->slug ), $item ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// must make sure to delete the original directory at the end
|
||||||
|
$success = rmdir( $this->archive_dir );
|
||||||
|
if ( ! $success ) {
|
||||||
|
return new WP_Error( 'cannot_delete_file_or_dir', sprintf( __( "Could not delete temporary file or directory: %s", $this->slug ), $item ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the contents of a page to a file in our archive directory
|
||||||
|
*
|
||||||
|
* @param string $path The relative path for the URL to save
|
||||||
|
* @param string $content The contents of the page we want to save
|
||||||
|
* @param boolean $is_html Is this an html page?
|
||||||
|
* @return boolean $success Did we successfully save the file?
|
||||||
|
*/
|
||||||
|
protected function save_url_to_file( $path, $content, $is_html ) {
|
||||||
|
$path_info = pathinfo( $path && $path != '/' ? $path : 'index.html' );
|
||||||
|
|
||||||
|
// Create file directory if it doesn't exist
|
||||||
|
$file_dir = $this->archive_dir . ( $path_info['dirname'] ? $path_info['dirname'] : '' );
|
||||||
|
if ( empty( $path_info['extension'] ) && $path_info['basename'] == $path_info['filename'] ) {
|
||||||
|
$file_dir .= '/' . $path_info['basename'];
|
||||||
|
$path_info['filename'] = 'index';
|
||||||
|
}
|
||||||
|
if ( ! file_exists( $file_dir ) ) {
|
||||||
|
wp_mkdir_p( $file_dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save file contents
|
||||||
|
$file_extension = ( $is_html || ! isset( $path_info['extension'] ) ) ? 'html' : $path_info['extension'];
|
||||||
|
$file_name = $file_dir . '/' . $path_info['filename'] . '.' . $file_extension;
|
||||||
|
$success = file_put_contents( $file_name, $content );
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static options class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static_Options {
|
||||||
|
/**
|
||||||
|
* Options array
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $options = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines options record in the wp_options table
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $option_key = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs initializion of the options structure
|
||||||
|
*
|
||||||
|
* @param string $option_key The options key name
|
||||||
|
*/
|
||||||
|
public function __construct( $option_key ) {
|
||||||
|
$options = get_option( $option_key );
|
||||||
|
|
||||||
|
if ( false === $options ) {
|
||||||
|
$options = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->options = $options;
|
||||||
|
$this->option_key = $option_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the option identified by $name with the value provided in $value
|
||||||
|
*
|
||||||
|
* @param string $name The option name
|
||||||
|
* @param mixed $value The option value
|
||||||
|
* @return Simply_Static_Options
|
||||||
|
*/
|
||||||
|
public function set( $name, $value ) {
|
||||||
|
$this->options[$name] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value of the option identified by $name
|
||||||
|
*
|
||||||
|
* @param string $name The option name
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function get( $name ) {
|
||||||
|
return array_key_exists( $name, $this->options ) ? $this->options[$name] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the internal options data to the wp_options table using the stored $option_key value as the key
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function save() {
|
||||||
|
return update_option( $this->option_key, $this->options );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static URL extractor class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static_Url_Extractor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following pages were incredibly helpful:
|
||||||
|
* - http://stackoverflow.com/questions/2725156/complete-list-of-html-tag-attributes-which-have-a-url-value
|
||||||
|
* - http://nadeausoftware.com/articles/2008/01/php_tip_how_extract_urls_web_page
|
||||||
|
* - http://php.net/manual/en/book.dom.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @const */
|
||||||
|
protected static $match_elements = array(
|
||||||
|
// HTML
|
||||||
|
'a' => array( 'href', 'urn' ),
|
||||||
|
'base' => array( 'href' ),
|
||||||
|
'form' => array( 'action', 'data' ),
|
||||||
|
'img' => array( 'src', 'usemap', 'longdesc', 'dynsrc', 'lowsrc' ),
|
||||||
|
'link' => array( 'href' ),
|
||||||
|
|
||||||
|
'applet' => array( 'code', 'codebase', 'archive', 'object' ),
|
||||||
|
'area' => array( 'href' ),
|
||||||
|
'body' => array( 'background', 'credits', 'instructions', 'logo' ),
|
||||||
|
'input' => array( 'src', 'usemap', 'dynsrc', 'lowsrc', 'action', 'formaction' ),
|
||||||
|
|
||||||
|
'blockquote' => array( 'cite' ),
|
||||||
|
'del' => array( 'cite' ),
|
||||||
|
'frame' => array( 'longdesc', 'src' ),
|
||||||
|
'head' => array( 'profile' ),
|
||||||
|
'iframe' => array( 'longdesc', 'src' ),
|
||||||
|
'ins' => array( 'cite' ),
|
||||||
|
'object' => array( 'archive', 'classid', 'codebase', 'data', 'usemap' ),
|
||||||
|
'q' => array( 'cite' ),
|
||||||
|
'script' => array( 'src' ),
|
||||||
|
|
||||||
|
'audio' => array( 'src' ),
|
||||||
|
'command' => array( 'icon' ),
|
||||||
|
'embed' => array( 'src', 'code', 'pluginspage' ),
|
||||||
|
'event-source' => array( 'src' ),
|
||||||
|
'html' => array( 'manifest', 'background', 'xmlns' ),
|
||||||
|
'source' => array( 'src' ),
|
||||||
|
'video' => array( 'src', 'poster' ),
|
||||||
|
|
||||||
|
'bgsound' => array( 'src' ),
|
||||||
|
'div' => array( 'href', 'src' ),
|
||||||
|
'ilayer' => array( 'src' ),
|
||||||
|
'table' => array( 'background' ),
|
||||||
|
'td' => array( 'background' ),
|
||||||
|
'th' => array( 'background' ),
|
||||||
|
'layer' => array( 'src' ),
|
||||||
|
'xml' => array( 'src' ),
|
||||||
|
|
||||||
|
'button' => array( 'action', 'formaction' ),
|
||||||
|
'datalist' => array( 'data' ),
|
||||||
|
'select' => array( 'data' ),
|
||||||
|
|
||||||
|
'access' => array( 'path' ),
|
||||||
|
'card' => array( 'onenterforward', 'onenterbackward', 'ontimer' ),
|
||||||
|
'go' => array( 'href' ),
|
||||||
|
'option' => array( 'onpick' ),
|
||||||
|
'template' => array( 'onenterforward', 'onenterbackward', 'ontimer' ),
|
||||||
|
'wml' => array( 'xmlns' )
|
||||||
|
);
|
||||||
|
|
||||||
|
// /** @const */
|
||||||
|
// protected static $match_metas = array(
|
||||||
|
// 'content-base',
|
||||||
|
// 'content-location',
|
||||||
|
// 'referer',
|
||||||
|
// 'location',
|
||||||
|
// 'refresh',
|
||||||
|
// );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL request response
|
||||||
|
*
|
||||||
|
* @var Simply_Static_Url_Response
|
||||||
|
*/
|
||||||
|
protected $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url of the site
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $extracted_urls = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $page_contents The contents of the html/css/etc. page/file
|
||||||
|
* @param string $url The url of the site
|
||||||
|
*/
|
||||||
|
public function __construct( $response ) {
|
||||||
|
$this->response = $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts URLs from the response
|
||||||
|
*
|
||||||
|
* Returns a list of unique URLs from the body of the response. It only
|
||||||
|
* extracts URLs from the same domain, either absolute urls or relative urls
|
||||||
|
* that are then converted to absolute urls.
|
||||||
|
*
|
||||||
|
* Note that no validation is performed on whether the URLs would actually
|
||||||
|
* return a 200/OK response.
|
||||||
|
*
|
||||||
|
* @return array $urls
|
||||||
|
*/
|
||||||
|
public function extract_urls() {
|
||||||
|
|
||||||
|
if ( $this->response->is_html() ) {
|
||||||
|
$this->extract_urls_from_html();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->response->is_css() ) {
|
||||||
|
$this->extract_urls_from_css( $this->response->body );
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique( $this->extracted_urls );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loops through all elements in the DOM to pull out URLs
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function extract_urls_from_html() {
|
||||||
|
|
||||||
|
$doc = new DOMDocument();
|
||||||
|
libxml_use_internal_errors( true );
|
||||||
|
$doc->loadHTML( $this->response->body );
|
||||||
|
libxml_use_internal_errors( false );
|
||||||
|
// get all elements on the page
|
||||||
|
$elements = $doc->getElementsByTagName( '*' );
|
||||||
|
foreach ( $elements as $element ) {
|
||||||
|
$tag_name = $element->tagName;
|
||||||
|
|
||||||
|
if( $tag_name === 'style' ) {
|
||||||
|
$this->extract_urls_from_css( $element->nodeValue );
|
||||||
|
} else {
|
||||||
|
$style_attr_value = $element->getAttribute( 'style' );
|
||||||
|
if ( $style_attr_value !== '' ) {
|
||||||
|
$this->extract_urls_from_css( $style_attr_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( array_key_exists( $tag_name, self::$match_elements ) ) {
|
||||||
|
$match_attributes = self::$match_elements[ $tag_name ];
|
||||||
|
foreach ( $match_attributes as $attribute_name ) {
|
||||||
|
$extracted_url = $element->getAttribute( $attribute_name );
|
||||||
|
$this->add_to_extracted_urls( $extracted_url );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use regex to extract URLs on CSS pages
|
||||||
|
*
|
||||||
|
* URLs in CSS follow three basic patterns:
|
||||||
|
* - @import "common.css" screen, projection;
|
||||||
|
* - @import url("fineprint.css") print;
|
||||||
|
* - background-image: url(image.png);
|
||||||
|
*
|
||||||
|
* URLs are either contained within url(), part of an @import statement,
|
||||||
|
* or both.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function extract_urls_from_css( $text ) {
|
||||||
|
|
||||||
|
$patterns = array( "/url\(\s*[\"']?([^)\"']+)/", // url()
|
||||||
|
"/@import\s+[\"']([^\"']+)/" ); // @import w/o url()
|
||||||
|
|
||||||
|
foreach ( $patterns as $pattern ) {
|
||||||
|
if ( preg_match_all( $pattern, $text, $matches, PREG_PATTERN_ORDER ) === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $matches[1] as $match ) {
|
||||||
|
if ( !empty($match) ) {
|
||||||
|
$this->add_to_extracted_urls( $match );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an extracted URL (relative or absolute) to the extracted URLs array
|
||||||
|
*
|
||||||
|
* Absolute URLs are only added if the scheme/host matches the site it was
|
||||||
|
* extracted from. Relative URLs are converted to absolute URLs before being
|
||||||
|
* added to the array.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function add_to_extracted_urls( $extracted_url ) {
|
||||||
|
$absolute_url = sist_relative_to_absolute_url( $extracted_url, $this->response->url );
|
||||||
|
|
||||||
|
if ( $absolute_url && sist_is_local_url( $absolute_url ) ) {
|
||||||
|
$this->extracted_urls[] = sist_remove_params_and_fragment( $absolute_url );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static URL fetcher class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static_Url_Fetcher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timeout for fetching URLs
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const TIMEOUT = 300;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the URL and return a WP_Error if we get one, otherwise a Response class.
|
||||||
|
*
|
||||||
|
* @return WP_Error|Simply_Static_Url_Response
|
||||||
|
*/
|
||||||
|
public static function fetch( $url ) {
|
||||||
|
// Don't process URLs that don't match the URL of this WordPress installation
|
||||||
|
if ( ! sist_is_local_url( $url ) ) {
|
||||||
|
return new WP_Error( 'attempting_to_fetch_remote_url', sprintf( __( "Attempting to fetch remote URL: %s", Simply_Static::SLUG ), $url ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = wp_remote_get( $url, array(
|
||||||
|
'timeout' => self::TIMEOUT,
|
||||||
|
'sslverify' => false, // not verifying SSL because all calls are local
|
||||||
|
'redirection' => 0 // disable redirection
|
||||||
|
) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
return $response;
|
||||||
|
} else {
|
||||||
|
return new Simply_Static_Url_Response( $url, $response );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static URL response class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Simply_Static_Url_Response {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URI resource
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The headers from the response
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $headers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The body content of the response
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $body = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The code from the response, e.g. 200
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
public $code = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message from the response, e.g. 'OK'
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $message = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param string $url URI resource
|
||||||
|
*/
|
||||||
|
public function __construct( $url, $response ) {
|
||||||
|
$this->url = $url;
|
||||||
|
$this->headers = $response['headers'];
|
||||||
|
$this->body = $response['body'];
|
||||||
|
$this->code = $response['response']['code'];
|
||||||
|
$this->message = $response['response']['message'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content type
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function get_content_type() {
|
||||||
|
return isset( $this->headers['content-type'] ) ? $this->headers['content-type'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if content type is html
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is_html() {
|
||||||
|
return stripos( $this->get_content_type(), 'html' ) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if content type is html
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is_css() {
|
||||||
|
return stripos( $this->get_content_type(), 'css' ) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for a location header (redirection URL). Returns an empty string if
|
||||||
|
* it doesn't find one.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function get_redirect_url() {
|
||||||
|
return isset( $this->headers['location'] ) ? $this->headers['location'] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Removes WordPress-specific meta tags
|
||||||
|
// *
|
||||||
|
// * @return void
|
||||||
|
// */
|
||||||
|
// protected function cleanup() {
|
||||||
|
// if ( $this->is_html() ) {
|
||||||
|
// $response_body = preg_replace( '/<link rel=["\' ](pingback|alternate|EditURI|wlwmanifest|index|profile|prev)["\' ](.*?)>/si', '', $this->get_response_body() );
|
||||||
|
// $response_body = preg_replace( '/<meta name=["\' ]generator["\' ](.*?)>/si', '', $response_body );
|
||||||
|
// $this->set_response_body( $response_body );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the list of unique URLs
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function extract_urls() {
|
||||||
|
$extractor = new Simply_Static_Url_Extractor( $this );
|
||||||
|
return $extractor->extract_urls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces base URL
|
||||||
|
*
|
||||||
|
* @param string $origin_url
|
||||||
|
* @param string $destination_url
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function replace_url( $origin_url, $destination_url ) {
|
||||||
|
if ( $this->is_html() ) {
|
||||||
|
$response_body = str_replace( $origin_url, $destination_url, $this->body );
|
||||||
|
$this->body = $response_body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply Static view class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static_View {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base directory for views
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const DIRECTORY = 'views';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View script extension
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const EXTENSION = '.phtml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View variables array
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $variables = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Absolute path for view
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $path = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template file name to render
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $template = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flashes are quick status messages displayed at the top of the page
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $flashes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs initialization of the absolute path for views
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
// Looking for a basic directory where plugin resides
|
||||||
|
list($plugin_dir) = explode( '/', plugin_basename( __FILE__ ) );
|
||||||
|
|
||||||
|
// making up an absolute path to views directory
|
||||||
|
$path_array = array( WP_PLUGIN_DIR, $plugin_dir, self::DIRECTORY );
|
||||||
|
|
||||||
|
$this->path = implode( '/', $path_array );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a layout that will be used later in render() method.
|
||||||
|
*
|
||||||
|
* @param string $template The template filename, without extension
|
||||||
|
* @return Simply_Static_View
|
||||||
|
*/
|
||||||
|
public function set_layout( $layout ) {
|
||||||
|
$this->layout = trailingslashit( $this->path ) . 'layouts/' . $layout . self::EXTENSION;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a template that will be used later in render() method.
|
||||||
|
*
|
||||||
|
* @param string $template The template filename, without extension
|
||||||
|
* @return Simply_Static_View
|
||||||
|
*/
|
||||||
|
public function set_template( $template ) {
|
||||||
|
$this->template = trailingslashit( $this->path ) . $template . self::EXTENSION;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value of the option identified by $name
|
||||||
|
*
|
||||||
|
* @param string $name The option name
|
||||||
|
* @return mixed|null
|
||||||
|
*/
|
||||||
|
public function __get( $name ) {
|
||||||
|
$value = array_key_exists( $name, $this->variables ) ? $this->variables[$name] : null;
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the view variable identified by $name with the value provided in $value
|
||||||
|
*
|
||||||
|
* @param string $name The variable name
|
||||||
|
* @param mixed $value The variable value
|
||||||
|
* @return Simply_Static_View
|
||||||
|
*/
|
||||||
|
public function __set( $name, $value ) {
|
||||||
|
$this->variables[$name] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the view variable identified by $name with the value provided in $value
|
||||||
|
*
|
||||||
|
* @param string $name The variable name
|
||||||
|
* @param mixed $value The variable value
|
||||||
|
* @return Simply_Static_View
|
||||||
|
*/
|
||||||
|
public function assign( $name, $value ) {
|
||||||
|
return $this->__set( $name, $value );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a flash message to be displayed at the top of the page
|
||||||
|
*
|
||||||
|
* @param string $type The type of message to be displayed
|
||||||
|
* @param string $message The message to be displayed
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add_flash( $type, $message ) {
|
||||||
|
array_push( $this->flashes, array( 'type' => $type, 'message' => $message ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the layout (if available) or template. Checks to make sure that
|
||||||
|
* the file exists and is readable.
|
||||||
|
*
|
||||||
|
* @return string|WP_Error
|
||||||
|
*/
|
||||||
|
private function get_renderable_file() {
|
||||||
|
|
||||||
|
// must include a template
|
||||||
|
if ( ! is_readable( $this->template ) ) {
|
||||||
|
return new WP_Error( 'invalid_template', sprintf( __( "Can't find view template: %s", $this->slug ), $this->template ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// layouts are optional. if no layout provided, use the template by itself.
|
||||||
|
if ( $this->layout ) {
|
||||||
|
if ( ! is_readable( $this->layout ) ) {
|
||||||
|
return new WP_Error( 'invalid_layout', sprintf( __( "Can't find view layout: %s", $this->slug ), $this->layout ) );
|
||||||
|
} else {
|
||||||
|
// the layout should include the template
|
||||||
|
return $this->layout;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $this->template;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Simply_Static's system requirements and add errors as necessary.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function check_for_errors() {
|
||||||
|
|
||||||
|
$errors = Simply_Static::instance()->check_system_requirements();
|
||||||
|
|
||||||
|
foreach ( $errors as $field ) {
|
||||||
|
foreach ( $field as $error ) {
|
||||||
|
$this->add_flash( 'error', $error );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the view script.
|
||||||
|
*
|
||||||
|
* @return Simply_Static_View|WP_Error
|
||||||
|
*/
|
||||||
|
public function render() {
|
||||||
|
|
||||||
|
$this->check_for_errors();
|
||||||
|
|
||||||
|
$file = $this->get_renderable_file();
|
||||||
|
|
||||||
|
if ( is_wp_error( $file ) ) {
|
||||||
|
return $file;
|
||||||
|
} else {
|
||||||
|
include $file;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the view as a string.
|
||||||
|
*
|
||||||
|
* @return string|WP_Error
|
||||||
|
*/
|
||||||
|
public function render_to_string() {
|
||||||
|
|
||||||
|
$file = $this->get_renderable_file();
|
||||||
|
|
||||||
|
if ( is_wp_error( $file ) ) {
|
||||||
|
return $file;
|
||||||
|
} else {
|
||||||
|
ob_start();
|
||||||
|
include $file;
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+420
@@ -0,0 +1,420 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The core plugin class
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
class Simply_Static {
|
||||||
|
/**
|
||||||
|
* Plugin version
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const VERSION = '2.0.0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The slug of the plugin; used in actions, filters, i18n, etc.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const SLUG = 'simply-static-s3';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instance
|
||||||
|
*
|
||||||
|
* @var Simply_Static
|
||||||
|
*/
|
||||||
|
protected static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of the options structure containing all options for this plugin
|
||||||
|
*
|
||||||
|
* @var Simply_Static_Options
|
||||||
|
*/
|
||||||
|
protected $options = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View object
|
||||||
|
*
|
||||||
|
* @var Simply_Static_View
|
||||||
|
*/
|
||||||
|
protected $view = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable usage of "new"
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function __construct() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable cloning of the class
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function __clone() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable unserializing of the class
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __wakeup() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance of the Simply Static plugin
|
||||||
|
*
|
||||||
|
* @return Simply_Static
|
||||||
|
*/
|
||||||
|
public static function instance()
|
||||||
|
{
|
||||||
|
if ( null === self::$instance )
|
||||||
|
{
|
||||||
|
self::$instance = new self();
|
||||||
|
self::$instance->includes();
|
||||||
|
self::$instance->options = new Simply_Static_Options( self::SLUG );
|
||||||
|
self::$instance->view = new Simply_Static_View();
|
||||||
|
|
||||||
|
// Load the text domain for i18n
|
||||||
|
add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
|
||||||
|
// Enqueue admin styles
|
||||||
|
add_action( 'admin_enqueue_scripts', array( self::$instance, 'enqueue_admin_styles' ) );
|
||||||
|
// Enqueue admin scripts
|
||||||
|
add_action( 'admin_enqueue_scripts', array( self::$instance, 'enqueue_admin_scripts' ) );
|
||||||
|
// Add the options page and menu item.
|
||||||
|
add_action( 'admin_menu', array( self::$instance, 'add_plugin_admin_menu' ), 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize singleton instance
|
||||||
|
*
|
||||||
|
* @param string $bootstrap_file
|
||||||
|
* @return Simply_Static
|
||||||
|
*/
|
||||||
|
public static function init( $bootstrap_file )
|
||||||
|
{
|
||||||
|
$instance = self::instance();
|
||||||
|
|
||||||
|
// Activation
|
||||||
|
register_activation_hook( $bootstrap_file, array( $instance, 'activate' ) );
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs activation
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function activate()
|
||||||
|
{
|
||||||
|
// Not installed?
|
||||||
|
if ( null === $this->options->get( 'version' ) ) {
|
||||||
|
$this->options
|
||||||
|
->set( 'version', self::VERSION )
|
||||||
|
->set( 'destination_scheme', sist_get_origin_scheme() )
|
||||||
|
->set( 'destination_host', sist_get_origin_host() )
|
||||||
|
->set( 'temp_files_dir', trailingslashit( plugin_dir_path( dirname( __FILE__ ) ) . 'static-files' ) )
|
||||||
|
->set( 'additional_urls', '' )
|
||||||
|
->set( 'delivery_method', 's3' )
|
||||||
|
->set( 'local_dir', '' )
|
||||||
|
->set( 'delete_temp_files', '1' )
|
||||||
|
->set( 'aws_s3_bucket', '' )
|
||||||
|
->set( 'aws_access_key_id', '' )
|
||||||
|
->set( 'aws_secret_access_key', '' )
|
||||||
|
->set( 'aws_s3_region', 'us-east-1' )
|
||||||
|
->set( 'aws_s3_endpoint', 's3.amazonaws.com' )
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include required files
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function includes() {
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/libraries/phpuri.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/libraries/S3.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-options.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-view.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-url-extractor.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-url-fetcher.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-url-response.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-simply-static-archive-creator.php';
|
||||||
|
require plugin_dir_path( dirname( __FILE__ ) ) . 'includes/misc-functions.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue admin-specific style sheets for this plugin's admin pages only
|
||||||
|
*
|
||||||
|
* @return null Return early if no settings page is registered.
|
||||||
|
*/
|
||||||
|
public function enqueue_admin_styles() {
|
||||||
|
// Plugin admin CSS. Tack on plugin version.
|
||||||
|
wp_enqueue_style( self::SLUG . '-admin-styles', plugin_dir_url( dirname( __FILE__ ) ) . 'css/admin.css', array(), self::VERSION );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue admin-specific javascript files for this plugin's admin pages only
|
||||||
|
*
|
||||||
|
* @return null Return early if no settings page is registered.
|
||||||
|
*/
|
||||||
|
public function enqueue_admin_scripts() {
|
||||||
|
// Plugin admin CSS. Tack on plugin version.
|
||||||
|
wp_enqueue_script( self::SLUG . '-admin-styles', plugin_dir_url( dirname( __FILE__ ) ) . 'js/admin.js', array(), self::VERSION );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the administration menu for this plugin into the WordPress Dashboard menu.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add_plugin_admin_menu() {
|
||||||
|
// Base 64 encoded SVG image.
|
||||||
|
$icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiICAgaWQ9InN2ZzM0MzQiICAgdmVyc2lvbj0iMS4xIiAgIGlua3NjYXBlOnZlcnNpb249IjAuOTEgcjEzNzI1IiAgIHdpZHRoPSIxODAiICAgaGVpZ2h0PSIzMDAiICAgdmlld0JveD0iMCAwIDE4MCAzMDAiICAgc29kaXBvZGk6ZG9jbmFtZT0iYm9sdC12ZWN0b3ItZ3JheS5zdmciPiAgPG1ldGFkYXRhICAgICBpZD0ibWV0YWRhdGEzNDQwIj4gICAgPHJkZjpSREY+ICAgICAgPGNjOldvcmsgICAgICAgICByZGY6YWJvdXQ9IiI+ICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4gICAgICAgIDxkYzp0eXBlICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPiAgICAgICAgPGRjOnRpdGxlIC8+ICAgICAgPC9jYzpXb3JrPiAgICA8L3JkZjpSREY+ICA8L21ldGFkYXRhPiAgPGRlZnMgICAgIGlkPSJkZWZzMzQzOCIgLz4gIDxzb2RpcG9kaTpuYW1lZHZpZXcgICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiAgICAgYm9yZGVyb3BhY2l0eT0iMSIgICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiICAgICBncmlkdG9sZXJhbmNlPSIxMCIgICAgIGd1aWRldG9sZXJhbmNlPSIxMCIgICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIgICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTUzNiIgICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjgwMSIgICAgIGlkPSJuYW1lZHZpZXczNDM2IiAgICAgc2hvd2dyaWQ9ImZhbHNlIiAgICAgZml0LW1hcmdpbi10b3A9IjAiICAgICBmaXQtbWFyZ2luLWxlZnQ9IjAiICAgICBmaXQtbWFyZ2luLXJpZ2h0PSIwIiAgICAgZml0LW1hcmdpbi1ib3R0b209IjAiICAgICBpbmtzY2FwZTp6b29tPSIyLjE0MjM3MjkiICAgICBpbmtzY2FwZTpjeD0iOC44Njg2Njc5IiAgICAgaW5rc2NhcGU6Y3k9IjE0Ny41MDAwMSIgICAgIGlua3NjYXBlOndpbmRvdy14PSItOCIgICAgIGlua3NjYXBlOndpbmRvdy15PSItOCIgICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczNDM0IiAvPiAgPHBhdGggICAgIHN0eWxlPSJmaWxsOiM5Y2ExYTY7ZmlsbC1vcGFjaXR5OjEiICAgICBkPSJNIDM5LjksMjMzLjUgODQuNDMzMzMzLDE2MS4xMzMzMyAzOS45LDE2MS4xMzMzMyAxNDAuMSw2Ni41IGwgLTQ0LjUzMzMzMyw3Mi4zNjY2NyA0NC41MzMzMzMsMCB6IiAgICAgaWQ9InBhdGgzNDQ2IiAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2NjYyIgLz48L3N2Zz4=';
|
||||||
|
|
||||||
|
// Add main menu item
|
||||||
|
add_menu_page(
|
||||||
|
__( 'Simply Static S3 Settings', self::SLUG ),
|
||||||
|
__( 'Simply Static S3', self::SLUG ),
|
||||||
|
'manage_options',
|
||||||
|
self::SLUG,
|
||||||
|
array( self::$instance, 'display_generate_page' ),
|
||||||
|
$icon_svg
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page(
|
||||||
|
self::SLUG,
|
||||||
|
__( 'Generate Static Site', self::SLUG ),
|
||||||
|
__( 'Generate', self::SLUG ),
|
||||||
|
'manage_options',
|
||||||
|
self::SLUG,
|
||||||
|
array( self::$instance, 'display_generate_page' )
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page(
|
||||||
|
self::SLUG,
|
||||||
|
__( 'Simply Static S3 Settings', self::SLUG ),
|
||||||
|
__( 'Settings', self::SLUG ),
|
||||||
|
'manage_options',
|
||||||
|
self::SLUG . '-options',
|
||||||
|
array( self::$instance, 'display_options_page' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the page for generating a static site.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function display_generate_page() {
|
||||||
|
if ( $this->check_system_requirements() ) {
|
||||||
|
$this->view->assign( 'system_requirements_check_failed', true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $_POST['generate'] ) ) {
|
||||||
|
$archive_creator = new Simply_Static_Archive_Creator(
|
||||||
|
self::SLUG,
|
||||||
|
$this->options->get( 'destination_scheme' ),
|
||||||
|
$this->options->get( 'destination_host' ),
|
||||||
|
$this->options->get( 'temp_files_dir' ),
|
||||||
|
$this->options->get( 'additional_urls' )
|
||||||
|
);
|
||||||
|
$archive_creator->create_archive();
|
||||||
|
|
||||||
|
// TODO: archive_url could be a WP_Error
|
||||||
|
if ( $this->options->get( 'delivery_method' ) == 'zip' ) {
|
||||||
|
|
||||||
|
$archive_url = $archive_creator->create_zip();
|
||||||
|
if ( is_wp_error( $archive_url ) ) {
|
||||||
|
$error = $archive_url->get_error_message();
|
||||||
|
$this->view->add_flash( 'error', $error );
|
||||||
|
} else {
|
||||||
|
$message = __( 'ZIP archive created: ', self::SLUG );
|
||||||
|
$message .= ' <a href="' . $archive_url . '">' . __( 'Click here to download', self::SLUG ) . '</a>';
|
||||||
|
$this->view->add_flash( 'updated', $message );
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ( $this->options->get( 'delivery_method' ) == 'local' ) {
|
||||||
|
|
||||||
|
$local_dir = $this->options->get( 'local_dir' );
|
||||||
|
$result = $archive_creator->copy_static_files( $local_dir );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
$error = $result->get_error_message();
|
||||||
|
$this->view->add_flash( 'error', $error );
|
||||||
|
} else {
|
||||||
|
$message = __( 'Static files copied to: ' . $local_dir, self::SLUG );
|
||||||
|
$this->view->add_flash( 'updated', $message );
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ( $this->options->get( 'delivery_method' ) == 's3' ) {
|
||||||
|
$bucket = $this->options->get( 'aws_s3_bucket' );
|
||||||
|
$result = $archive_creator->publish_to_s3(
|
||||||
|
$bucket,
|
||||||
|
$this->options->get( 'aws_access_key_id' ),
|
||||||
|
$this->options->get( 'aws_secret_access_key' ),
|
||||||
|
$this->options->get( 'aws_s3_region' ),
|
||||||
|
$this->options->get( 'aws_s3_endpoint' )
|
||||||
|
);
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
$error = $result->get_error_message();
|
||||||
|
$this->view->add_flash( 'error', $error );
|
||||||
|
} else {
|
||||||
|
$message = __( 'Site published to S3 bucket: ' . $bucket, self::SLUG );
|
||||||
|
$this->view->add_flash( 'updated', $message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->options->get( 'delete_temp_files' ) == '1' ) {
|
||||||
|
$deleted_successfully = $archive_creator->delete_static_files();
|
||||||
|
}
|
||||||
|
|
||||||
|
$export_log = $archive_creator->get_export_log();
|
||||||
|
$this->view->assign( 'export_log', $export_log );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->view
|
||||||
|
->set_layout( 'admin' )
|
||||||
|
->set_template( 'generate' )
|
||||||
|
->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the options page.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function display_options_page() {
|
||||||
|
if ( isset( $_POST['save'] ) ) {
|
||||||
|
$this->save_options();
|
||||||
|
$message = __( 'Settings saved.', self::SLUG );
|
||||||
|
$this->view->add_flash( 'updated', $message );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->view
|
||||||
|
->set_layout( 'admin' )
|
||||||
|
->set_template( 'options' )
|
||||||
|
->assign( 'slug', self::SLUG )
|
||||||
|
->assign( 'origin_scheme', sist_get_origin_scheme() )
|
||||||
|
->assign( 'origin_host', sist_get_origin_host() )
|
||||||
|
->assign( 'destination_scheme', $this->options->get( 'destination_scheme' ) )
|
||||||
|
->assign( 'destination_host', $this->options->get( 'destination_host' ) )
|
||||||
|
->assign( 'temp_files_dir', $this->options->get( 'temp_files_dir' ) )
|
||||||
|
->assign( 'additional_urls', $this->options->get( 'additional_urls' ) )
|
||||||
|
->assign( 'delivery_method', $this->options->get( 'delivery_method' ) )
|
||||||
|
->assign( 'local_dir', $this->options->get( 'local_dir' ) )
|
||||||
|
->assign( 'delete_temp_files', $this->options->get( 'delete_temp_files' ) )
|
||||||
|
->assign( 'aws_s3_bucket', $this->options->get( 'aws_s3_bucket' ) )
|
||||||
|
->assign( 'aws_access_key_id', $this->options->get( 'aws_access_key_id' ) )
|
||||||
|
->assign( 'aws_secret_access_key', $this->options->get( 'aws_secret_access_key' ) )
|
||||||
|
->assign( 'aws_s3_region', $this->options->get( 'aws_s3_region' ) )
|
||||||
|
->assign( 'aws_s3_endpoint', $this->options->get( 'aws_s3_endpoint' ) )
|
||||||
|
->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the options from the options page.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function save_options() {
|
||||||
|
$this->options
|
||||||
|
->set( 'destination_scheme', filter_input( INPUT_POST, 'destination_scheme' ) )
|
||||||
|
->set( 'destination_host', untrailingslashit( filter_input( INPUT_POST, 'destination_host', FILTER_SANITIZE_URL ) ) )
|
||||||
|
->set( 'temp_files_dir', sist_trailingslashit_unless_blank( filter_input( INPUT_POST, 'temp_files_dir' ) ) )
|
||||||
|
->set( 'additional_urls', filter_input( INPUT_POST, 'additional_urls' ) )
|
||||||
|
->set( 'delivery_method', filter_input( INPUT_POST, 'delivery_method' ) )
|
||||||
|
->set( 'local_dir', sist_trailingslashit_unless_blank( filter_input( INPUT_POST, 'local_dir' ) ) )
|
||||||
|
->set( 'delete_temp_files', filter_input( INPUT_POST, 'delete_temp_files' ) )
|
||||||
|
->set( 'aws_s3_bucket', filter_input( INPUT_POST, 'aws_s3_bucket' ) )
|
||||||
|
->set( 'aws_access_key_id', filter_input( INPUT_POST, 'aws_access_key_id' ) )
|
||||||
|
->set( 'aws_secret_access_key', filter_input( INPUT_POST, 'aws_secret_access_key' ) )
|
||||||
|
->set( 'aws_s3_region', filter_input( INPUT_POST, 'aws_s3_region' ) )
|
||||||
|
->set( 'aws_s3_endpoint', filter_input( INPUT_POST, 'aws_s3_endpoint' ) )
|
||||||
|
->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the plugin language files
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function load_textdomain() {
|
||||||
|
load_plugin_textdomain(
|
||||||
|
self::SLUG,
|
||||||
|
false,
|
||||||
|
dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the plugin language files
|
||||||
|
*
|
||||||
|
* @return array $errors associative array containing errored field names and an array of error messages
|
||||||
|
*/
|
||||||
|
public function check_system_requirements() {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
$destination_host = $this->options->get( 'destination_host' );
|
||||||
|
if ( strlen( $destination_host ) === 0 ) {
|
||||||
|
$errors['destination_host'][] = __( 'Destination URL cannot be blank', self::SLUG );
|
||||||
|
}
|
||||||
|
|
||||||
|
$temp_files_dir = $this->options->get( 'temp_files_dir' );
|
||||||
|
if ( strlen( $temp_files_dir ) === 0 ) {
|
||||||
|
$errors['temp_files_dir'][] = __( 'Temporary Files Directory cannot be blank', self::SLUG );
|
||||||
|
} else {
|
||||||
|
if ( file_exists( $temp_files_dir ) ) {
|
||||||
|
if ( ! is_writeable( $temp_files_dir ) ) {
|
||||||
|
$errors['delivery_method'][] = sprintf( __( 'Temporary Files Directory is not writeable: %s', self::SLUG ), $temp_files_dir );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$errors['delivery_method'][] = sprintf( __( 'Temporary Files Directory does not exist: %s', self::SLUG ), $temp_files_dir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( strlen( get_option( 'permalink_structure' ) ) === 0 ) {
|
||||||
|
$errors['permalink_structure'][] = sprintf( __( "Your site does not have a permalink structure set. You can select one on <a href='%s'>the Permalink Settings page</a>.", self::SLUG ), admin_url( '/options-permalink.php' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->options->get( 'delivery_method' ) == 's3' ) {
|
||||||
|
if ( strlen( $this->options->get( 'aws_s3_bucket' ) ) == 0 ) {
|
||||||
|
$errors['delivery_method'][] = __( "You haven't configured an Amazon AWS bucket for S3 publishing.", self::SLUG );
|
||||||
|
}
|
||||||
|
if ( strlen( $this->options->get( 'aws_access_key_id' ) ) == 0 || strlen( $this->options->get( 'aws_secret_access_key' ) ) == 0 ) {
|
||||||
|
$errors['delivery_method'][] = __( "You haven't configured Amazon AWS credentials for S3 publishing.", self::SLUG );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->options->get( 'delivery_method' ) == 'zip' ) {
|
||||||
|
if ( ! extension_loaded('zip') ) {
|
||||||
|
$errors['delivery_method'][] = __( "Your server does not have the PHP zip extension enabled. Please visit <a href='http://www.php.net/manual/en/book.zip.php'>the PHP zip extension page</a> for more information on how to enable it.", self::SLUG );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->options->get( 'delivery_method' ) == 'local' ) {
|
||||||
|
$local_dir = $this->options->get( 'local_dir' );
|
||||||
|
|
||||||
|
if ( strlen( $local_dir ) === 0 ) {
|
||||||
|
$errors['delivery_method'][] = __( 'Local Directory cannot be blank', self::SLUG );
|
||||||
|
} else {
|
||||||
|
if ( file_exists( $local_dir ) ) {
|
||||||
|
if ( ! is_writeable( $local_dir ) ) {
|
||||||
|
$errors['delivery_method'][] = sprintf( __( 'Local Directory is not writeable: %s', self::SLUG ), $local_dir );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$errors['delivery_method'][] = sprintf( __( 'Local Directory does not exist: %s', self::SLUG ), $local_dir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
Executable
+1
@@ -0,0 +1 @@
|
|||||||
|
<?php // Silence is golden
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,209 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A php library for converting relative urls to absolute.
|
||||||
|
* Website: https://github.com/monkeysuffrage/phpuri
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* echo phpUri::parse('https://www.google.com/')->join('foo');
|
||||||
|
* //==> https://www.google.com/foo
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Licensed under The MIT License
|
||||||
|
* Redistributions of files must retain the above copyright notice.
|
||||||
|
*
|
||||||
|
* @author P Guardiario <pguardiario@gmail.com>
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phpUri
|
||||||
|
*/
|
||||||
|
class phpUri
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http(s)://
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $scheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.example.com
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $authority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /search
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?q=foo
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #bar
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $fragment;
|
||||||
|
|
||||||
|
private function __construct( $string )
|
||||||
|
{
|
||||||
|
preg_match_all( '/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $string, $m );
|
||||||
|
$this->scheme = $m[ 2 ][ 0 ];
|
||||||
|
$this->authority = $m[ 4 ][ 0 ];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CHANGE:
|
||||||
|
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
|
||||||
|
* @since 24 Mai 2015 10:02 Uhr
|
||||||
|
*
|
||||||
|
* Former code: $this->path = ( empty( $m[ 5 ][ 0 ] ) ) ? '/' : $m[ 5 ][ 0 ];
|
||||||
|
* No tests failed, when the path is empty.
|
||||||
|
* With the former code, the relative urls //g and #s failed
|
||||||
|
*/
|
||||||
|
$this->path = $m[ 5 ][ 0 ];
|
||||||
|
$this->query = $m[ 7 ][ 0 ];
|
||||||
|
$this->fragment = $m[ 9 ][ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function to_str()
|
||||||
|
{
|
||||||
|
$ret = '';
|
||||||
|
if ( !empty( $this->scheme ) )
|
||||||
|
{
|
||||||
|
$ret .= "{$this->scheme}:";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !empty( $this->authority ) )
|
||||||
|
{
|
||||||
|
$ret .= "//{$this->authority}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret .= $this->normalize_path( $this->path );
|
||||||
|
|
||||||
|
if ( !empty( $this->query ) )
|
||||||
|
{
|
||||||
|
$ret .= "?{$this->query}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !empty( $this->fragment ) )
|
||||||
|
{
|
||||||
|
$ret .= "#{$this->fragment}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function normalize_path( $path )
|
||||||
|
{
|
||||||
|
if ( empty( $path ) )
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$normalized_path = $path;
|
||||||
|
$normalized_path = preg_replace( '`//+`', '/', $normalized_path, -1, $c0 );
|
||||||
|
$normalized_path = preg_replace( '`^/\\.\\.?/`', '/', $normalized_path, -1, $c1 );
|
||||||
|
$normalized_path = preg_replace( '`/\\.(/|$)`', '/', $normalized_path, -1, $c2 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CHANGE:
|
||||||
|
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
|
||||||
|
* @since 24 Mai 2015 10:05 Uhr
|
||||||
|
* changed limit form -1 to 1, because climbing up the directory-tree failed
|
||||||
|
*/
|
||||||
|
$normalized_path = preg_replace( '`/[^/]*?/\\.\\.(/|$)`', '/', $normalized_path, 1, $c3 );
|
||||||
|
$num_matches = $c0 + $c1 + $c2 + $c3;
|
||||||
|
|
||||||
|
return ( $num_matches > 0 ) ? $this->normalize_path( $normalized_path ) : $normalized_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an url string
|
||||||
|
*
|
||||||
|
* @param string $url the url to parse
|
||||||
|
*
|
||||||
|
* @return phpUri
|
||||||
|
*/
|
||||||
|
public static function parse( $url )
|
||||||
|
{
|
||||||
|
$uri = new phpUri( $url );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CHANGE:
|
||||||
|
* @author Dominik Habichtsberg <Dominik.Habichtsberg@Hbg-IT.de>
|
||||||
|
* @since 24 Mai 2015 10:25 Uhr
|
||||||
|
* The base-url should always have a path
|
||||||
|
*/
|
||||||
|
if ( empty( $uri->path ) )
|
||||||
|
{
|
||||||
|
$uri->path = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join with a relative url
|
||||||
|
*
|
||||||
|
* @param string $relative the relative url to join
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function join( $relative )
|
||||||
|
{
|
||||||
|
$uri = new phpUri( $relative );
|
||||||
|
switch ( TRUE )
|
||||||
|
{
|
||||||
|
case !empty( $uri->scheme ):
|
||||||
|
break;
|
||||||
|
|
||||||
|
case !empty( $uri->authority ):
|
||||||
|
break;
|
||||||
|
|
||||||
|
case empty( $uri->path ):
|
||||||
|
$uri->path = $this->path;
|
||||||
|
if ( empty( $uri->query ) )
|
||||||
|
{
|
||||||
|
$uri->query = $this->query;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case strpos( $uri->path, '/' ) === 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$base_path = $this->path;
|
||||||
|
if ( strpos( $base_path, '/' ) === FALSE )
|
||||||
|
{
|
||||||
|
$base_path = '';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$base_path = preg_replace( '/\/[^\/]+$/', '/', $base_path );
|
||||||
|
}
|
||||||
|
if ( empty( $base_path ) && empty( $this->authority ) )
|
||||||
|
{
|
||||||
|
$base_path = '/';
|
||||||
|
}
|
||||||
|
$uri->path = $base_path . $uri->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $uri->scheme ) )
|
||||||
|
{
|
||||||
|
$uri->scheme = $this->scheme;
|
||||||
|
if ( empty( $uri->authority ) )
|
||||||
|
{
|
||||||
|
$uri->authority = $this->authority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri->to_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Miscellaneous functions for use across the plugin
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if accessed directly.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the protocol used for the origin URL
|
||||||
|
*
|
||||||
|
* @return string http or https
|
||||||
|
*/
|
||||||
|
function sist_get_origin_scheme() {
|
||||||
|
return is_ssl() ? 'https' : 'http';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the host for the origin URL
|
||||||
|
*
|
||||||
|
* @return string host (URL minus the protocol)
|
||||||
|
*/
|
||||||
|
function sist_get_origin_host() {
|
||||||
|
return untrailingslashit( preg_replace( "(^https?://)", "", home_url() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Echo the selected value for an option tag if the statement is true.
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
function sist_selected_if( $statement ) {
|
||||||
|
echo ( $statement == true ? 'selected="selected"' : '' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate if a string exceeds a certain length (30 chars by default)
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function sist_truncate( $string, $length = 30, $omission = '...' ) {
|
||||||
|
return ( strlen( $string ) > $length + 3 ) ? ( substr( $string, 0, $length ) . $omission ) : $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use trailingslashit unless the string is empty
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function sist_trailingslashit_unless_blank( $string ) {
|
||||||
|
return $string === '' ? $string : trailingslashit( $string );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump an object to error_log
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function sist_error_log( $object=null ){
|
||||||
|
ob_start();
|
||||||
|
var_dump( $object );
|
||||||
|
$contents = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
error_log( $contents );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a URL extracted from a page, return an absolute URL
|
||||||
|
*
|
||||||
|
* Takes a URL (e.g. /test) extracted from a page (e.g. http://foo.com/bar/) and
|
||||||
|
* returns an absolute URL (e.g. http://foo.com/bar/test). Absolute URLs are
|
||||||
|
* returned as-is.
|
||||||
|
*
|
||||||
|
* A null value is returned in the event that the extracted_url is blank or it's
|
||||||
|
* unable to be parsed.
|
||||||
|
*
|
||||||
|
* @param string $extracted_url Relative or absolute URL extracted from page
|
||||||
|
* @param string $page_url URL of page
|
||||||
|
* @return string|null Absolute URL, or null
|
||||||
|
*/
|
||||||
|
function sist_relative_to_absolute_url( $extracted_url, $page_url ) {
|
||||||
|
|
||||||
|
$extracted_url = trim( $extracted_url );
|
||||||
|
|
||||||
|
if ( $extracted_url === '' ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parsed_extracted_url = parse_url( $extracted_url );
|
||||||
|
|
||||||
|
// parse_url can sometimes return false; bail if it does
|
||||||
|
if ( $parsed_extracted_url === false ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $parsed_extracted_url['host'] ) ) {
|
||||||
|
|
||||||
|
return $extracted_url;
|
||||||
|
|
||||||
|
} elseif ( isset( $parsed_extracted_url['scheme'] ) ) {
|
||||||
|
|
||||||
|
// examples of schemes without hosts: java:, data:
|
||||||
|
return $extracted_url;
|
||||||
|
|
||||||
|
} else { // no host on extracted page (might be relative url)
|
||||||
|
|
||||||
|
$path = isset( $parsed_extracted_url['path'] ) ? $parsed_extracted_url['path'] : '';
|
||||||
|
|
||||||
|
// Check for a bug in PHP <= 5.4.7 where URLs starting
|
||||||
|
// with '//' are identified as a path
|
||||||
|
// http://php.net/manual/en/function.parse-url.php#example-4617
|
||||||
|
if ( substr( $path, 0, 2 ) === '//' ) {
|
||||||
|
|
||||||
|
return $extracted_url;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$query = isset( $parsed_extracted_url['query'] ) ? '?' . $parsed_extracted_url['query'] : '';
|
||||||
|
$fragment = isset( $parsed_extracted_url['fragment'] ) ? '#' . $parsed_extracted_url['fragment'] : '';
|
||||||
|
|
||||||
|
// turn our relative url into an absolute url
|
||||||
|
$extracted_url = phpUri::parse( $page_url )->join( $path . $query . $fragment );
|
||||||
|
|
||||||
|
return $extracted_url;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if URL starts with same URL as WordPress installation
|
||||||
|
*
|
||||||
|
* @param string $url URL to check
|
||||||
|
* @return boolean true if URL is local, false otherwise
|
||||||
|
*/
|
||||||
|
function sist_is_local_url( $url ) {
|
||||||
|
return ( stripos( $url, home_url() ) === 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a URL w/o the query string or fragment (i.e. nothing after the path)
|
||||||
|
*
|
||||||
|
* @param string $url URL to remove query string/fragment from
|
||||||
|
* @return string URL without query string/fragment
|
||||||
|
*/
|
||||||
|
function sist_remove_params_and_fragment( $url ) {
|
||||||
|
return preg_replace('/(\?|#).*/', '', $url);
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
'use strict';
|
||||||
|
jQuery( document ).ready( function() {
|
||||||
|
|
||||||
|
// show / hide tabs:
|
||||||
|
jQuery( '#sistTabs' ).find( 'a' ).click( function() {
|
||||||
|
jQuery( '#sistTabs' ).find( 'a' ).removeClass( 'nav-tab-active' );
|
||||||
|
jQuery( '.tab-pane' ).removeClass( 'active' );
|
||||||
|
|
||||||
|
var id = jQuery( this ).attr( 'id' ).replace( '-tab', '' );
|
||||||
|
jQuery( '#' + id ).addClass( 'active' );
|
||||||
|
jQuery( this ).addClass( 'nav-tab-active' );
|
||||||
|
});
|
||||||
|
|
||||||
|
// set active tab on page load:
|
||||||
|
var activeTab = window.location.hash.replace( '#tab-', '' );
|
||||||
|
|
||||||
|
// if no tab hash, default to the first tab
|
||||||
|
if ( activeTab === '' ) {
|
||||||
|
activeTab = jQuery( '.tab-pane' ).attr( 'id' );
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery( '#' + activeTab ).addClass( 'active' );
|
||||||
|
jQuery( '#' + activeTab + '-tab' ).addClass( 'nav-tab-active' );
|
||||||
|
|
||||||
|
// pretend the user clicked on the active tab
|
||||||
|
jQuery( '.nav-tab-active' ).click();
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// delivery method selection:
|
||||||
|
jQuery( '#deliveryMethod' ).change(function() {
|
||||||
|
var selected = jQuery( this ).val();
|
||||||
|
jQuery( '.delivery-method' ).removeClass( 'active' );
|
||||||
|
jQuery( '.' + selected + '.delivery-method' ).addClass( 'active ');
|
||||||
|
});
|
||||||
|
|
||||||
|
// pretend the user selected a value
|
||||||
|
jQuery(' #deliveryMethod' ).change();
|
||||||
|
|
||||||
|
});
|
||||||
Whitespace-only changes.
Executable
+339
@@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 2 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, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
Based on https://github.com/kennu/simply-static-s3
|
||||||
|
|
||||||
|
Updated for modern v4 API support and generic S3 providers.
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
<?php if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin Name: Simply Static S3
|
||||||
|
* Plugin URI: https://github.com/kennu/simply-static-s3
|
||||||
|
* Description: Produces a static HTML version of your WordPress install, adjusts URLs accordingly and deploys to Amazon S3.
|
||||||
|
* Version: 2.0.0
|
||||||
|
* Author: Kenneth Falck (based on Code of Conduct)
|
||||||
|
* Author URI: https://github.com/kennu
|
||||||
|
* License: GPL-2.0+
|
||||||
|
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||||
|
* Text Domain: simply-static-s3
|
||||||
|
* Domain Path: /languages
|
||||||
|
*/
|
||||||
|
|
||||||
|
require plugin_dir_path( __FILE__ ) . 'includes/class-simply-static.php';
|
||||||
|
|
||||||
|
Simply_Static::init( __FILE__ );
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Uninstall Simply Static
|
||||||
|
*
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
|
||||||
|
// exit if accessed directly
|
||||||
|
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) exit;
|
||||||
|
|
||||||
|
// Delete Simply Static's settings
|
||||||
|
delete_option( 'simply-static' );
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h2><?php _e( 'Simply Static S3', $this->slug ); ?></h2>
|
||||||
|
|
||||||
|
<div class="wrap">
|
||||||
|
|
||||||
|
<?php if ( is_array( $this->export_log ) && count( $this->export_log ) ): ?>
|
||||||
|
<h3><?php _e( 'Export Log', $this->slug ); ?></h3>
|
||||||
|
<div class="export-log">
|
||||||
|
<pre><?php echo implode( "\n", $this->export_log ) ?></pre>
|
||||||
|
</div>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
|
<form id="generate" method="post" action="">
|
||||||
|
|
||||||
|
<?php if ( $this->system_requirements_check_failed ) : ?>
|
||||||
|
<p><?php _e( "Uh oh, we've found an issue that prevents us from creating a static copy of your site.", $this->slug ); ?></p>
|
||||||
|
<?php else : ?>
|
||||||
|
<p><?php _e( "Press the button below to create a static copy of your site.", $this->slug ); ?></p>
|
||||||
|
<p><?php _e( "Note: on large sites this process may take a while.", $this->slug ); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<p class="submit">
|
||||||
|
<?php wp_nonce_field( $this->slug ) ?>
|
||||||
|
<input class="button button-primary button-hero" type="submit" name="generate" value="Generate Static Files" <?php if ( $this->system_requirements_check_failed ) { echo 'disabled=disabled'; } ?> />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ( $this->flashes as $flash ) : ?>
|
||||||
|
<div class="fade <?php echo $flash['type']; ?>">
|
||||||
|
<p><strong>
|
||||||
|
<?php echo $flash['message']; ?>
|
||||||
|
</strong></p>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<div class="wrap">
|
||||||
|
<div id="sistContainer">
|
||||||
|
|
||||||
|
<div id="sistContent">
|
||||||
|
<?php include $this->template; ?>
|
||||||
|
</div>
|
||||||
|
<!-- .sist-content -->
|
||||||
|
|
||||||
|
<div id="sistSidebar">
|
||||||
|
<div class="sidebar-container metabox-holder">
|
||||||
|
<div class="postbox">
|
||||||
|
<h3 class="wp-ui-primary"><?php _e( 'Like this plugin?', $this->slug ); ?></h3>
|
||||||
|
<div class="inside">
|
||||||
|
<div class="main">
|
||||||
|
<p><?php _e( 'Join the mailing list to be notified when new features and plugins are released.', $this->slug ); ?></p>
|
||||||
|
|
||||||
|
<!-- Begin MailChimp Signup Form -->
|
||||||
|
<div id="mc_embed_signup">
|
||||||
|
<form action="//codeofconduct.us8.list-manage.com/subscribe/post?u=add8381918934d53034b89daf&id=7b053181a2" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
|
||||||
|
<div id="mc_embed_signup_scroll">
|
||||||
|
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="<?php _e( 'email address', $this->slug ); ?>" required>
|
||||||
|
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
|
||||||
|
<div style="position: absolute; left: -5000px;"><input type="text" name="b_add8381918934d53034b89daf_7b053181a2" tabindex="-1" value=""></div>
|
||||||
|
<div class="clear"><input type="submit" value="<?php _e( 'Subscribe', $this->slug ); ?>" name="subscribe" id="mc-embedded-subscribe" class="button-primary"></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!--End mc_embed_signup-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- .sist-sidebar -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- .sist-container -->
|
||||||
|
</div>
|
||||||
|
<!-- .wrap -->
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Simply_Static
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class='wrap'>
|
||||||
|
|
||||||
|
<h2><?php _e( 'Simply Static S3', $this->slug ); ?></h2>
|
||||||
|
|
||||||
|
<form id='options' method='post' action=''>
|
||||||
|
|
||||||
|
<?php wp_nonce_field( $this->slug ) ?>
|
||||||
|
|
||||||
|
<h2 id='sistTabs' class='nav-tab-wrapper'>
|
||||||
|
<a class='nav-tab' id='general-tab' href='#tab-general'><?php _e( 'General', $this->slug ); ?></a>
|
||||||
|
<a class='nav-tab' id='advanced-tab' href='#tab-advanced'><?php _e( 'Advanced', $this->slug ); ?></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div id='general' class='tab-pane'>
|
||||||
|
|
||||||
|
<table class='form-table'>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for='originHost'><?php _e( "Origin URL", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<select id='originScheme' name='origin_scheme' disabled>
|
||||||
|
<option value='<?php echo $this->origin_scheme; ?>'><?php echo $this->origin_scheme; ?>://</option>
|
||||||
|
</select>
|
||||||
|
<input aria-describedby='originHostHelpBlock' type='text' id='originHost' name='origin_host' value='<?php echo esc_attr( $this->origin_host ) ?>' size='50' disabled />
|
||||||
|
<p id='originHostHelpBlock' class='help-block'><?php echo sprintf( __( "This is the URL of your WordPress installation. You can edit the URL on <a href='%s'>the General Settings page</a>.", $this->slug ), admin_url( '/options-general.php' ) ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for='destinationHost'><?php _e( "Destination URL", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<select id='destinationScheme' name='destination_scheme'>
|
||||||
|
<option value='http' <?php sist_selected_if( $this->destination_scheme == 'http' ) ?>>http://</option>
|
||||||
|
<option value='https' <?php sist_selected_if( $this->destination_scheme == 'https' ) ?>>https://</option>
|
||||||
|
</select>
|
||||||
|
<input aria-describedby='destinationHostHelpBlock' type='text' id='destinationHost' name='destination_host' value='<?php echo esc_attr( $this->destination_host ) ?>' size='50' />
|
||||||
|
<p id='destinationHostHelpBlock' class='help-block'><?php _e( "This is the URL where your static site will live. When generating your static site, all links to the Origin URL will be replaced with the Destination URL.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for='deliveryMethod'><?php _e( "Delivery Method", $this->slug ); ?></label></th>
|
||||||
|
<td>
|
||||||
|
<select name='delivery_method' id='deliveryMethod'>
|
||||||
|
<option value='s3' <?php sist_selected_if( $this->delivery_method == 's3' ) ?>><?php _e( "Amazon S3", $this->slug ); ?></option>
|
||||||
|
<option value='zip' <?php sist_selected_if( $this->delivery_method == 'zip' ) ?>><?php _e( "ZIP Archive", $this->slug ); ?></option>
|
||||||
|
<option value='local' <?php sist_selected_if( $this->delivery_method == 'local' ) ?>><?php _e( "Local Directory", $this->slug ); ?></option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method zip'>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<p><?php _e( "Saving your static files to a ZIP archive is Simply Static's default delivery method. After generating your static files you will be prompted to download the ZIP archive.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method local'>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<p><?php _e( "Saving your static files to a local directory is useful if you want to serve your static files from the same server as your WordPress installation. WordPress can live on a subdomain (e.g. wordpress.example.com) while your static files are served from your primary domain (e.g. www.example.com).", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method local'>
|
||||||
|
<th>
|
||||||
|
<label for='local_dir'><?php _e( "Local Directory", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<?php $example_local_dir = plugin_dir_path( dirname( __FILE__ ) ); ?>
|
||||||
|
<input aria-describedby='localDirHelpBlock' type='text' id='localDir' name='local_dir' value='<?php echo esc_attr( $this->local_dir ) ?>' placeholder='<?php echo $example_local_dir; ?>' class='widefat' />
|
||||||
|
<p id='localDirHelpBlock' class='help-block'><?php _e( "This is the directory where your static files will be saved. The directory must exist and be writeable by the webserver.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<p><?php _e( "A static copy of your site will be published to Amazon S3 in the bucket you specify.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th>
|
||||||
|
<label for='aws_s3_bucket'><?php _e( "AWS S3 Bucket", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input aria-describedby='awsS3BucketHelpBlock' type='text' id='awsS3Bucket' name='aws_s3_bucket' value='<?php echo esc_attr( $this->aws_s3_bucket ) ?>' placeholder='Existing bucket name' class='widefat' />
|
||||||
|
<p id='awsS3BucketHelpBlock' class='help-block'><?php _e( "Your static site will be published in this S3 bucket. It must already exist. Use AWS Console to create a bucket.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th>
|
||||||
|
<label for='aws_access_key_id'><?php _e( "AWS Access Key ID", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input aria-describedby='awsAccessKeyIDHelpBlock' type='text' id='awsS3AccessKeyID' name='aws_access_key_id' value='<?php echo esc_attr( $this->aws_access_key_id ) ?>' placeholder='Access Key ID with write access to S3' class='widefat' />
|
||||||
|
<p id='awsS3AccessKeyIDHelpBlock' class='help-block'><?php _e( "If you don't have an access key, use AWS Console IAM to generate a new user and access key. It must have rights to publish to S3.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th>
|
||||||
|
<label for='aws_secret_access_key'><?php _e( "AWS Secret Access Key", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input aria-describedby='awsSecretAccessKeyHelpBlock' type='text' id='awsSecretS3AccessKey' name='aws_secret_access_key' value='<?php echo esc_attr( $this->aws_secret_access_key ) ?>' placeholder='Secret Access Key with write access to S3' class='widefat' />
|
||||||
|
<p id='awsS3SecretAccessKeyHelpBlock' class='help-block'><?php _e( "If you don't have an access key, use AWS Console IAM to generate a new user and access key. It must have rights to publish to S3.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th>
|
||||||
|
<label for='aws_s3_region'><?php _e( "S3 Region", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input aria-describedby='awsS3RegionHelpBlock' type='text' id='awsS3Region' name='aws_s3_region' value='<?php echo esc_attr( $this->aws_s3_region ) ?>' placeholder='us-east-1' class='widefat' />
|
||||||
|
<p id='awsS3RegionHelpBlock' class='help-block'><?php _e( "The region of your S3 bucket (e.g. us-east-1, eu-west-1, us-west-1).", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class='delivery-method s3'>
|
||||||
|
<th>
|
||||||
|
<label for='aws_s3_endpoint'><?php _e( "S3 Endpoint URL", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input aria-describedby='awsS3EndpointHelpBlock' type='text' id='awsS3Endpoint' name='aws_s3_endpoint' value='<?php echo esc_attr( $this->aws_s3_endpoint ) ?>' placeholder='s3.amazonaws.com' class='widefat' />
|
||||||
|
<p id='awsS3EndpointHelpBlock' class='help-block'><?php _e( "The endpoint URL for your S3 provider (e.g. s3.amazonaws.com, s3.wasabisys.com, s3.us-west-002.backblazeb2.com).", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<p class='submit'>
|
||||||
|
<input class='button button-primary' type='submit' name='save' value='<?php _e( "Save Changes", $this->slug );?>' />
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id='advanced' class='tab-pane'>
|
||||||
|
|
||||||
|
<table class='form-table'>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for='tempFilesDir'><?php _e( "Temporary Files Directory", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<?php $example_temp_files_dir = trailingslashit( plugin_dir_path( dirname( __FILE__ ) ) . 'static-files' );?>
|
||||||
|
<input aria-describedby='tempFilesDirHelpBlock' type='text' id='tempFilesDir' name='temp_files_dir' value='<?php echo esc_attr( $this->temp_files_dir ) ?>' placeholder='<?php echo $example_temp_files_dir; ?>'class='widefat' />
|
||||||
|
<p id='tempFilesDirHelpBlock' class='help-block'><?php _e( "Your static files (and ZIP archives, if generated) are temporarily saved to this directory. This directory must exist and be writeable.", $this->slug ); ?></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input aria-describedby='deleteTempFilesHelpBlock' name='delete_temp_files' id='deleteTempFiles' value='1' type='checkbox' <?php if ( $this->delete_temp_files == '1' ) { echo 'checked'; } ?> />
|
||||||
|
<?php _e( "Delete temporary files", $this->slug ); ?>
|
||||||
|
</label>
|
||||||
|
<p id='deleteTempFilesHelpBlock' class='help-block'>
|
||||||
|
<?php _e( "Static files are temporarily saved to the directory above before being copied to their destination. These files can be deleted after the copy process, or you can keep them as a backup.", $this->slug ); ?>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for='additionalUrls'><?php _e( "Additional URLs", $this->slug );?></label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<textarea aria-describedby='additionalUrlsHelpBlock' class='widefat' name='additional_urls' id='additionalUrls' rows='5' cols='10'><?php echo esc_html( $this->additional_urls ) ?></textarea>
|
||||||
|
<p id='additionalUrlsHelpBlock' class='help-block'>
|
||||||
|
<?php echo sprintf( __( "Simply Static will create a static copy of any page it can find a link to, starting at %s. If you want to create static copies of pages or files that <em>aren't</em> linked to, add the URLs here (one per line). Examples: <code>%s</code> or <code>%s</code>", $this->slug),
|
||||||
|
$this->origin_scheme . '://' . $this->origin_host,
|
||||||
|
$this->origin_scheme . '://' . $this->origin_host . '/hidden-page',
|
||||||
|
$this->origin_scheme . '://' . $this->origin_host . '/images/secret.jpg' ); ?>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<td>
|
||||||
|
<p class='submit'>
|
||||||
|
<input class='button button-primary' type='submit' name='save' value='<?php _e( "Save Changes", $this->slug );?>' />
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><?php _e( 'Redirecting...', $this->slug ); ?></title>
|
||||||
|
<noscript>
|
||||||
|
<meta http-equiv="refresh" content="0;url=<?php echo $this->redirect_url; ?>">
|
||||||
|
</noscript>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.location = "<?php echo $this->redirect_url; ?>";
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>You are being redirected to <a href="<?php echo $this->redirect_url; ?>"><?php echo $this->redirect_url; ?></a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in new issue
Block a user