Commit ecc43310 authored by Erick Hitter's avatar Erick Hitter

Merge branch 'add/lint' into 'master'

add linting

See merge request !6
parents aa217a9e f7936dda
Pipeline #237 passed with stage
in 3 minutes and 14 seconds
......@@ -24,42 +24,29 @@ before_script:
- composer global require automattic/vipwpcs
- phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs,$HOME/.composer/vendor/automattic/vipwpcs
PHPunit:PHP5.3:MySQL:
image: containers.ethitter.com:443/docker/images/php:5.3
services:
- mysql:5.6
script:
- phpcs -n
- phpunit
PHPunit:PHP5.6:MySQL:
image: containers.ethitter.com:443/docker/images/php:5.6
services:
- mysql:5.6
script:
- phpcs -n
- phpunit
PHPunit:PHP7.0:MySQL:
test_7.0:
image: containers.ethitter.com:443/docker/images/php:7.0
services:
- mysql:5.6
script:
- find . -type "f" -iname "*.php" | xargs -L "1" php -l
- phpcs -n
- phpunit
PHPunit:PHP7.1:MySQL:
test_7.1:
image: containers.ethitter.com:443/docker/images/php:7.1
services:
- mysql:5.6
script:
- find . -type "f" -iname "*.php" | xargs -L "1" php -l
- phpcs -n
- phpunit
PHPunit:PHP7.2:MySQL:
test_7.2:
image: containers.ethitter.com:443/docker/images/php:7.2
services:
- mysql:5.6
script:
- find . -type "f" -iname "*.php" | xargs -L "1" php -l
- phpcs -n
- phpunit
......@@ -3,6 +3,7 @@
**Donate link:** https://ethitter.com/donate/
**Tags:** image, proxy, cdn
**Requires at least:** 4.9
**Requires PHP:** 7.0
**Tested up to:** 4.9
**Stable tag:** 0.1.0
**License:** GPLv2 or later
......
......@@ -13,3 +13,58 @@
*/
namespace Camo_Image_Proxy;
const PLUGIN_PATH = __DIR__;
/**
* Trait for singletons
*/
require_once PLUGIN_PATH . '/inc/trait-singleton.php';
/**
* Plugin options
*/
require_once PLUGIN_PATH . '/inc/class-options.php';
/**
* Options page
*/
require_once PLUGIN_PATH . '/inc/class-options-page.php';
/**
* URL Building
*/
require_once PLUGIN_PATH . '/inc/class-url.php';
/**
* Rewrite WordPress-generated URLs
*/
require_once PLUGIN_PATH . '/inc/class-rewrite-urls.php';
/**
* Rewrite URLs in post content
*/
require_once PLUGIN_PATH . '/inc/class-rewrite-content.php';
/**
* Assorted functions
*/
require_once PLUGIN_PATH . '/inc/functions.php';
/**
* Load plugin singletons
*/
function init() {
Options::instance();
URL::instance();
if ( is_admin() ) {
Options_Page::instance();
}
if ( URL::instance()->can_rewrite() ) {
Rewrite_URLs::instance();
Rewrite_Content::instance();
}
}
add_action( 'init', __NAMESPACE__ . '\init' );
<?php
/**
* Plugin options page
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Class Options_Page
*/
class Options_Page {
use Singleton;
/**
* Settings screen section
*
* @var string
*/
private $section = 'camp-image-proxy';
/**
* Field labels
*
* @var array
*/
private $labels = [];
/**
* Option name
*
* @var string
*/
private $name;
/**
* Hooks
*/
public function setup() {
$this->name = Options::instance()->name;
$this->labels['host'] = __( 'Host', 'camo-image-proxy' );
$this->labels['key'] = __( 'Shared Key', 'camo-image-proxy' );
add_action( 'admin_init', [ $this, 'action_admin_init' ] );
}
/**
* Add fields to Media settings page
*/
public function action_admin_init() {
register_setting( 'media', $this->name, [ Options::instance(), 'sanitize_all' ] );
add_settings_section( $this->section, __( 'Camo Image Proxy', 'camo-image-proxy' ), '__return_false', 'media' );
foreach ( $this->labels as $key => $label ) {
$args = [
'option' => $key,
'label' => $label,
];
add_settings_field( $key, $label, [ $this, 'screen' ], 'media', $this->section, $args );
}
}
/**
* Render options field
*
* @param array $args Field arguments.
*/
public function screen( $args ) {
$value = Options::instance()->get( $args['option'] );
$input_type = 'host' === $args['option'] ? 'url' : 'text';
$name = sprintf( '%1$s[%2$s]', $this->name, $args['option'] );
$html_id = sprintf( '%1$s-%2$s', str_replace( '_', '-', $this->name ), $args['option'] );
?>
<input
type="<?php echo esc_attr( $input_type ); ?>"
name="<?php echo esc_attr( $name ); ?>"
class="regular-text"
id="<?php echo esc_attr( $html_id ); ?>"
value="<?php echo esc_attr( $value ); ?>"
/>
<?php
}
}
<?php
/**
* Plugin options
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Class Options
*/
class Options {
use Singleton;
/**
* Option name
*
* @var string
*/
private $name = 'camo_image_proxy_opts';
/**
* Allowed options
*
* @var array
*/
private $allowed_options = [
'host' => '',
'key' => '',
];
/**
* Access certain private properties
*
* @param string $name Property name.
* @return mixed
*/
public function __get( string $name ) {
switch ( $name ) {
case 'name':
return $this->name;
default:
return new \WP_Error( 'invalid-property', __( 'Invalid property requested.', 'camo-image-proxy' ), $name );
}
}
/**
* Retrieve full plugin options
*
* @return array
*/
private function get_all() : array {
$options = get_option( $this->name, [] );
$options = wp_parse_args( $options, $this->allowed_options );
return $options;
}
/**
* Get plugin option
*
* @param string $option Plugin option to retrieve.
* @return mixed
*/
public function get( string $option ) {
if ( ! array_key_exists( $option, $this->allowed_options ) ) {
return false;
}
$options = $this->get_all();
return $options[ $option ] ?? false;
}
/**
* Set plugin option
*
* @param string $option Plugin option to set.
* @param mixed $value Option value.
* @return bool
*/
public function set( string $option, $value ) : bool {
$value = $this->sanitize( $option, $value );
$options = $this->get_all();
$options[ $option ] = $value;
return update_option( $this->name, $options );
}
/**
* Sanitize option
*
* @param string $option Plugin option.
* @param mixed $value Option value to sanitize.
* @return mixed
*/
public function sanitize( string $option, $value ) {
switch ( $option ) {
case 'host':
$value = esc_url( $value );
if ( ! empty( $value ) ) {
$value = untrailingslashit( $value );
}
break;
case 'key':
$value = sanitize_text_field( $value );
break;
default:
return false;
}
return $value;
}
/**
* Sanitize array of options
*
* @param array $options Options to sanitize.
* @return array
*/
public function sanitize_all( array $options ) : array {
foreach ( $options as $option => $value ) {
$options[ $option ] = $this->sanitize( $option, $value );
}
return $options;
}
}
<?php
/**
* Rewrite images in content
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Class Rewrite_Content
*/
class Rewrite_Content {
use Singleton;
/**
* Filter priority
*
* @var int
*/
private $priority;
/**
* Hooks
*/
public function setup() {
$priority = apply_filters( 'camo_image_proxy_rewrite_content_priority', PHP_INT_MAX - 1 );
$this->priority = absint( $priority );
add_filter( 'the_content', [ $this, 'filter_the_content' ], $this->priority );
}
/**
* Rewrite image URLs in content
*
* @param string $content Post content.
* @return string
*/
public function filter_the_content( string $content ) : string {
// TODO: only deal with image srcs, use DOM Document.
return $content;
}
}
<?php
/**
* Force Core's image functions to use Camo
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Class Rewrite_URLs
*/
class Rewrite_URLs {
use Singleton;
/**
* Hooks
*/
public function setup() {
add_filter( 'wp_get_attachment_image_src', [ $this, 'encode_image' ] );
}
/**
* Camouflage attachment URL
*
* @param array $image Image data.
* @return array
*/
public function encode_image( array $image ) : array {
$url = URL::instance()->encode( $image[0] );
if ( is_string( $url ) ) {
$image[0] = $url;
}
return $image;
}
}
<?php
/**
* URL Building
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Class URL
*/
class URL {
use Singleton;
/**
* Can URLs be rewritten to use Camo?
*
* @return bool
*/
public function can_rewrite() : bool {
// Never rewrite in admin.
if ( is_admin() ) {
return false;
}
$host = Options::instance()->get( 'host' );
$key = Options::instance()->get( 'key' );
$can_rewrite = true;
// Validate host.
if ( ! $this->is_valid_url( $host ) ) {
$can_rewrite = false;
}
// Validate key.
// TODO: make sure it's an HMAC or something?
if ( empty( $key ) || ! is_string( $key ) ) {
$can_rewrite = false;
}
return apply_filters( 'camo_image_proxy_can_rewrite', $can_rewrite, $host, $key );
}
/**
* Encode image URL
*
* @param string $url Image URL to encode.
* @return string|bool
*/
public function encode( string $url ) : string {
if ( ! $this->can_rewrite() || ! $this->is_valid_url( $url ) ) {
return false;
}
$key = hash_hmac( 'sha1', $url, Options::instance()->get( 'key' ) );
$url_encoded = bin2hex( $url );
$url_encoded = sprintf( '%1$s/%2$s/%3$s', Options::instance()->get( 'host' ), $key, $url_encoded );
$url_encoded = set_url_scheme( $url_encoded, 'https' );
return $url_encoded;
}
/**
* Decode encoded URL
*
* @param string $url Camo URL to decode.
* @return string|bool
*/
public function decode( string $url ) : string {
return false;
}
/**
* Can we encode this URL?
*
* @param string $url URL to validate.
* @return bool
*/
private function is_valid_url( string $url ) : bool {
if ( empty( $url ) ) {
return false;
}
if ( false === filter_var( $url, FILTER_VALIDATE_URL ) && false === filter_var( $url, FILTER_VALIDATE_IP ) ) {
return false;
}
return true;
}
}
<?php
/**
* Assorted helpers
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
<?php
/**
* Trait file for Singletons.
*
* @package Camo_Image_Proxy
*/
namespace Camo_Image_Proxy;
/**
* Make a class into a singleton.
*/
trait Singleton {
/**
* Existing instance.
*
* @var object
*/
protected static $instance;
/**
* Get class instance.
*
* @return object
*/
public static function instance() {
if ( ! isset( static::$instance ) ) {
static::$instance = new static();
static::$instance->setup();
}
return static::$instance;
}
/**
* Setup the singleton.
*/
public function setup() {
// Silence.
}
}
......@@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Camo Image Proxy 0.1.0\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/camo-image-proxy\n"
"POT-Creation-Date: 2018-02-18 19:07:54+00:00\n"
"POT-Creation-Date: 2018-02-19 01:54:23+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
......@@ -24,10 +24,22 @@ msgstr ""
"X-Poedit-Bookmarks: \n"
"X-Textdomain-Support: yes\n"
#: inc/class-options-page.php:43
msgid "Host"
msgstr ""
#: inc/class-options-page.php:44
msgid "Shared Key"
msgstr ""
#. Plugin Name of the plugin/theme
msgid "Camo Image Proxy"
msgstr ""
#: inc/class-options.php:45
msgid "Invalid property requested."
msgstr ""
#. Plugin URI of the plugin/theme
msgid "https://ethitter.com/plugins/"
msgstr ""
......
......@@ -3,6 +3,7 @@ Contributors: ethitter
Donate link: https://ethitter.com/donate/
Tags: image, proxy, cdn
Requires at least: 4.9
Requires PHP: 7.0
Tested up to: 4.9
Stable tag: 0.1.0
License: GPLv2 or later
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment