installed plugin Subscribe2 version 10.35

This commit is contained in:
2021-07-25 23:28:47 +00:00
committed by Gitium
parent 13a3f7b718
commit b69f6155de
63 changed files with 15023 additions and 0 deletions

View File

@ -0,0 +1,21 @@
{
"name": "appsero/client",
"description": "Appsero Client",
"keywords": ["analytics", "wordpress", "plugin", "theme"],
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Tareq Hasan",
"email": "tareq@appsero.com"
}
],
"autoload": {
"psr-4": {
"Appsero\\": "src/"
}
},
"require": {
"php": ">=5.3"
}
}

View File

@ -0,0 +1,206 @@
# Appsero - Client
- [Installation](#installation)
- [Insights](#insights)
- [Dynamic Usage](#dynamic-usage)
## Installation
You can install AppSero Client in two ways, via composer and manually.
### 1. Composer Installation
Add dependency in your project (theme/plugin):
```
composer require appsero/client
```
Now add `autoload.php` in your file if you haven't done already.
```php
require __DIR__ . '/vendor/autoload.php';
```
### 2. Manual Installation
Clone the repository in your project.
```
cd /path/to/your/project/folder
git clone https://github.com/AppSero/client.git appsero
```
Now include the dependencies in your plugin/theme.
```php
require __DIR__ . '/appsero/src/Client.php';
```
## Insights
AppSero can be used in both themes and plugins.
The `Appsero\Client` class has *three* parameters:
```php
$client = new Appsero\Client( $hash, $name, $file );
```
- **hash** (*string*, *required*) - The unique identifier for a plugin or theme.
- **name** (*string*, *required*) - The name of the plugin or theme.
- **file** (*string*, *required*) - The **main file** path of the plugin. For theme, path to `functions.php`
### Usage Example
Please refer to the **installation** step before start using the class.
You can obtain the **hash** for your plugin for the [Appsero Dashboard](https://dashboard.appsero.com). The 3rd parameter **must** have to be the main file of the plugin.
```php
/**
* Initialize the tracker
*
* @return void
*/
function appsero_init_tracker_appsero_test() {
if ( ! class_exists( 'Appsero\Client' ) ) {
require_once __DIR__ . '/appsero/src/Client.php';
}
$client = new Appsero\Client( 'a4a8da5b-b419-4656-98e9-4a42e9044891', 'Akismet', __FILE__ );
// Active insights
$client->insights()->init();
// Active automatic updater
$client->updater();
// Active license page and checker
$args = array(
'type' => 'options',
'menu_title' => 'Akismet',
'page_title' => 'Akismet License Settings',
'menu_slug' => 'akismet_settings',
);
$client->license()->add_settings_page( $args );
}
appsero_init_tracker_appsero_test();
```
Make sure you call this function directly, never use any action hook to call this function.
> For plugins example code that needs to be used on your main plugin file.
> For themes example code that needs to be used on your themes `functions.php` file.
## More Usage
Sometimes you wouldn't want to show the notice, or want to customize the notice message. You can do that as well.
```php
$client = new Appsero\Client( 'a4a8da5b-b419-4656-98e9-4a42e9044892', 'Twenty Twelve', __FILE__ );
```
#### 1. Hiding the notice
```php
$client->insights()
->hide_notice()
->init();
```
#### 2. Customizing the notice message
```php
$client->insights()
->notice( 'My Custom Notice Message' )
->init();
```
#### 3. Adding extra data
You can add extra metadata from your theme or plugin. In that case, the **keys** has to be whitelisted from the Appsero dashboard.
`add_extra` method also support callback as parameter, If you need database call then callback is best for you.
```php
$metadata = array(
'key' => 'value',
'another' => 'another_value'
);
$client->insights()
->add_extra( $metadata )
->init();
```
or
```php
$metadata = function () {
return array(
'key' => 'value',
'another' => 'another_value'
);
};
$client->insights()
->add_extra( $metadata )
->init();
```
---
### Check License Validity
Check your plugin/theme is using with valid license or not, First create a global variable of `License` object then use it anywhere in your code.
If you are using it outside of same function make sure you global the variable before using the condition.
```php
$client = new Appsero\Client( 'a4a8da5b-b419-4656-98e9-4a42e9044892', 'Twenty Twelve', __FILE__ );
$args = array(
'type' => 'submenu',
'menu_title' => 'Twenty Twelve License',
'page_title' => 'Twenty Twelve License Settings',
'menu_slug' => 'twenty_twelve_settings',
'parent_slug' => 'themes.php',
);
global $twenty_twelve_license;
$twenty_twelve_license = $client->license();
$twenty_twelve_license->add_settings_page( $args );
if ( $twenty_twelve_license->is_valid() ) {
// Your special code here
}
Or check by pricing plan title
if ( $twenty_twelve_license->is_valid_by( 'title', 'Business' ) ) {
// Your special code here
}
```
### Use your own license form
You can easily manage license by creating a form using HTTP request. Call `license_form_submit` method from License object.
```php
global $twenty_twelve_license; // License object
$twenty_twelve_license->license_form_submit([
'_nonce' => wp_create_nonce( 'Twenty Twelve' ), // create a nonce with name
'_action' => 'active', // active, deactive
'license_key' => 'random-license-key', // no need to provide if you want to deactive
]);
if ( ! $twenty_twelve_license->error ) {
// license activated
$twenty_twelve_license->success; // Success message is here
} else {
$twenty_twelve_license->error; // has error message here
}
```
## Credits
Created and maintained by [Appsero](https://appsero.com).

View File

@ -0,0 +1,233 @@
<?php
namespace Appsero;
/**
* Appsero Client
*
* This class is necessary to set project data
*/
class Client {
/**
* The client version
*
* @var string
*/
public $version = '1.1.11';
/**
* Hash identifier of the plugin
*
* @var string
*/
public $hash;
/**
* Name of the plugin
*
* @var string
*/
public $name;
/**
* The plugin/theme file path
* @example .../wp-content/plugins/test-slug/test-slug.php
*
* @var string
*/
public $file;
/**
* Main plugin file
* @example test-slug/test-slug.php
*
* @var string
*/
public $basename;
/**
* Slug of the plugin
* @example test-slug
*
* @var string
*/
public $slug;
/**
* The project version
*
* @var string
*/
public $project_version;
/**
* The project type
*
* @var string
*/
public $type;
/**
* textdomain
*
* @var string
*/
public $textdomain;
/**
* Initialize the class
*
* @param string $hash hash of the plugin
* @param string $name readable name of the plugin
* @param string $file main plugin file path
*/
public function __construct( $hash, $name, $file ) {
$this->hash = $hash;
$this->name = $name;
$this->file = $file;
$this->set_basename_and_slug();
}
/**
* Initialize insights class
*
* @return Appsero\Insights
*/
public function insights() {
if ( ! class_exists( __NAMESPACE__ . '\Insights') ) {
require_once __DIR__ . '/Insights.php';
}
return new Insights( $this );
}
/**
* Initialize plugin/theme updater
*
* @return Appsero\Updater
*/
public function updater() {
if ( ! class_exists( __NAMESPACE__ . '\Updater') ) {
require_once __DIR__ . '/Updater.php';
}
return new Updater( $this );
}
/**
* Initialize license checker
*
* @return Appsero\License
*/
public function license() {
if ( ! class_exists( __NAMESPACE__ . '\License') ) {
require_once __DIR__ . '/License.php';
}
return new License( $this );
}
/**
* API Endpoint
*
* @return string
*/
public function endpoint() {
$endpoint = apply_filters( 'appsero_endpoint', 'https://api.appsero.com' );
return trailingslashit( $endpoint );
}
/**
* Set project basename, slug and version
*
* @return void
*/
protected function set_basename_and_slug() {
if ( strpos( $this->file, WP_CONTENT_DIR . '/themes/' ) === false ) {
$this->basename = plugin_basename( $this->file );
list( $this->slug, $mainfile) = explode( '/', $this->basename );
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$plugin_data = get_plugin_data( $this->file );
$this->project_version = $plugin_data['Version'];
$this->type = 'plugin';
$this->textdomain = $this->slug;
} else {
$this->basename = str_replace( WP_CONTENT_DIR . '/themes/', '', $this->file );
list( $this->slug, $mainfile) = explode( '/', $this->basename );
$theme = wp_get_theme( $this->slug );
$this->project_version = $theme->version;
$this->type = 'theme';
}
}
/**
* Send request to remote endpoint
*
* @param array $params
* @param string $route
*
* @return array|WP_Error Array of results including HTTP headers or WP_Error if the request failed.
*/
public function send_request( $params, $route, $blocking = false ) {
$url = $this->endpoint() . $route;
$headers = array(
'user-agent' => 'Appsero/' . md5( esc_url( home_url() ) ) . ';',
'Accept' => 'application/json',
);
$response = wp_remote_post( $url, array(
'method' => 'POST',
'timeout' => 30,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => $blocking,
'headers' => $headers,
'body' => array_merge( $params, array( 'client' => $this->version ) ),
'cookies' => array()
) );
return $response;
}
/**
* Check if the current server is localhost
*
* @return boolean
*/
public function is_local_server() {
return in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
}
/**
* Translate function _e()
*/
public function _etrans( $text ) {
call_user_func( '_e', $text, $this->textdomain );
}
/**
* Translate function __()
*/
public function __trans( $text ) {
return call_user_func( '__', $text, $this->textdomain );
}
}

View File

@ -0,0 +1,972 @@
<?php
namespace Appsero;
/**
* Appsero Insights
*
* This is a tracker class to track plugin usage based on if the customer has opted in.
* No personal information is being tracked by this class, only general settings, active plugins, environment details
* and admin email.
*/
class Insights {
/**
* The notice text
*
* @var string
*/
public $notice;
/**
* Wheather to the notice or not
*
* @var boolean
*/
protected $show_notice = true;
/**
* If extra data needs to be sent
*
* @var array
*/
protected $extra_data = array();
/**
* AppSero\Client
*
* @var object
*/
protected $client;
/**
* Initialize the class
*
* @param AppSero\Client
*/
public function __construct( $client, $name = null, $file = null ) {
if ( is_string( $client ) && ! empty( $name ) && ! empty( $file ) ) {
$client = new Client( $client, $name, $file );
}
if ( is_object( $client ) && is_a( $client, 'Appsero\Client' ) ) {
$this->client = $client;
}
}
/**
* Don't show the notice
*
* @return \self
*/
public function hide_notice() {
$this->show_notice = false;
return $this;
}
/**
* Add extra data if needed
*
* @param array $data
*
* @return \self
*/
public function add_extra( $data = array() ) {
$this->extra_data = $data;
return $this;
}
/**
* Set custom notice text
*
* @param string $text
*
* @return \self
*/
public function notice( $text ) {
$this->notice = $text;
return $this;
}
/**
* Initialize insights
*
* @return void
*/
public function init() {
if ( $this->client->type == 'plugin' ) {
$this->init_plugin();
} else if ( $this->client->type == 'theme' ) {
$this->init_theme();
}
}
/**
* Initialize theme hooks
*
* @return void
*/
public function init_theme() {
$this->init_common();
add_action( 'switch_theme', array( $this, 'deactivation_cleanup' ) );
add_action( 'switch_theme', array( $this, 'theme_deactivated' ), 12, 3 );
}
/**
* Initialize plugin hooks
*
* @return void
*/
public function init_plugin() {
// plugin deactivate popup
if ( ! $this->is_local_server() ) {
add_filter( 'plugin_action_links_' . $this->client->basename, array( $this, 'plugin_action_links' ) );
add_action( 'admin_footer', array( $this, 'deactivate_scripts' ) );
}
$this->init_common();
register_activation_hook( $this->client->file, array( $this, 'activate_plugin' ) );
register_deactivation_hook( $this->client->file, array( $this, 'deactivation_cleanup' ) );
}
/**
* Initialize common hooks
*
* @return void
*/
protected function init_common() {
if ( $this->show_notice ) {
// tracking notice
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
}
add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
// uninstall reason
add_action( 'wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array( $this, 'uninstall_reason_submission' ) );
// cron events
add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
add_action( $this->client->slug . '_tracker_send_event', array( $this, 'send_tracking_data' ) );
// add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
}
/**
* Send tracking data to AppSero server
*
* @param boolean $override
*
* @return void
*/
public function send_tracking_data( $override = false ) {
// skip on AJAX Requests
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return;
}
if ( ! $this->tracking_allowed() && ! $override ) {
return;
}
// Send a maximum of once per week
$last_send = $this->get_last_send();
if ( $last_send && $last_send > strtotime( '-1 week' ) ) {
return;
}
$response = $this->client->send_request( $this->get_tracking_data(), 'track' );
update_option( $this->client->slug . '_tracking_last_send', time() );
}
/**
* Get the tracking data points
*
* @return array
*/
protected function get_tracking_data() {
$all_plugins = $this->get_all_plugins();
$users = get_users( array(
'role' => 'administrator',
'orderby' => 'ID',
'order' => 'ASC',
'number' => 1,
'paged' => 1,
) );
$admin_user = ( is_array( $users ) && ! empty( $users ) ) ? $users[0] : false;
$first_name = $last_name = '';
if ( $admin_user ) {
$first_name = $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name;
$last_name = $admin_user->last_name;
}
$data = array(
'version' => $this->client->project_version,
'url' => esc_url( home_url() ),
'site' => $this->get_site_name(),
'admin_email' => get_option( 'admin_email' ),
'first_name' => $first_name,
'last_name' => $last_name,
'hash' => $this->client->hash,
'server' => $this->get_server_info(),
'wp' => $this->get_wp_info(),
'users' => $this->get_user_counts(),
'active_plugins' => count( $all_plugins['active_plugins'] ),
'inactive_plugins' => count( $all_plugins['inactive_plugins'] ),
'ip_address' => $this->get_user_ip_address(),
'theme' => get_stylesheet(),
'version' => $this->client->project_version,
);
// Add metadata
if ( $extra = $this->get_extra_data() ) {
$data['extra'] = $extra;
}
return apply_filters( $this->client->slug . '_tracker_data', $data );
}
/**
* If a child class wants to send extra data
*
* @return mixed
*/
protected function get_extra_data() {
if ( is_callable( $this->extra_data ) ) {
return call_user_func( $this->extra_data );
}
if ( is_array( $this->extra_data ) ) {
return $this->extra_data;
}
return array();
}
/**
* Explain the user which data we collect
*
* @return string
*/
protected function data_we_collect() {
$data = array(
'Server environment details (php, mysql, server, WordPress versions)',
'Number of users in your site',
'Site language',
'Number of active and inactive plugins',
'Site name and url',
'Your name and email address',
);
return $data;
}
/**
* Check if the user has opted into tracking
*
* @return bool
*/
public function tracking_allowed() {
$allow_tracking = get_option( $this->client->slug . '_allow_tracking', 'no' );
return $allow_tracking == 'yes';
}
/**
* Get the last time a tracking was sent
*
* @return false|string
*/
private function get_last_send() {
return get_option( $this->client->slug . '_tracking_last_send', false );
}
/**
* Check if the notice has been dismissed or enabled
*
* @return boolean
*/
private function notice_dismissed() {
$hide_notice = get_option( $this->client->slug . '_tracking_notice', null );
if ( 'hide' == $hide_notice ) {
return true;
}
return false;
}
/**
* Check if the current server is localhost
*
* @return boolean
*/
private function is_local_server() {
return false;
$is_local = in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
return apply_filters( 'appsero_is_local', $is_local );
}
/**
* Schedule the event weekly
*
* @return void
*/
private function schedule_event() {
$hook_name = $this->client->slug . '_tracker_send_event';
if ( ! wp_next_scheduled( $hook_name ) ) {
wp_schedule_event( time(), 'weekly', $hook_name );
}
}
/**
* Clear any scheduled hook
*
* @return void
*/
private function clear_schedule_event() {
wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
}
/**
* Display the admin notice to users that have not opted-in or out
*
* @return void
*/
public function admin_notice() {
if ( $this->notice_dismissed() ) {
return;
}
if ( $this->tracking_allowed() ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// don't show tracking if a local server
if ( ! $this->is_local_server() ) {
$optin_url = add_query_arg( $this->client->slug . '_tracker_optin', 'true' );
$optout_url = add_query_arg( $this->client->slug . '_tracker_optout', 'true' );
if ( empty( $this->notice ) ) {
$notice = sprintf( $this->client->__trans( 'Want to help make <strong>%1$s</strong> even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.' ), $this->client->name );
} else {
$notice = $this->notice;
}
$policy_url = 'https://' . 'appsero.com/privacy-policy/';
$notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . $this->client->__trans( 'what we collect' ) . '</a>)';
$notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked. ';
$notice .= 'We are using Appsero to collect your data. <a href="' . $policy_url . '">Learn more</a> about how Appsero collects and handle your data.</p>';
echo '<div class="updated"><p>';
echo $notice;
echo '</p><p class="submit">';
echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-primary button-large">' . $this->client->__trans( 'Allow' ) . '</a>';
echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary button-large">' . $this->client->__trans( 'No thanks' ) . '</a>';
echo '</p></div>';
echo "<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
e.preventDefault();
jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
});
</script>
";
}
}
/**
* handle the optin/optout
*
* @return void
*/
public function handle_optin_optout() {
if ( isset( $_GET[ $this->client->slug . '_tracker_optin' ] ) && $_GET[ $this->client->slug . '_tracker_optin' ] == 'true' ) {
$this->optin();
wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optin' ) );
exit;
}
if ( isset( $_GET[ $this->client->slug . '_tracker_optout' ] ) && $_GET[ $this->client->slug . '_tracker_optout' ] == 'true' ) {
$this->optout();
wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optout' ) );
exit;
}
}
/**
* Tracking optin
*
* @return void
*/
public function optin() {
update_option( $this->client->slug . '_allow_tracking', 'yes' );
update_option( $this->client->slug . '_tracking_notice', 'hide' );
$this->clear_schedule_event();
$this->schedule_event();
$this->send_tracking_data();
}
/**
* Optout from tracking
*
* @return void
*/
public function optout() {
update_option( $this->client->slug . '_allow_tracking', 'no' );
update_option( $this->client->slug . '_tracking_notice', 'hide' );
$this->clear_schedule_event();
}
/**
* Get the number of post counts
*
* @param string $post_type
*
* @return integer
*/
public function get_post_count( $post_type ) {
global $wpdb;
return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
}
/**
* Get server related info.
*
* @return array
*/
private static function get_server_info() {
global $wpdb;
$server_data = array();
if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
$server_data['software'] = $_SERVER['SERVER_SOFTWARE'];
}
if ( function_exists( 'phpversion' ) ) {
$server_data['php_version'] = phpversion();
}
$server_data['mysql_version'] = $wpdb->db_version();
$server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
$server_data['php_default_timezone'] = date_default_timezone_get();
$server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
$server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
$server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
return $server_data;
}
/**
* Get WordPress related data.
*
* @return array
*/
private function get_wp_info() {
$wp_data = array();
$wp_data['memory_limit'] = WP_MEMORY_LIMIT;
$wp_data['debug_mode'] = ( defined('WP_DEBUG') && WP_DEBUG ) ? 'Yes' : 'No';
$wp_data['locale'] = get_locale();
$wp_data['version'] = get_bloginfo( 'version' );
$wp_data['multisite'] = is_multisite() ? 'Yes' : 'No';
return $wp_data;
}
/**
* Get the list of active and inactive plugins
*
* @return array
*/
private function get_all_plugins() {
// Ensure get_plugins function is loaded
if ( ! function_exists( 'get_plugins' ) ) {
include ABSPATH . '/wp-admin/includes/plugin.php';
}
$plugins = get_plugins();
$active_plugins_keys = get_option( 'active_plugins', array() );
$active_plugins = array();
foreach ( $plugins as $k => $v ) {
// Take care of formatting the data how we want it.
$formatted = array();
$formatted['name'] = strip_tags( $v['Name'] );
if ( isset( $v['Version'] ) ) {
$formatted['version'] = strip_tags( $v['Version'] );
}
if ( isset( $v['Author'] ) ) {
$formatted['author'] = strip_tags( $v['Author'] );
}
if ( isset( $v['Network'] ) ) {
$formatted['network'] = strip_tags( $v['Network'] );
}
if ( isset( $v['PluginURI'] ) ) {
$formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
}
if ( in_array( $k, $active_plugins_keys ) ) {
// Remove active plugins from list so we can show active and inactive separately
unset( $plugins[$k] );
$active_plugins[$k] = $formatted;
} else {
$plugins[$k] = $formatted;
}
}
return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
}
/**
* Get user totals based on user role.
*
* @return array
*/
public function get_user_counts() {
$user_count = array();
$user_count_data = count_users();
$user_count['total'] = $user_count_data['total_users'];
// Get user count based on user role
foreach ( $user_count_data['avail_roles'] as $role => $count ) {
$user_count[ $role ] = $count;
}
return $user_count;
}
/**
* Add weekly cron schedule
*
* @param array $schedules
*
* @return array
*/
public function add_weekly_schedule( $schedules ) {
$schedules['weekly'] = array(
'interval' => DAY_IN_SECONDS * 7,
'display' => 'Once Weekly',
);
return $schedules;
}
/**
* Plugin activation hook
*
* @return void
*/
public function activate_plugin() {
$allowed = get_option( $this->client->slug . '_allow_tracking', 'no' );
// if it wasn't allowed before, do nothing
if ( 'yes' !== $allowed ) {
return;
}
// re-schedule and delete the last sent time so we could force send again
$hook_name = $this->client->slug . '_tracker_send_event';
if ( ! wp_next_scheduled( $hook_name ) ) {
wp_schedule_event( time(), 'weekly', $hook_name );
}
delete_option( $this->client->slug . '_tracking_last_send' );
$this->send_tracking_data( true );
}
/**
* Clear our options upon deactivation
*
* @return void
*/
public function deactivation_cleanup() {
$this->clear_schedule_event();
if ( 'theme' == $this->client->type ) {
delete_option( $this->client->slug . '_tracking_last_send' );
delete_option( $this->client->slug . '_allow_tracking' );
}
delete_option( $this->client->slug . '_tracking_notice' );
}
/**
* Hook into action links and modify the deactivate link
*
* @param array $links
*
* @return array
*/
public function plugin_action_links( $links ) {
if ( array_key_exists( 'deactivate', $links ) ) {
$links['deactivate'] = str_replace( '<a', '<a class="' . $this->client->slug . '-deactivate-link"', $links['deactivate'] );
}
return $links;
}
/**
* Plugin uninstall reasons
*
* @return array
*/
private function get_uninstall_reasons() {
$reasons = array(
array(
'id' => 'could-not-understand',
'text' => "I couldn't understand how to make it work",
'type' => 'textarea',
'placeholder' => 'Would you like us to assist you?'
),
array(
'id' => 'found-better-plugin',
'text' => 'I found a better plugin',
'type' => 'text',
'placeholder' => 'Which plugin?'
),
array(
'id' => 'not-have-that-feature',
'text' => 'The plugin is great, but I need specific feature that you don\'t support',
'type' => 'textarea',
'placeholder' => 'Could you tell us more about that feature?'
),
array(
'id' => 'is-not-working',
'text' => 'The plugin is not working',
'type' => 'textarea',
'placeholder' => 'Could you tell us a bit more whats not working?'
),
array(
'id' => 'looking-for-other',
'text' => "It's not what I was looking for",
'type' => '',
'placeholder' => ''
),
array(
'id' => 'did-not-work-as-expected',
'text' => "The plugin didn't work as expected",
'type' => 'textarea',
'placeholder' => 'What did you expect?'
),
array(
'id' => 'other',
'text' => 'Other',
'type' => 'textarea',
'placeholder' => 'Could you tell us a bit more?'
),
);
return $reasons;
}
/**
* Plugin deactivation uninstall reason submission
*
* @return void
*/
public function uninstall_reason_submission() {
if ( ! isset( $_POST['reason_id'] ) ) {
wp_send_json_error();
}
$current_user = wp_get_current_user();
$data = array(
'hash' => $this->client->hash,
'reason_id' => sanitize_text_field( $_POST['reason_id'] ),
'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
'site' => $this->get_site_name(),
'url' => esc_url( home_url() ),
'admin_email' => get_option( 'admin_email' ),
'user_email' => $current_user->user_email,
'first_name' => $current_user->first_name,
'last_name' => $current_user->last_name,
'server' => $this->get_server_info(),
'wp' => $this->get_wp_info(),
'ip_address' => $this->get_user_ip_address(),
'theme' => get_stylesheet(),
'version' => $this->client->project_version,
);
// Add metadata
if ( $extra = $this->get_extra_data() ) {
$data['extra'] = $extra;
}
$this->client->send_request( $data, 'deactivate' );
wp_send_json_success();
}
/**
* Handle the plugin deactivation feedback
*
* @return void
*/
public function deactivate_scripts() {
global $pagenow;
if ( 'plugins.php' != $pagenow ) {
return;
}
$reasons = $this->get_uninstall_reasons();
?>
<div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
<div class="wd-dr-modal-wrap">
<div class="wd-dr-modal-header">
<h3><?php $this->client->_etrans( 'If you have a moment, please let us know why you are deactivating:' ); ?></h3>
</div>
<div class="wd-dr-modal-body">
<ul class="reasons">
<?php foreach ($reasons as $reason) { ?>
<li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
<label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
</li>
<?php } ?>
</ul>
<p class="wd-dr-modal-reasons-bottom">
We share your data with <a href="<?php echo 'https://appsero.com'; ?>">Appsero</a> to troubleshoot problems &amp; make product improvements.
<a href="<?php echo 'https://appsero.com/privacy-policy'; ?>">Learn more</a> about how Appsero handles your data.
</p>
</div>
<div class="wd-dr-modal-footer">
<a href="#" class="dont-bother-me"><?php $this->client->_etrans( "I rather wouldn't say" ); ?></a>
<button class="button-secondary"><?php $this->client->_etrans( 'Submit & Deactivate' ); ?></button>
<button class="button-primary"><?php $this->client->_etrans( 'Cancel' ); ?></button>
</div>
</div>
</div>
<style type="text/css">
.wd-dr-modal {
position: fixed;
z-index: 99999;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,0.5);
display: none;
}
.wd-dr-modal.modal-active {
display: block;
}
.wd-dr-modal-wrap {
width: 475px;
position: relative;
margin: 10% auto;
background: #fff;
}
.wd-dr-modal-header {
border-bottom: 1px solid #eee;
padding: 8px 20px;
}
.wd-dr-modal-header h3 {
line-height: 150%;
margin: 0;
}
.wd-dr-modal-body {
padding: 5px 20px 20px 20px;
}
.wd-dr-modal-body .reason-input {
margin-top: 5px;
margin-left: 20px;
}
.wd-dr-modal-footer {
border-top: 1px solid #eee;
padding: 12px 20px;
text-align: right;
}
.wd-dr-modal-reasons-bottom {
margin: 15px 0 0 0;
}
</style>
<script type="text/javascript">
(function($) {
$(function() {
var modal = $( '#<?php echo $this->client->slug; ?>-wd-dr-modal' );
var deactivateLink = '';
$( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
e.preventDefault();
modal.addClass('modal-active');
deactivateLink = $(this).attr('href');
modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
});
modal.on('click', 'button.button-primary', function(e) {
e.preventDefault();
modal.removeClass('modal-active');
});
modal.on('click', 'input[type="radio"]', function () {
var parent = $(this).parents('li:first');
modal.find('.reason-input').remove();
var inputType = parent.data('type'),
inputPlaceholder = parent.data('placeholder'),
reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
if ( inputType !== '' ) {
parent.append( $(reasonInputHtml) );
parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
}
});
modal.on('click', 'button.button-secondary', function(e) {
e.preventDefault();
var button = $(this);
if ( button.hasClass('disabled') ) {
return;
}
var $radio = $( 'input[type="radio"]:checked', modal );
var $selected_reason = $radio.parents('li:first'),
$input = $selected_reason.find('textarea, input[type="text"]');
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason',
reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
},
beforeSend: function() {
button.addClass('disabled');
button.text('Processing...');
},
complete: function() {
window.location.href = deactivateLink;
}
});
});
});
}(jQuery));
</script>
<?php
}
/**
* Run after theme deactivated
* @param string $new_name
* @param object $new_theme
* @param object $old_theme
* @return void
*/
public function theme_deactivated( $new_name, $new_theme, $old_theme ) {
// Make sure this is appsero theme
if ( $old_theme->get_template() == $this->client->slug ) {
$current_user = wp_get_current_user();
$data = array(
'hash' => $this->client->hash,
'reason_id' => 'none',
'reason_info' => '',
'site' => $this->get_site_name(),
'url' => esc_url( home_url() ),
'admin_email' => get_option( 'admin_email' ),
'user_email' => $current_user->user_email,
'first_name' => $current_user->first_name,
'last_name' => $current_user->last_name,
'server' => $this->get_server_info(),
'wp' => $this->get_wp_info(),
'ip_address' => $this->get_user_ip_address(),
'theme' => get_stylesheet(),
'version' => $this->client->project_version,
);
$this->client->send_request( $data, 'deactivate' );
}
}
/**
* Get user IP Address
*/
private function get_user_ip_address() {
$response = wp_remote_get( 'https://icanhazip.com/' );
if ( is_wp_error( $response ) ) {
return '';
}
$ip = trim( wp_remote_retrieve_body( $response ) );
if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
return '';
}
return $ip;
}
/**
* Get site name
*/
private function get_site_name() {
$site_name = get_bloginfo( 'name' );
if ( empty( $site_name ) ) {
$site_name = get_bloginfo( 'description' );
$site_name = wp_trim_words( $site_name, 3, '' );
}
if ( empty( $site_name ) ) {
$site_name = esc_url( home_url() );
}
return $site_name;
}
}

View File

@ -0,0 +1,705 @@
<?php
namespace Appsero;
/**
* Appsero License Checker
*
* This class will check, active and deactive license
*/
class License {
/**
* AppSero\Client
*
* @var object
*/
protected $client;
/**
* Arguments of create menu
*
* @var array
*/
protected $menu_args;
/**
* `option_name` of `wp_options` table
*
* @var string
*/
protected $option_key;
/**
* Error message of HTTP request
*
* @var string
*/
public $error;
/**
* Success message on form submit
*
* @var string
*/
public $success;
/**
* Corn schedule hook name
*
* @var string
*/
protected $schedule_hook;
/**
* Set value for valid licnese
*
* @var boolean
*/
private $is_valid_licnese = null;
/**
* Initialize the class
*
* @param Appsero\Client
*/
public function __construct( Client $client ) {
$this->client = $client;
$this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
$this->schedule_hook = $this->client->slug . '_license_check_event';
// Run hook to check license status daily
add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
// Active/Deactive corn schedule
$this->run_schedule();
}
/**
* Check license
*
* @return boolean
*/
public function check( $license_key ) {
$route = 'public/license/' . $this->client->hash . '/check';
return $this->send_request( $license_key, $route );
}
/**
* Active a license
*
* @return boolean
*/
public function activate( $license_key ) {
$route = 'public/license/' . $this->client->hash . '/activate';
return $this->send_request( $license_key, $route );
}
/**
* Deactivate a license
*
* @return boolean
*/
public function deactivate( $license_key ) {
$route = 'public/license/' . $this->client->hash . '/deactivate';
return $this->send_request( $license_key, $route );
}
/**
* Send common request
*
* @param $license_key
* @param $route
*
* @return array
*/
protected function send_request( $license_key, $route ) {
$params = array(
'license_key' => $license_key,
'url' => esc_url( home_url() ),
'is_local' => $this->client->is_local_server(),
);
$response = $this->client->send_request( $params, $route, true );
if ( is_wp_error( $response ) ) {
return array(
'success' => false,
'error' => $response->get_error_message()
);
}
$response = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $response ) || isset( $response['exception'] )) {
return array(
'success' => false,
'error' => 'Unknown error occurred, Please try again.'
);
}
if ( isset( $response['errors'] ) && isset( $response['errors']['license_key'] ) ) {
$response = array(
'success' => false,
'error' => $response['errors']['license_key'][0]
);
}
return $response;
}
/**
* Add settings page for license
*
* @param array $args
*
* @return void
*/
public function add_settings_page( $args = array() ) {
$defaults = array(
'type' => 'menu', // Can be: menu, options, submenu
'page_title' => 'Manage License',
'menu_title' => 'Manage License',
'capability' => 'manage_options',
'menu_slug' => $this->client->slug . '-manage-license',
'icon_url' => '',
'position' => null,
'parent_slug' => '',
);
$this->menu_args = wp_parse_args( $args, $defaults );
add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
}
/**
* Admin Menu hook
*
* @return void
*/
public function admin_menu() {
switch ( $this->menu_args['type'] ) {
case 'menu':
$this->create_menu_page();
break;
case 'submenu':
$this->create_submenu_page();
break;
case 'options':
$this->create_options_page();
break;
}
}
/**
* License menu output
*/
public function menu_output() {
if ( isset( $_POST['submit'] ) ) {
$this->license_form_submit( $_POST );
}
$license = get_option( $this->option_key, null );
$action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
$this->licenses_style();
?>
<div class="wrap appsero-license-settings-wrapper">
<h1>License Settings</h1>
<?php
$this->show_license_page_notices();
do_action( 'before_appsero_license_section' );
?>
<div class="appsero-license-settings appsero-license-section">
<?php $this->show_license_page_card_header(); ?>
<div class="appsero-license-details">
<p>Activate <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
<form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
<input type="hidden" name="_action" value="<?php echo $action; ?>">
<input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
<div class="license-input-fields">
<div class="license-input-key">
<svg enable-background="new 0 0 512 512" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<path d="m463.75 48.251c-64.336-64.336-169.01-64.335-233.35 1e-3 -43.945 43.945-59.209 108.71-40.181 167.46l-185.82 185.82c-2.813 2.813-4.395 6.621-4.395 10.606v84.858c0 8.291 6.709 15 15 15h84.858c3.984 0 7.793-1.582 10.605-4.395l21.211-21.226c3.237-3.237 4.819-7.778 4.292-12.334l-2.637-22.793 31.582-2.974c7.178-0.674 12.847-6.343 13.521-13.521l2.974-31.582 22.793 2.651c4.233 0.571 8.496-0.85 11.704-3.691 3.193-2.856 5.024-6.929 5.024-11.206v-27.929h27.422c3.984 0 7.793-1.582 10.605-4.395l38.467-37.958c58.74 19.043 122.38 4.929 166.33-39.046 64.336-64.335 64.336-169.01 0-233.35zm-42.435 106.07c-17.549 17.549-46.084 17.549-63.633 0s-17.549-46.084 0-63.633 46.084-17.549 63.633 0 17.548 46.084 0 63.633z"/>
</svg>
<input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
placeholder="Enter your license key to activate" name="license_key"
<?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
/>
</div>
<button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
<?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
</button>
</div>
</form>
<?php
if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
$this->show_active_license_info( $license );
}
?>
</div>
</div> <!-- /.appsero-license-settings -->
<?php do_action( 'after_appsero_license_section' ); ?>
</div>
<?php
}
/**
* License form submit
*/
public function license_form_submit( $form ) {
if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
$this->error = "Please add all information";
return;
}
if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
$this->error = "You don't have permission to manage license.";
return;
}
switch ( $form['_action'] ) {
case 'active':
$this->active_client_license( $form );
break;
case 'deactive':
$this->deactive_client_license( $form );
break;
}
}
/**
* Check license status on schedule
*/
public function check_license_status() {
$license = get_option( $this->option_key, null );
if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
$response = $this->check( $license['key'] );
if ( isset( $response['success'] ) && $response['success'] ) {
$license['status'] = 'activate';
$license['remaining'] = $response['remaining'];
$license['activation_limit'] = $response['activation_limit'];
$license['expiry_days'] = $response['expiry_days'];
$license['title'] = $response['title'];
$license['source_id'] = $response['source_identifier'];
$license['recurring'] = $response['recurring'];
} else {
$license['status'] = 'deactivate';
$license['expiry_days'] = 0;
}
update_option( $this->option_key, $license, false );
}
}
/**
* Check this is a valid license
*/
public function is_valid() {
if ( null !== $this->is_valid_licnese ) {
return $this->is_valid_licnese;
}
$license = get_option( $this->option_key, null );
if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
$this->is_valid_licnese = true;
} else {
$this->is_valid_licnese = false;
}
return $this->is_valid_licnese;
}
/**
* Check this is a valid license
*/
public function is_valid_by( $option, $value ) {
$license = get_option( $this->option_key, null );
if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
return true;
}
}
return false;
}
/**
* Styles for licenses page
*/
private function licenses_style() {
?>
<style type="text/css">
.appsero-license-section {
width: 100%;
max-width: 1100px;
min-height: 1px;
box-sizing: border-box;
}
.appsero-license-settings {
background-color: #fff;
box-shadow: 0px 3px 10px rgba(16, 16, 16, 0.05);
}
.appsero-license-settings * {
box-sizing: border-box;
}
.appsero-license-title {
background-color: #F8FAFB;
border-bottom: 2px solid #EAEAEA;
display: flex;
align-items: center;
padding: 10px 20px;
}
.appsero-license-title svg {
width: 30px;
height: 30px;
fill: #0082BF;
}
.appsero-license-title span {
font-size: 17px;
color: #444444;
margin-left: 10px;
}
.appsero-license-details {
padding: 20px;
}
.appsero-license-details p {
font-size: 15px;
margin: 0 0 20px 0;
}
.license-input-key {
position: relative;
flex: 0 0 72%;
max-width: 72%;
}
.license-input-key input {
background-color: #F9F9F9;
padding: 10px 15px 10px 48px;
border: 1px solid #E8E5E5;
border-radius: 3px;
height: 45px;
font-size: 16px;
color: #71777D;
width: 100%;
box-shadow: 0 0 0 transparent;
}
.license-input-key input:focus {
outline: 0 none;
border: 1px solid #E8E5E5;
box-shadow: 0 0 0 transparent;
}
.license-input-key svg {
width: 22px;
height: 22px;
fill: #0082BF;
position: absolute;
left: 14px;
top: 13px;
}
.license-input-fields {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
max-width: 850px;
width: 100%;
}
.license-input-fields button {
color: #fff;
font-size: 17px;
padding: 8px;
height: 46px;
background-color: #0082BF;
border-radius: 3px;
cursor: pointer;
flex: 0 0 25%;
max-width: 25%;
border: 1px solid #0082BF;
}
.license-input-fields button.deactive-button {
background-color: #E40055;
border-color: #E40055;
}
.license-input-fields button:focus {
outline: 0 none;
}
.active-license-info {
display: flex;
}
.single-license-info {
min-width: 220px;
flex: 0 0 30%;
}
.single-license-info h3 {
font-size: 18px;
margin: 0 0 12px 0;
}
.single-license-info p {
margin: 0;
color: #00C000;
}
.single-license-info p.occupied {
color: #E40055;
}
</style>
<?php
}
/**
* Show active license information
*/
private function show_active_license_info( $license ) {
?>
<div class="active-license-info">
<div class="single-license-info">
<h3>Activation Remaining</h3>
<?php if ( empty( $license['activation_limit'] ) ): ?>
<p>Unlimited</p>
<?php else: ?>
<p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
<?php echo $license['remaining']; ?> out of <?php echo $license['activation_limit']; ?>
</p>
<?php endif; ?>
</div>
<div class="single-license-info">
<h3>Expires in</h3>
<?php
if ( $license['recurring'] && false !== $license['expiry_days'] ) {
$occupied = $license['expiry_days'] > 10 ? '' : 'occupied';
echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
} else {
echo '<p>Never</p>';
}
?>
</div>
</div>
<?php
}
/**
* Show license settings page notices
*/
private function show_license_page_notices() {
if ( ! empty( $this->error ) ) :
?>
<div class="notice notice-error is-dismissible appsero-license-section">
<p><?php echo $this->error; ?></p>
</div>
<?php
endif;
if ( ! empty( $this->success ) ) :
?>
<div class="notice notice-success is-dismissible appsero-license-section">
<p><?php echo $this->success; ?></p>
</div>
<?php
endif;
echo '<br />';
}
/**
* Card header
*/
private function show_license_page_card_header() {
?>
<div class="appsero-license-title">
<svg enable-background="new 0 0 299.995 299.995" version="1.1" viewBox="0 0 300 300" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<path d="m150 161.48c-8.613 0-15.598 6.982-15.598 15.598 0 5.776 3.149 10.807 7.817 13.505v17.341h15.562v-17.341c4.668-2.697 7.817-7.729 7.817-13.505 0-8.616-6.984-15.598-15.598-15.598z"/>
<path d="m150 85.849c-13.111 0-23.775 10.665-23.775 23.775v25.319h47.548v-25.319c-1e-3 -13.108-10.665-23.775-23.773-23.775z"/>
<path d="m150 1e-3c-82.839 0-150 67.158-150 150 0 82.837 67.156 150 150 150s150-67.161 150-150c0-82.839-67.161-150-150-150zm46.09 227.12h-92.173c-9.734 0-17.626-7.892-17.626-17.629v-56.919c0-8.491 6.007-15.582 14.003-17.25v-25.697c0-27.409 22.3-49.711 49.711-49.711 27.409 0 49.709 22.3 49.709 49.711v25.697c7.993 1.673 14 8.759 14 17.25v56.919h2e-3c0 9.736-7.892 17.629-17.626 17.629z"/>
</svg>
<span>Activate License</span>
</div>
<?php
}
/**
* Active client license
*/
private function active_client_license( $form ) {
if ( empty( $form['license_key'] ) ) {
$this->error = 'The license key field is required.';
return;
}
$license_key = sanitize_text_field( $form['license_key'] );
$response = $this->activate( $license_key );
if ( ! $response['success'] ) {
$this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
return;
}
$data = array(
'key' => $license_key,
'status' => 'activate',
'remaining' => $response['remaining'],
'activation_limit' => $response['activation_limit'],
'expiry_days' => $response['expiry_days'],
'title' => $response['title'],
'source_id' => $response['source_identifier'],
'recurring' => $response['recurring'],
);
update_option( $this->option_key, $data, false );
$this->success = 'License activated successfully.';
}
/**
* Deactive client license
*/
private function deactive_client_license( $form ) {
$license = get_option( $this->option_key, null );
if ( empty( $license['key'] ) ) {
$this->error = 'License key not found.';
return;
}
$response = $this->deactivate( $license['key'] );
$data = array(
'key' => '',
'status' => 'deactivate',
);
update_option( $this->option_key, $data, false );
if ( ! $response['success'] ) {
$this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
return;
}
$this->success = 'License deactivated successfully.';
}
/**
* Add license menu page
*/
private function create_menu_page() {
call_user_func(
'add_' . 'menu' . '_page',
$this->menu_args['page_title'],
$this->menu_args['menu_title'],
$this->menu_args['capability'],
$this->menu_args['menu_slug'],
array( $this, 'menu_output' ),
$this->menu_args['icon_url'],
$this->menu_args['position']
);
}
/**
* Add submenu page
*/
private function create_submenu_page() {
call_user_func(
'add_' . 'submenu' . '_page',
$this->menu_args['parent_slug'],
$this->menu_args['page_title'],
$this->menu_args['menu_title'],
$this->menu_args['capability'],
$this->menu_args['menu_slug'],
array( $this, 'menu_output' ),
$this->menu_args['position']
);
}
/**
* Add submenu page
*/
private function create_options_page() {
call_user_func(
'add_' . 'options' . '_page',
$this->menu_args['page_title'],
$this->menu_args['menu_title'],
$this->menu_args['capability'],
$this->menu_args['menu_slug'],
array( $this, 'menu_output' ),
$this->menu_args['position']
);
}
/**
* Schedule daily sicense checker event
*/
public function schedule_cron_event() {
if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
wp_schedule_event( time(), 'daily', $this->schedule_hook );
wp_schedule_single_event( time() + 20, $this->schedule_hook );
}
}
/**
* Clear any scheduled hook
*/
public function clear_scheduler() {
wp_clear_scheduled_hook( $this->schedule_hook );
}
/**
* Enable/Disable schedule
*/
private function run_schedule() {
switch ( $this->client->type ) {
case 'plugin':
register_activation_hook( $this->client->file, array( $this, 'schedule_cron_event' ) );
register_deactivation_hook( $this->client->file, array( $this, 'clear_scheduler' ) );
break;
case 'theme':
add_action( 'after_switch_theme', array( $this, 'schedule_cron_event' ) );
add_action( 'switch_theme', array( $this, 'clear_scheduler' ) );
break;
}
}
/**
* Form action URL
*/
private function formActionUrl() {
echo add_query_arg(
array( 'page' => $_GET['page'] ),
admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
);
}
/**
* Get input license key
* @param $action
* @return $license
*/
private function get_input_license_value( $action, $license ) {
if ( 'active' == $action ) {
return isset( $license['key'] ) ? $license['key'] : '';
}
if ( 'deactive' == $action ) {
$key_length = strlen( $license['key'] );
return str_pad(
substr( $license['key'], 0, $key_length / 2 ), $key_length, '*'
);
}
return '';
}
}

View File

@ -0,0 +1,247 @@
<?php
namespace Appsero;
/**
* Appsero Updater
*
* This class will show new updates project
*/
class Updater {
/**
* Appsero\Client
*
* @var object
*/
protected $client;
/**
* Initialize the class
*
* @param Appsero\Client
*/
public function __construct( Client $client ) {
$this->client = $client;
$this->cache_key = 'appsero_' . md5( $this->client->slug ) . '_version_info';
// Run hooks.
if ( $this->client->type == 'plugin' ) {
$this->run_plugin_hooks();
} elseif ( $this->client->type == 'theme' ) {
$this->run_theme_hooks();
}
}
/**
* Set up WordPress filter to hooks to get update.
*
* @return void
*/
public function run_plugin_hooks() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_plugin_update' ) );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
}
/**
* Set up WordPress filter to hooks to get update.
*
* @return void
*/
public function run_theme_hooks() {
add_filter( 'pre_set_site_transient_update_themes', array( $this, 'check_theme_update' ) );
}
/**
* Check for Update for this specific project
*/
public function check_plugin_update( $transient_data ) {
global $pagenow;
if ( ! is_object( $transient_data ) ) {
$transient_data = new \stdClass;
}
if ( 'plugins.php' == $pagenow && is_multisite() ) {
return $transient_data;
}
if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->basename ] ) ) {
return $transient_data;
}
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->get_project_latest_version();
$this->set_cached_version_info( $version_info );
}
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
unset( $version_info->sections );
$transient_data->response[ $this->client->basename ] = $version_info;
}
$transient_data->last_checked = time();
$transient_data->checked[ $this->client->basename ] = $this->client->project_version;
}
return $transient_data;
}
/**
* Get version info from database
*
* @return Object or Boolean
*/
private function get_cached_version_info() {
$value = get_transient( $this->cache_key );
if( ! $value && ! isset( $value->name ) ) {
return false; // Cache is expired
}
// We need to turn the icons into an array
if ( isset( $value->icons ) ) {
$value->icons = (array) $value->icons;
}
// We need to turn the banners into an array
if ( isset( $value->banners ) ) {
$value->banners = (array) $value->banners;
}
if ( isset( $value->sections ) ) {
$value->sections = (array) $value->sections;
}
return $value;
}
/**
* Set version info to database
*/
private function set_cached_version_info( $value ) {
if ( ! $value ) {
return;
}
set_transient( $this->cache_key, $value, 3 * HOUR_IN_SECONDS );
}
/**
* Get plugin info from Appsero
*/
private function get_project_latest_version() {
$license_option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
$license = get_option( $license_option_key, null );
$params = array(
'version' => $this->client->project_version,
'name' => $this->client->name,
'slug' => $this->client->slug,
'basename' => $this->client->basename,
'license_key' => ! empty( $license ) && isset( $license['key'] ) ? $license['key'] : '',
);
$route = 'update/' . $this->client->hash . '/check';
$response = $this->client->send_request( $params, $route, true );
if ( is_wp_error( $response ) ) {
return false;
}
$response = json_decode( wp_remote_retrieve_body( $response ) );
if ( ! isset( $response->slug ) ) {
return false;
}
if ( isset( $response->icons ) ) {
$response->icons = (array) $response->icons;
}
if ( isset( $response->banners ) ) {
$response->banners = (array) $response->banners;
}
if ( isset( $response->sections ) ) {
$response->sections = (array) $response->sections;
}
return $response;
}
/**
* Updates information on the "View version x.x details" page with custom data.
*
* @param mixed $data
* @param string $action
* @param object $args
*
* @return object $data
*/
public function plugins_api_filter( $data, $action = '', $args = null ) {
if ( $action != 'plugin_information' ) {
return $data;
}
if ( ! isset( $args->slug ) || ( $args->slug != $this->client->slug ) ) {
return $data;
}
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->get_project_latest_version();
$this->set_cached_version_info( $version_info );
}
return $version_info;
}
/**
* Check theme upate
*/
public function check_theme_update( $transient_data ) {
global $pagenow;
if ( ! is_object( $transient_data ) ) {
$transient_data = new \stdClass;
}
if ( 'themes.php' == $pagenow && is_multisite() ) {
return $transient_data;
}
if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->slug ] ) ) {
return $transient_data;
}
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->get_project_latest_version();
$this->set_cached_version_info( $version_info );
}
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
$transient_data->response[ $this->client->slug ] = (array) $version_info;
}
$transient_data->last_checked = time();
$transient_data->checked[ $this->client->slug ] = $this->client->project_version;
}
return $transient_data;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

View File

@ -0,0 +1,173 @@
<?php
// Handles options for subscribe2
// DO NOT EDIT THIS FILE AS IT IS SET BY THE OPTIONS PAGE
global $mysubscribe2;
if ( ! isset( $mysubscribe2->subscribe2_options['autosub'] ) ) {
$mysubscribe2->subscribe2_options['autosub'] = 'no';
} // option to autosubscribe registered users to new categories
if ( ! isset( $mysubscribe2->subscribe2_options['newreg_override'] ) ) {
$mysubscribe2->subscribe2_options['newreg_override'] = 'no';
} // option to autosubscribe registered users to new categories
if ( ! isset( $mysubscribe2->subscribe2_options['wpregdef'] ) ) {
$mysubscribe2->subscribe2_options['wpregdef'] = 'no';
} // option to check registration form box by default
if ( ! isset( $mysubscribe2->subscribe2_options['autoformat'] ) ) {
$mysubscribe2->subscribe2_options['autoformat'] = 'post';
} // option for default auto-subscription email format
if ( ! isset( $mysubscribe2->subscribe2_options['show_autosub'] ) ) {
$mysubscribe2->subscribe2_options['show_autosub'] = 'yes';
} // option to display auto-subscription option to registered users
if ( ! isset( $mysubscribe2->subscribe2_options['autosub_def'] ) ) {
$mysubscribe2->subscribe2_options['autosub_def'] = 'no';
} // option for user default auto-subscription to new categories
if ( ! isset( $mysubscribe2->subscribe2_options['comment_subs'] ) ) {
$mysubscribe2->subscribe2_options['comment_subs'] = 'no';
} // option for commenters to subscribe as public subscribers
if ( ! isset( $mysubscribe2->subscribe2_options['comment_def'] ) ) {
$mysubscribe2->subscribe2_options['comment_def'] = 'no';
} // option for comments box to be checked by default
if ( ! isset( $mysubscribe2->subscribe2_options['one_click_profile'] ) ) {
$mysubscribe2->subscribe2_options['one_click_profile'] = 'no';
} // option for displaying 'one-click' option on profile page
if ( ! isset( $mysubscribe2->subscribe2_options['bcclimit'] ) ) {
$mysubscribe2->subscribe2_options['bcclimit'] = 1;
} // option for default bcc limit on email notifications
if ( ! isset( $mysubscribe2->subscribe2_options['admin_email'] ) ) {
$mysubscribe2->subscribe2_options['admin_email'] = 'subs';
} // option for sending new subscriber notifications to admins
if ( ! isset( $mysubscribe2->subscribe2_options['tracking'] ) ) {
$mysubscribe2->subscribe2_options['tracking'] = '';
} // option for tracking
if ( ! isset( $mysubscribe2->subscribe2_options['s2page'] ) ) {
$mysubscribe2->subscribe2_options['s2page'] = 0;
} // option for default WordPress page for Subscribe2 to use
if ( ! isset( $mysubscribe2->subscribe2_options['s2_unsub_page'] ) ) {
$mysubscribe2->subscribe2_options['s2_unsub_page'] = 0;
} // option for default Subscribe2 unsubscribe page
if ( ! isset( $mysubscribe2->subscribe2_options['stylesheet'] ) ) {
$mysubscribe2->subscribe2_options['stylesheet'] = 'yes';
} // option to include link to theme stylesheet from HTML notifications
if ( ! isset( $mysubscribe2->subscribe2_options['embed'] ) ) {
$mysubscribe2->subscribe2_options['embed'] = 'no';
} // option to embed stylesheet and images into HTML emails
if ( ! isset( $mysubscribe2->subscribe2_options['pages'] ) ) {
$mysubscribe2->subscribe2_options['pages'] = 'no';
} // option for sending notifications for WordPress pages
if ( ! isset( $mysubscribe2->subscribe2_options['password'] ) ) {
$mysubscribe2->subscribe2_options['password'] = 'no';
} // option for sending notifications for posts that are password protected
if ( ! isset( $mysubscribe2->subscribe2_options['stickies'] ) ) {
$mysubscribe2->subscribe2_options['stickies'] = 'no';
} // option for including sticky posts in digest notifications
if ( ! isset( $mysubscribe2->subscribe2_options['private'] ) ) {
$mysubscribe2->subscribe2_options['private'] = 'no';
} // option for sending notifications for posts that are private
if ( ! isset( $mysubscribe2->subscribe2_options['email_freq'] ) ) {
$mysubscribe2->subscribe2_options['email_freq'] = 'never';
} // option for sending emails per-post or as a digest email on a cron schedule
if ( ! isset( $mysubscribe2->subscribe2_options['cron_order'] ) ) {
$mysubscribe2->subscribe2_options['cron_order'] = 'desc';
} // option for ordering of posts in digest email
if ( ! isset( $mysubscribe2->subscribe2_options['compulsory'] ) ) {
$mysubscribe2->subscribe2_options['compulsory'] = '';
} // option for compulsory categories
if ( ! isset( $mysubscribe2->subscribe2_options['exclude'] ) ) {
$mysubscribe2->subscribe2_options['exclude'] = '';
} // option for excluded categories
if ( ! isset( $mysubscribe2->subscribe2_options['sender'] ) ) {
$mysubscribe2->subscribe2_options['sender'] = 'blogname';
} // option for email notification sender
if ( ! isset( $mysubscribe2->subscribe2_options['reg_override'] ) ) {
$mysubscribe2->subscribe2_options['reg_override'] = '1';
} // option for excluded categories to be overriden for registered users
if ( ! isset( $mysubscribe2->subscribe2_options['show_meta'] ) ) {
$mysubscribe2->subscribe2_options['show_meta'] = '0';
} // option to display link to subscribe2 page from 'meta'
if ( ! isset( $mysubscribe2->subscribe2_options['show_button'] ) ) {
$mysubscribe2->subscribe2_options['show_button'] = '1';
} // option to show Subscribe2 button on Write page
if ( ! isset( $mysubscribe2->subscribe2_options['ajax'] ) ) {
$mysubscribe2->subscribe2_options['ajax'] = '0';
} // option to enable an AJAX style form
if ( ! isset( $mysubscribe2->subscribe2_options['widget'] ) ) {
$mysubscribe2->subscribe2_options['widget'] = '1';
} // option to enable Subscribe2 Widget
if ( ! isset( $mysubscribe2->subscribe2_options['counterwidget'] ) ) {
$mysubscribe2->subscribe2_options['counterwidget'] = '0';
} // option to enable Subscribe2 Counter Widget
if ( ! isset( $mysubscribe2->subscribe2_options['s2meta_default'] ) ) {
$mysubscribe2->subscribe2_options['s2meta_default'] = '0';
} // option for Subscribe2 over ride postmeta to be checked by default
if ( ! isset( $mysubscribe2->subscribe2_options['barred'] ) ) {
$mysubscribe2->subscribe2_options['barred'] = '';
} // option containing domains barred from public registration
if ( ! isset( $mysubscribe2->subscribe2_options['exclude_formats'] ) ) {
$mysubscribe2->subscribe2_options['exclude_formats'] = '';
} // option for excluding post formats as supported by the current theme
if ( ! isset( $mysubscribe2->subscribe2_options['mailtext'] ) ) {
$mysubscribe2->subscribe2_options['mailtext'] = __( "{BLOGNAME} has posted a new item, '{TITLE}'\n\n{POST}\n\nYou may view the latest post at\n{PERMALINK}\n\nYou received this e-mail because you asked to be notified when new updates are posted.\nBest regards,\n{MYNAME}\n{EMAIL}", 'subscribe2' );
} // Default notification email text
if ( ! isset( $mysubscribe2->subscribe2_options['notification_subject'] ) ) {
$mysubscribe2->subscribe2_options['notification_subject'] = '[{BLOGNAME}] {TITLE}';
} // Default notification email subject
if ( ! isset( $mysubscribe2->subscribe2_options['confirm_email'] ) ) {
$mysubscribe2->subscribe2_options['confirm_email'] = __( "{BLOGNAME} has received a request to {ACTION} for this email address. To complete your request please click on the link below:\n\n{LINK}\n\nIf you did not request this, please feel free to disregard this notice!\n\nThank you,\n{MYNAME}.", 'subscribe2' );
} // Default confirmation email text
if ( ! isset( $mysubscribe2->subscribe2_options['confirm_subject'] ) ) {
$mysubscribe2->subscribe2_options['confirm_subject'] = '[{BLOGNAME}] ' . __( 'Please confirm your request', 'subscribe2' );
} // Default confirmation email subject
if ( ! isset( $mysubscribe2->subscribe2_options['remind_email'] ) ) {
$mysubscribe2->subscribe2_options['remind_email'] = __( "This email address was subscribed for notifications at {BLOGNAME} ({BLOGLINK}) but the subscription remains incomplete.\n\nIf you wish to complete your subscription please click on the link below:\n\n{LINK}\n\nIf you do not wish to complete your subscription please ignore this email and your address will be removed from our database.\n\nRegards,\n{MYNAME}", 'subscribe2' );
} // Default reminder email text
if ( ! isset( $mysubscribe2->subscribe2_options['remind_subject'] ) ) {
$mysubscribe2->subscribe2_options['remind_subject'] = '[{BLOGNAME}] ' . __( 'Subscription Reminder', 'subscribe2' );
} // Default reminder email subject
if ( ! isset( $mysubscribe2->subscribe2_options['ajax'] ) ) {
$mysubscribe2->subscribe2_options['ajax'] = '';
} // Default frontend form setting
if ( ! isset( $mysubscribe2->subscribe2_options['js_ip_updater'] ) ) {
$mysubscribe2->subscribe2_options['js_ip_updater'] = '';
} // Default setting for using javascript to update form ip address

View File

@ -0,0 +1,106 @@
/* global s2AjaxScriptStrings */
// Version 1.0 - original version
// Version 1.1 - added position and minimum width and height attributes to .dialog
// Version 1.2 - added nonce use for form submission
// Version 1.3 - eslinted
var s2jQuery = jQuery.noConflict();
s2jQuery( document ).ready(
function() {
var dialog = s2jQuery( '<div></div>' );
var ajaxurl = s2AjaxScriptStrings.ajaxurl;
s2jQuery( 'a.s2popup' ).click(
function( event ) {
var data = {
'action': 'subscribe2_form',
'data': s2jQuery( 'a.s2popup' ).attr( 'id' )
};
event.preventDefault();
jQuery.post(
ajaxurl,
data,
function( response ) {
dialog.html( response );
}
);
dialog.dialog(
{
modal: true,
zIndex: 10000,
minWidth: 350,
minHeight: 300,
title: s2AjaxScriptStrings.title
}
);
dialog.dialog( 'open' );
}
);
s2jQuery( document ).on(
'submit',
'#s2ajaxform',
function( event ) {
var email = s2jQuery( '#s2ajaxform input[name=email]' ).val();
var ip = s2jQuery( '#s2ajaxform input[name=ip]' ).val();
var firstname = s2jQuery( '#s2ajaxform input[name=firstname]' ).val();
var lastname = s2jQuery( '#s2ajaxform input[name=lastname]' ).val();
var uri = s2jQuery( '#s2ajaxform input[name=uri]' ).val();
var btn = s2jQuery( this ).find( 'input[type=submit][clicked=true]' );
var data;
event.preventDefault();
if ( 'undefined' === typeof firstname ) {
firstname = '';
}
if ( 'undefined' === typeof lastname ) {
lastname = '';
}
if ( 'undefined' === typeof uri ) {
uri = 'http://';
}
if ( btn.length && s2jQuery( '#s2ajaxform' ).has( btn ) ) {
data = {
'action': 'subscribe2_submit',
'nonce': s2AjaxScriptStrings.nonce,
'data': {
'email': email,
'ip': ip,
'firstname': firstname,
'lastname': lastname,
'uri': uri,
'button': btn.attr( 'name' )
}
};
jQuery.post(
ajaxurl,
data,
function( response ) {
dialog.html( response );
}
);
}
}
);
// Allows detection of which button was clicked
s2jQuery( document ).on(
'click',
'#s2ajaxform input[type=submit]',
function() {
s2jQuery( '#s2ajaxform input[type=submit]' ).removeAttr( 'clicked' );
s2jQuery( this ).attr( 'clicked', 'true' );
}
);
// when form is closed return to default
s2jQuery( document ).on(
'dialogclose',
function() {
dialog.html( dialog );
}
);
}
);

View File

@ -0,0 +1 @@
var s2jQuery=jQuery.noConflict();s2jQuery(document).ready(function(){var t=s2jQuery("<div></div>"),a=s2AjaxScriptStrings.ajaxurl;s2jQuery("a.s2popup").click(function(e){var i={action:"subscribe2_form",data:s2jQuery("a.s2popup").attr("id")};e.preventDefault(),jQuery.post(a,i,function(a){t.html(a)}),t.dialog({modal:!0,zIndex:1e4,minWidth:350,minHeight:300,title:s2AjaxScriptStrings.title}),t.dialog("open")}),s2jQuery(document).on("submit","#s2ajaxform",function(e){var i,n=s2jQuery("#s2ajaxform input[name=email]").val(),r=s2jQuery("#s2ajaxform input[name=ip]").val(),u=s2jQuery("#s2ajaxform input[name=firstname]").val(),s=s2jQuery("#s2ajaxform input[name=lastname]").val(),o=s2jQuery("#s2ajaxform input[name=uri]").val(),m=s2jQuery(this).find("input[type=submit][clicked=true]");e.preventDefault(),void 0===u&&(u=""),void 0===s&&(s=""),void 0===o&&(o="http://"),m.length&&s2jQuery("#s2ajaxform").has(m)&&(i={action:"subscribe2_submit",nonce:s2AjaxScriptStrings.nonce,data:{email:n,ip:r,firstname:u,lastname:s,uri:o,button:m.attr("name")}},jQuery.post(a,i,function(a){t.html(a)}))}),s2jQuery(document).on("click","#s2ajaxform input[type=submit]",function(){s2jQuery("#s2ajaxform input[type=submit]").removeAttr("clicked"),s2jQuery(this).attr("clicked","true")}),s2jQuery(document).on("dialogclose",function(){t.html(t)})});

View File

@ -0,0 +1,4 @@
/* global QTags */
// Version 2.0 - original version for WordPress versions 3.3 and greater
QTags.addButton( 'Subscribe2', 'Subscribe2', '[subscribe2]' );

View File

@ -0,0 +1 @@
QTags.addButton("Subscribe2","Subscribe2","[subscribe2]");

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

View File

@ -0,0 +1,56 @@
// Version 1.0 - original version
// Version 1.1 - Updated with function fixes and for WordPress 3.2 / jQuery 1.6
// Version 1.2 - Update to work when DISABLED is specified for changes in version 8.5
// Version 1.3 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
// Version 1.4 - eslinted
jQuery( document ).ready(
function() {
// function to check or uncheck all when 'checkall' box it toggled
jQuery( 'input[name="checkall"]' ).click(
function() {
var checkedStatus = this.checked;
jQuery( 'input[class="' + this.value + '"]' ).each(
function() {
if ( false === jQuery( this ).prop( 'disabled' ) ) {
this.checked = checkedStatus;
}
}
);
}
);
// function to check or uncheck 'checkall' box when individual boxes are toggled
jQuery( 'input[class^="checkall"]' ).click(
function() {
var checkedStatus = true;
jQuery( 'input[class="' + this.className + '"]' ).each(
function() {
if ( ( true === this.checked ) && ( true === checkedStatus ) ) {
checkedStatus = true;
} else {
checkedStatus = false;
}
jQuery( 'input[value="' + this.className + '"]' )
.prop( 'checked', checkedStatus );
}
);
}
);
// function to check or uncheck 'checkall' box when page is loaded
jQuery( 'input[class^="checkall"]' ).each(
function() {
var checkedStatus = true;
if ( ( true === this.checked ) && ( true === checkedStatus ) ) {
checkedStatus = true;
} else {
checkedStatus = false;
}
jQuery( 'input[value="' + this.className + '"]' )
.prop( 'checked', checkedStatus );
}
);
}
);

View File

@ -0,0 +1 @@
jQuery(document).ready(function(){jQuery('input[name="checkall"]').click(function(){var c=this.checked;jQuery('input[class="'+this.value+'"]').each(function(){!1===jQuery(this).prop("disabled")&&(this.checked=c)})}),jQuery('input[class^="checkall"]').click(function(){var c=!0;jQuery('input[class="'+this.className+'"]').each(function(){c=!0===this.checked&&!0===c,jQuery('input[value="'+this.className+'"]').prop("checked",c)})}),jQuery('input[class^="checkall"]').each(function(){var c=!0;c=!0===this.checked&&!0===c,jQuery('input[value="'+this.className+'"]').prop("checked",c)})});

View File

@ -0,0 +1,55 @@
// Version 1.0 - original version
// Version 1.1 - Update for Subscribe2 9.0 to remove unecessary code now WordPress 3.3 is minimum requirement
// Version 1.2 - Initialise the colour fields on page load so they are the correct colour
// Version 1.3 - eslinted
jQuery( document ).ready(
function() {
jQuery( document ).on(
'focus',
'.colorpickerField',
function() {
var picker,
field = this.id.substr( 0, 20 );
if ( jQuery( this ).is( '.s2_initialised' ) || -1 !== this.id.search( '__i__' ) ) {
return; // exit early, already initialized or not activated
}
jQuery( this ).addClass( 's2_initialised' );
jQuery( '.s2_colorpicker' ).each(
function() {
if ( -1 !== this.id.search( field ) ) {
picker = this.id;
return false; // stop looping
}
}
);
jQuery( this ).on(
'focusin',
function() {
jQuery( '.s2_colorpicker' ).slideUp();
jQuery.farbtastic( '#' + picker ).linkTo( this );
jQuery( '#' + picker ).slideDown();
}
);
jQuery( this ).on(
'focusout',
function() {
jQuery( '#' + picker ).slideUp();
}
);
jQuery( this ).trigger( 'focus' );
}
);
jQuery( '.colorpickerField' ).each(
function() {
jQuery.farbtastic( '#' + this.id ).linkTo( this );
}
);
}
);

View File

@ -0,0 +1 @@
jQuery(document).ready(function(){jQuery(document).on("focus",".colorpickerField",function(){var i,e=this.id.substr(0,20);jQuery(this).is(".s2_initialised")||-1!==this.id.search("__i__")||(jQuery(this).addClass("s2_initialised"),jQuery(".s2_colorpicker").each(function(){if(-1!==this.id.search(e))return i=this.id,!1}),jQuery(this).on("focusin",function(){jQuery(".s2_colorpicker").slideUp(),jQuery.farbtastic("#"+i).linkTo(this),jQuery("#"+i).slideDown()}),jQuery(this).on("focusout",function(){jQuery("#"+i).slideUp()}),jQuery(this).trigger("focus"))}),jQuery(".colorpickerField").each(function(){jQuery.farbtastic("#"+this.id).linkTo(this)})});

View File

@ -0,0 +1,12 @@
// Version 1.0 - original version
// Version 1.1 - eslinted
jQuery( document ).ready(
function() {
jQuery( '#s2datepicker' ).datepicker(
{
dateFormat: 'MM d, yy'
}
);
}
);

View File

@ -0,0 +1 @@
jQuery(document).ready(function(){jQuery("#s2datepicker").datepicker({dateFormat:"MM d, yy"})});

View File

@ -0,0 +1,17 @@
/* global s2DismissScriptStrings */
// Version 1.0 - original version
// Version 1.1 - eslinted
jQuery( document ).on(
'click',
'#sender_message .notice-dismiss',
function() {
var ajaxurl = s2DismissScriptStrings.ajaxurl;
var data = {
'action': 's2_dismiss_notice',
'nonce': s2DismissScriptStrings.nonce
};
jQuery.post( ajaxurl, data );
}
);

View File

@ -0,0 +1 @@
jQuery(document).on("click","#sender_message .notice-dismiss",function(){var s=s2DismissScriptStrings.ajaxurl,i={action:"s2_dismiss_notice",nonce:s2DismissScriptStrings.nonce};jQuery.post(s,i)});

View File

@ -0,0 +1,65 @@
/* exported s2Show, s2Hide, s2Update, s2Revert, s2CronUpdate, s2CronRevert */
// Version 1.0 - original version
// Version 1.1 - updated for Subscribe2 8.6
// Version 1.2 - updated for Subscribe2 9.0
// Version 1.3 - eslinted
// hide our span before page loads
jQuery( document ).ready(
function() {
jQuery( '#s2bcclimit_2' ).hide();
jQuery( '#s2entries_2' ).hide();
jQuery( '#s2cron_2' ).hide();
}
);
//show span on clicking the edit link
function s2Show( id ) {
jQuery( '#s2' + id + '_2' ).show();
jQuery( '#s2' + id + '_1' ).hide();
return false;
}
// hide span on clicking the hide link
function s2Hide( id ) {
jQuery( '#s2' + id + '_1' ).show();
jQuery( '#s2' + id + '_2' ).hide();
return false;
}
function s2Update( id ) {
var input = jQuery( 'input[name="' + id + '"]' ).val();
jQuery( '#s2' + id ).html( input );
s2Hide( id );
}
function s2Revert( id ) {
var option = jQuery( '#js' + id ).val();
jQuery( 'input[name="' + id + '"]' ).val( option );
jQuery( '#s2' + id ).html( option );
s2Hide( id );
}
function s2CronUpdate( id ) {
var date, time;
date = jQuery( 'input[name="' + id + 'date"]' ).val();
jQuery( '#s2' + id + 'date' ).html( date );
time = jQuery( 'select[name="' + id + 'time"] option:selected' ).html();
jQuery( '#s2' + id + 'time' ).html( time );
s2Hide( id );
}
function s2CronRevert( id ) {
var date, time;
date = jQuery( '#js' + id + 'date' ).val();
jQuery( 'input[name="' + id + 'date"]' ).val( date );
jQuery( '#s2' + id + 'date' ).html( date );
time = jQuery( '#js' + id + 'time' ).val();
jQuery( '[name=' + id + 'time] option' ).filter(
function() {
return ( this.text === time );
}
).prop( 'selected', true ).parent().focus();
jQuery( '#s2' + id + 'time' ).html( time );
s2Hide( id );
}

View File

@ -0,0 +1 @@
function s2Show(e){return jQuery("#s2"+e+"_2").show(),jQuery("#s2"+e+"_1").hide(),!1}function s2Hide(e){return jQuery("#s2"+e+"_1").show(),jQuery("#s2"+e+"_2").hide(),!1}function s2Update(e){var t=jQuery('input[name="'+e+'"]').val();jQuery("#s2"+e).html(t),s2Hide(e)}function s2Revert(e){var t=jQuery("#js"+e).val();jQuery('input[name="'+e+'"]').val(t),jQuery("#s2"+e).html(t),s2Hide(e)}function s2CronUpdate(e){var t,r;t=jQuery('input[name="'+e+'date"]').val(),jQuery("#s2"+e+"date").html(t),r=jQuery('select[name="'+e+'time"] option:selected').html(),jQuery("#s2"+e+"time").html(r),s2Hide(e)}function s2CronRevert(e){var t,r;t=jQuery("#js"+e+"date").val(),jQuery('input[name="'+e+'date"]').val(t),jQuery("#s2"+e+"date").html(t),r=jQuery("#js"+e+"time").val(),jQuery("[name="+e+"time] option").filter(function(){return this.text===r}).prop("selected",!0).parent().focus(),jQuery("#s2"+e+"time").html(r),s2Hide(e)}jQuery(document).ready(function(){jQuery("#s2bcclimit_2").hide(),jQuery("#s2entries_2").hide(),jQuery("#s2cron_2").hide()});

View File

@ -0,0 +1,16 @@
/* exported getip */
// Version 1.0 - original version
// Version 1.1 - eslinted and fixed for Widget form name change
function getip( json ) {
var ip, i, l;
if ( true === document.body.contains( document.forms.s2form ) || true === document.body.contains( document.forms.s2formwidget ) ) {
ip = document.getElementsByName( 'ip' );
l = ip.length;
for ( i = 0; i < l; i++ ) {
if ( 's2form' === ip[i].parentElement.name ) {
ip[i].value = json.ip;
}
}
}
}

View File

@ -0,0 +1 @@
function getip(e){var n,o,t;if(!0===document.body.contains(document.forms.s2form)||!0===document.body.contains(document.forms.s2formwidget))for(t=(n=document.getElementsByName("ip")).length,o=0;o<t;o++)"s2form"===n[o].parentElement.name&&(n[o].value=e.ip)}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,58 @@
/* global s2ScriptStrings */
/* exported s2BulkActionCheck, submitHandler, bmCheck, s2ScriptStrings */
// Version 1.0 - original version
// Version 1.1 - context specific delete warnings for registered or public subscribers
// Version 1.2 - single and plural string confirmation messages
// Version 1.3 - fix suppressed form processing for Toggle action, JavaScript binding only if elements exist & more effecient handling when no users selected
// Version 1.4 - improve Bulk Management user experience and functions
// Version 1.5 - eslinted
function s2BulkActionCheck() {
if ( null !== document.getElementById( 'doaction' ) ) {
document.getElementById( 'doaction' ).onclick = submitHandler;
document.getElementById( 'doaction2' ).onclick = submitHandler;
}
}
function submitHandler() {
var location, action1, action2, agree, selected;
location = document.getElementById( 's2_location' );
action1 = document.getElementById( 'bulk-action-selector-top' );
action2 = document.getElementById( 'bulk-action-selector-bottom' );
agree = false;
selected = document.querySelectorAll( 'input[name="subscriber[]"]:checked' ).length;
if ( 0 === selected ) {
return true;
}
if ( 'delete' === action1.value || 'delete' === action2.value ) {
if ( 'registered' === location.value ) {
if ( 1 < selected ) {
agree = window.confirm( s2ScriptStrings.registered_confirm_plural );
} else {
agree = window.confirm( s2ScriptStrings.registered_confirm_single );
}
} else if ( 'public' === location.value ) {
if ( 1 < selected ) {
agree = window.confirm( s2ScriptStrings.public_confirm_plural );
} else {
agree = window.confirm( s2ScriptStrings.public_confirm_single );
}
}
} else if ( 'toggle' === action1.value || 'toggle' === action2.value ) {
agree = true;
}
return agree;
}
function bmCheck() {
var agree, selected;
agree = false;
selected = document.querySelectorAll( 'input[name="subscriber[]"]:checked' ).length;
if ( 0 === selected ) {
agree = window.confirm( s2ScriptStrings.bulk_manage_all );
} else if ( 1 < selected ) {
agree = window.confirm( s2ScriptStrings.bulk_manage_single );
} else {
agree = window.confirm( s2ScriptStrings.bulk_manage_plural );
}
return agree;
}
window.onload = s2BulkActionCheck;

View File

@ -0,0 +1 @@
function s2BulkActionCheck(){null!==document.getElementById("doaction")&&(document.getElementById("doaction").onclick=submitHandler,document.getElementById("doaction2").onclick=submitHandler)}function submitHandler(){var e,n,t,i,c;return e=document.getElementById("s2_location"),n=document.getElementById("bulk-action-selector-top"),t=document.getElementById("bulk-action-selector-bottom"),i=!1,0===(c=document.querySelectorAll('input[name="subscriber[]"]:checked').length)||("delete"===n.value||"delete"===t.value?"registered"===e.value?i=1<c?window.confirm(s2ScriptStrings.registered_confirm_plural):window.confirm(s2ScriptStrings.registered_confirm_single):"public"===e.value&&(i=1<c?window.confirm(s2ScriptStrings.public_confirm_plural):window.confirm(s2ScriptStrings.public_confirm_single)):"toggle"!==n.value&&"toggle"!==t.value||(i=!0),i)}function bmCheck(){var e;return!1,0===(e=document.querySelectorAll('input[name="subscriber[]"]:checked').length)?window.confirm(s2ScriptStrings.bulk_manage_all):1<e?window.confirm(s2ScriptStrings.bulk_manage_single):window.confirm(s2ScriptStrings.bulk_manage_plural)}window.onload=s2BulkActionCheck;

View File

@ -0,0 +1,92 @@
ul.s2_blogs
{
float: left;
width: 99%;
}
ul.s2_blogs li
{
position: relative;
display: block;
float: left;
width: 47%;
margin: 3px;
padding: .5em;
white-space: nowrap;
border: 1px solid #e0e0e0;
background-color: #e3e3e3;
}
ul.s2_blogs li:hover
{
border-color: #666;
}
ul.s2_blogs li .name
{
display: block;
float: left;
}
ul.s2_blogs li .buttons
{
font-size: .8em;
display: block;
float: right;
margin-left: -6px;
white-space: nowrap;
}
ul.s2_blogs li .buttons a
{
display: block;
float: left;
margin: 0 0 0 1em;
padding: .1em .5em;
color: white;
background-color: #666;
}
ul.s2_blogs li .buttons a:hover
{
color: #666;
background-color: whitesmoke;
}
ul.s2_blogs div.additional_info
{
font-style: italic;
position: absolute;
z-index: 9;
bottom: 2.4em;
left: -2px;
display: none;
width: 75%;
margin-bottom: 2px;
padding: .5em 1em;
color: #fff;
border: 1px solid white;
border-bottom: medium none;
-moz-border-radius-topleft: .5em;
-moz-border-radius-topright: .5em;
background-color: #666;
}
ul.s2_blogs li:hover div.additional_info
{
display: block;
}

View File

@ -0,0 +1 @@
ul.s2_blogs{float:left;width:99%}ul.s2_blogs li{position:relative;display:block;float:left;width:47%;margin:3px;padding:.5em;white-space:nowrap;border:1px solid #e0e0e0;background-color:#e3e3e3}ul.s2_blogs li:hover{border-color:#666}ul.s2_blogs li .name{display:block;float:left}ul.s2_blogs li .buttons{font-size:.8em;display:block;float:right;margin-left:-6px;white-space:nowrap}ul.s2_blogs li .buttons a{display:block;float:left;margin:0 0 0 1em;padding:.1em .5em;color:#fff;background-color:#666}ul.s2_blogs li .buttons a:hover{color:#666;background-color:#f5f5f5}ul.s2_blogs div.additional_info{font-style:italic;position:absolute;z-index:9;bottom:2.4em;left:-2px;display:none;width:75%;margin-bottom:2px;padding:.5em 1em;color:#fff;border:1px solid #fff;border-bottom:medium none;-moz-border-radius-topleft:.5em;-moz-border-radius-topright:.5em;background-color:#666}ul.s2_blogs li:hover div.additional_info{display:block}

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B