first commit

This commit is contained in:
2024-07-15 11:28:08 +02:00
commit f52d538ea5
21891 changed files with 6161164 additions and 0 deletions

View File

@@ -0,0 +1,312 @@
<?php
/*
* TNP classes for internal API
*
* Error reference
* 404 Object not found
* 403 Not allowed (when the API key is missing or wrong)
* 400 Bad request, when the parameters are not correct or required parameters are missing
*
*/
/**
* Main API functions
*
* @author roby
*/
class TNP {
/*
* The full process of subscription
*/
public static function subscribe( $params ) {
$newsletter = Newsletter::instance();
$subscription = NewsletterSubscription::instance();
// default params
$defaults = array( 'send_emails' => true );
$params = array_merge( $defaults, $params );
// Messages
$options = get_option( 'newsletter', array() );
// Form field configuration
$options_profile = get_option( 'newsletter_profile', array() );
$optin = (int) $options['noconfirmation']; // 0 - double, 1 - single
$email = $newsletter->normalize_email( stripslashes( $params['email'] ) );
// Should never reach this point without a valid email address
if ( $email == null ) {
return new WP_Error( '-1', 'Email address not valid', array( 'status' => 400 ) );
}
$user = $newsletter->get_user( $email );
if ( $user != null ) {
$newsletter->logger->info( 'Subscription of an address with status ' . $user->status );
// Bounced
if ( $user->status == 'B' ) {
return new WP_Error( '-1', 'Bounced address', array( 'status' => 400 ) );
}
// If asked to put in confirmed status, do not check further
if ( $params['status'] != 'C' && $optin == 0 ) {
// Already confirmed
//if ($optin == 0 && $user->status == 'C') {
if ( $user->status == 'C' ) {
set_transient( $user->id . '-' . $user->token, $params, 3600 * 48 );
$subscription->set_updated( $user );
// A second subscription always require confirmation otherwise anywan can change other users' data
$user->status = 'S';
$subscription->send_activation_email( $user );
return $user;
}
}
}
if ( $user != null ) {
$newsletter->logger->info( "Email address subscribed but not confirmed" );
$user = array( 'id' => $user->id );
} else {
$newsletter->logger->info( "New email address" );
}
if ( $optin ) {
$params['status'] = 'C';
} else {
$params['status'] = 'S';
}
// Lists
if ( ! isset( $params['lists'] ) || ! is_array( $params['lists'] ) ) {
$params['lists'] = array();
}
// Public lists: rebuild the array keeping only the valid lists
$lists = $newsletter->get_lists_public();
// Public list IDs
$public_lists = array();
foreach ( $lists as $list ) {
$public_lists[] = $list->id;
}
// Keep only the public lists
$params['lists'] = array_intersect( $public_lists, $params['lists'] );
// Pre assigned lists
$lists = $newsletter->get_lists();
foreach ( $lists as $list ) {
if ( $list->forced ) {
$params['lists'][] = $list->id;
}
}
// Keep only the public profile fields
for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
// If the profile cannot be set by subscriber, skip it.
if ( $subscription->options_profile[ 'profile_' . $i . '_status' ] == 0 ) {
unset( $params[ 'profile_' . $i ] );
}
}
apply_filters( 'newsletter_api_subscribe', $params );
$user = TNP::add_subscriber( $params );
if ( is_wp_error( $user ) ) {
return ( $user );
}
// Notification to admin (only for new confirmed subscriptions)
if ( $user->status == 'C' ) {
do_action( 'newsletter_user_confirmed', $user );
$subscription->notify_admin( $user, 'Newsletter subscription' );
setcookie( 'newsletter', $user->id . '-' . $user->token, time() + 60 * 60 * 24 * 365, '/' );
}
// skip messages if send_emails = false
if ( ! $params['send_emails'] ) {
return $user;
}
$message_type = ( $user->status == 'C' ) ? 'confirmed' : 'confirmation';
$subscription->send_message( $message_type, $user );
return null;
}
/*
* The UNsubscription
*/
public static function unsubscribe( $params ) {
$newsletter = Newsletter::instance();
$user = $newsletter->get_user( $params['email'] );
// $newsletter->logger->debug($params);
if ( ! $user ) {
return new WP_Error( '-1', 'Email address not found', array( 'status' => 404 ) );
}
if ( $user->status == 'U' ) {
return $user;
}
$user = $newsletter->set_user_status( $user, 'U' );
if ( empty( NewsletterSubscription::instance()->options['unsubscribed_disabled'] ) ) {
$newsletter->mail( $user->email, $newsletter->replace( NewsletterSubscription::instance()->options['unsubscribed_subject'], $user ), $newsletter->replace( NewsletterSubscription::instance()->options['unsubscribed_message'], $user ) );
}
NewsletterSubscription::instance()->notify_admin( $user, 'Newsletter unsubscription' );
return $user;
}
/*
* Adds a subscriber if not already in
*/
public static function add_subscriber( $params ) {
$newsletter = Newsletter::instance();
$subscription = NewsletterSubscription::instance();
$email = $newsletter->normalize_email( stripslashes( $params['email'] ) );
if ( ! $email ) {
return new WP_Error( '-1', 'Email address not valid', array( 'status' => 400 ) );
}
$user = $newsletter->get_user( $email );
if ( $user ) {
return new WP_Error( '-1', 'Email address already exists', array( 'status' => 400 ) );
}
$user = array( 'email' => $email );
if ( isset( $params['name'] ) ) {
$user['name'] = $newsletter->normalize_name( stripslashes( $params['name'] ) );
}
if ( isset( $params['surname'] ) ) {
$user['surname'] = $newsletter->normalize_name( stripslashes( $params['surname'] ) );
}
if ( ! empty( $params['gender'] ) ) {
$user['sex'] = $newsletter->normalize_sex( $params['gender'] );
}
for ( $i = 1; $i <= NEWSLETTER_PROFILE_MAX; $i ++ ) {
if ( isset( $params[ 'profile_' . $i ] ) ) {
$user[ 'profile_' . $i ] = trim( stripslashes( $params[ 'profile_' . $i ] ) );
}
}
// Lists (an array under the key "lists")
// Preferences (field names are nl[] and values the list number so special forms with radio button can work)
if ( isset( $params['lists'] ) && is_array( $params['lists'] ) ) {
foreach ( $params['lists'] as $list_id ) {
$user[ 'list_' . ( (int) $list_id ) ] = 1;
}
}
if ( ! empty( $params['status'] ) ) {
$user['status'] = $params['status'];
} else {
$user['status'] = 'C';
}
$user['token'] = $newsletter->get_token();
$user['updated'] = time();
$user['ip'] = Newsletter::get_remote_ip();
$user = $newsletter->save_user( $user );
return $user;
}
/*
* Subscribers list
*/
public static function subscribers( $params ) {
global $wpdb;
$newsletter = Newsletter::instance();
$items_per_page = 20;
$where = "";
$query = "select name, email from " . NEWSLETTER_USERS_TABLE . ' ' . $where . " order by id desc";
$query .= " limit 0," . $items_per_page;
$list = $wpdb->get_results( $query );
return $list;
}
/*
* Deletes a subscriber
*/
public static function delete_subscriber( $params ) {
global $wpdb;
$newsletter = Newsletter::instance();
$user = $newsletter->get_user( $params['email'] );
if ( ! $user ) {
return new WP_Error( '-1', 'Email address not found', array( 'status' => 404 ) );
}
if ( $wpdb->query( $wpdb->prepare( "delete from " . NEWSLETTER_USERS_TABLE . " where id=%d", (int) $user->id ) ) ) {
return "OK";
} else {
$newsletter->logger->debug( $wpdb->last_query );
return new WP_Error( '-1', $wpdb->last_error, array( 'status' => 400 ) );
}
}
/*
* Newsletters list
*/
public static function newsletters( $params ) {
global $wpdb;
$newsletter = Newsletter::instance();
$list = $wpdb->get_results( "SELECT id, subject, created, status, total, sent, send_on FROM " . NEWSLETTER_EMAILS_TABLE . " ORDER BY id DESC LIMIT 10", OBJECT );
if ( $wpdb->last_error ) {
$newsletter->logger->error( $wpdb->last_error );
return false;
}
if ( empty( $list ) ) {
return array();
}
return $list;
}
}

View File

@@ -0,0 +1,13 @@
<?php
$codemirror_url = plugins_url('newsletter') . '/vendor/codemirror';
?>
<link href="<?php echo $codemirror_url ?>/codemirror.css" type="text/css" rel="stylesheet">
<link href="<?php echo $codemirror_url ?>/addon/hint/show-hint.css" type="text/css" rel="stylesheet">
<script src="<?php echo $codemirror_url ?>/codemirror.js"></script>
<script src="<?php echo $codemirror_url ?>/mode/xml/xml.js"></script>
<script src="<?php echo $codemirror_url ?>/mode/css/css.js"></script>
<script src="<?php echo $codemirror_url ?>/mode/javascript/javascript.js"></script>
<script src="<?php echo $codemirror_url ?>/mode/htmlmixed/htmlmixed.js"></script>
<script src="<?php echo $codemirror_url ?>/addon/hint/show-hint.js"></script>
<script src="<?php echo $codemirror_url ?>/addon/hint/xml-hint.js"></script>
<script src="<?php echo $codemirror_url ?>/addon/hint/html-hint.js"></script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,447 @@
<?php
class NewsletterFields {
static $field_open = '<div>';
static $field_close = '</div>';
var $controls;
public function __construct(NewsletterControls $controls) {
$this->controls = $controls;
}
public function _open($subclass = '') {
echo '<div class="tnp-field ', $subclass, '">';
}
public function _close() {
echo '</div>';
}
public function _label($text, $for = '') {
echo '<label class="tnp-label">', $text, '</label>';
}
public function _description($attrs) {
if (empty($attrs['description']))
return;
echo '<div class="tnp-description">', $attrs['description'], '</div>';
}
public function _id($name) {
return 'options-' . esc_attr($name);
}
public function _merge_base_attrs($attrs) {
return array_merge(array('description' => '', 'label' => '', 'help_url' => ''), $attrs);
}
public function _merge_attrs($attrs, $defaults = array()) {
return array_merge(array('description' => '', 'label' => '', 'help_url' => ''), $defaults, $attrs);
}
public function section($title = '') {
echo '<h3 class="tnp-section">', $title, '</h3>';
}
public function separator() {
echo '<div class="tnp-field tnp-separator"></div>';
}
public function checkbox($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('description' => '', 'label' => ''), $attrs);
$this->_open('tnp-checkbox');
$this->controls->checkbox($name, $label);
$this->_description($attrs);
$this->_close();
}
public function text($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => ''), $attrs);
$this->_open();
$this->_label($label);
$value = $this->controls->get_value($name);
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . ']" type="text"';
if (!empty($attrs['size'])) {
echo ' style="width: ', $attrs['size'], 'px"';
}
echo ' value="', esc_attr($value), '">';
if (!empty($attrs['label_after']))
echo $attrs['label_after'];
//$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
$this->_description($attrs);
$this->_close();
}
public function multitext($name, $label = '', $count = 10, $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => ''), $attrs);
$this->_open();
$this->_label($label);
for ($i = 1; $i <= $count; $i++) {
$value = $this->controls->get_value($name . '_' . $i);
echo '<input id="', $this->_id($name . '_' . $i), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[', $name, '_', $i, ']" type="text"';
if (!empty($attrs['size'])) {
echo ' style="width: ', $attrs['size'], 'px"';
}
echo ' value="', esc_attr($value), '">';
}
if (!empty($attrs['label_after']))
echo $attrs['label_after'];
//$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
$this->_description($attrs);
$this->_close();
}
public function textarea($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$this->controls->textarea_fixed($name);
$this->_description($attrs);
$this->_close();
}
public function wp_editor($name, $label = '', $attrs = array()) {
global $wp_version;
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$value = $this->controls->get_value($name);
if (is_array($value)) {
$value = implode("\n", $value);
}
if (version_compare($wp_version, '4.8', '<')) {
echo '<p><strong>Rich editor available only with WP 4.8+</strong></p>';
}
echo '<textarea id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" style="width: 100%;height:250px">';
echo esc_html($value);
echo '</textarea>';
if (version_compare($wp_version, '4.8', '>=')) {
echo '<script>wp.editor.remove("options-', $name, '");';
echo 'wp.editor.initialize("options-', $name, '", { tinymce: {toolbar1: "undo redo | formatselect fontselect fontsizeselect | bold italic forecolor backcolor | link unlink | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help", fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px", plugins: "link textcolor colorpicker", default_link_target: "_blank", relative_urls : false, convert_urls: false}});</script>';
}
$this->_description($attrs);
$this->_close();
}
public function select($name, $label = '', $options = array(), $attrs = array()) {
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$this->controls->select($name, $options);
$this->_description($attrs);
$this->_close();
}
public function yesno($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$this->controls->yesno($name);
$this->_description($attrs);
$this->_close();
}
public function select_number($name, $label = '', $min, $max, $attrs = array()) {
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$this->controls->select_number($name, $min, $max);
$this->_description($attrs);
$this->_close();
}
/** General field to collect a dimension */
public function size($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('description' => '', 'placeholder' => '', 'size' => 0, 'label_after' => 'px'), $attrs);
$this->_open('tnp-size');
$this->_label($label);
$value = $this->controls->get_value($name);
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . ']" type="text"';
if (!empty($attrs['size'])) {
echo ' style="width: ', $attrs['size'], 'px"';
}
echo ' value="', esc_attr($value), '">', $attrs['label_after'];
//$this->controls->text($name, $attrs['size'], $attrs['placeholder']);
$this->_description($attrs);
$this->_close();
}
/** Collects a color in RGB format (#RRGGBB) with a picker. */
public function color($name, $label, $attrs = array()) {
$attrs = array_merge(array('description' => '', 'placeholder' => ''), $attrs);
$this->_open('tnp-color');
$this->_label($label);
$this->controls->color($name);
$this->_description($attrs);
$this->_close();
}
/** Configuration for a simple button with label and color */
public function button($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_attrs($attrs, array('placeholder' => 'Label...', 'url_placeholder' => 'https://...', 'url' => true));
$this->_open('tnp-cta');
$this->_label($label);
$value = $this->controls->get_value($name . '_label');
echo '<input id="', $this->_id($name), '" placeholder="', esc_attr($attrs['placeholder']), '" name="options[' . $name . '_label]" type="text"';
echo ' style="width: 200px"';
echo ' value="', esc_attr($value), '">';
if ($attrs['url']) {
$value = $this->controls->get_value($name . '_url');
echo '<input id="', $this->_id($name . '_url'), '" placeholder="', esc_attr($attrs['url_placeholder']), '" name="options[' . $name . '_url]" type="url"';
echo ' style="width: 200px"';
echo ' value="', esc_attr($value), '">';
}
$this->controls->css_font($name . '_font', array('weight' => false));
$this->controls->color($name . '_background');
$this->_close();
}
public function url($name, $label = '', $attrs = array()) {
$attrs = array_merge(array('description' => '', 'placeholder' => 'https://...'), $attrs);
$this->_open();
$this->_label($label);
$this->controls->text_url($name);
$this->_description($attrs);
$this->_close();
}
public function post_type($name = 'post_type', $label = '', $attrs = array()) {
$post_types = get_post_types(array('public' => true), 'objects', 'and');
$attrs = array_merge(array('description' => ''), $attrs);
$this->_open();
$this->_label($label);
$options = array('post' => 'Standard post');
foreach ($post_types as $post_type) {
if ($post_type->name == 'post' || $post_type->name == 'page' || $post_type->name == 'attachment')
continue;
$options[$post_type->name] = $post_type->labels->name;
}
$value = $this->controls->get_value($name);
echo '<select id="options-' . esc_attr($name) . '" name="options[' . esc_attr($name) . ']" onchange="tnpc_reload_options(event); return false;">';
if (!empty($first)) {
echo '<option value="">' . esc_html($first) . '</option>';
}
foreach ($options as $key => $label) {
echo '<option value="' . esc_attr($key) . '"';
if ($value == $key)
echo ' selected';
echo '>' . esc_html($label) . '</option>';
}
echo '</select>';
$this->_description($attrs);
$this->_close();
}
function posts($name, $label, $count = 20, $args = array()) {
$args = array_merge(array('filters' => array(
'posts_per_page' => 5,
'offset' => 0,
'category' => '',
'category_name' => '',
'orderby' => 'date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => 'post',
'post_mime_type' => '',
'post_parent' => '',
'author' => '',
'author_name' => '',
'post_status' => 'publish',
'suppress_filters' => true,
'last_post_option'=>false
)), $args);
$args['filters']['posts_per_page'] = $count;
$posts = get_posts($args['filters']);
$options = array();
if ($args['last_post_option']) {
$options['last'] = 'Most recent post';
}
foreach ($posts as $post) {
$options['' . $post->ID] = $post->post_title;
}
$this->select($name, $label, $options);
}
function lists($name, $label, $attrs = array()) {
$attrs = $this->_merge_attrs($attrs);
$this->_open();
$this->_label($label);
$lists = $this->controls->get_list_options($empty_label);
$this->controls->select($name, $lists);
$this->_description($attrs);
$this->_close();
}
/**
* Media selector using the WP media library (for images and files.
* The field to use it the {$name}_id which contains the media id.
*
* @param type $name
* @param type $label
* @param type $attrs
*/
public function media($name, $label = '', $attrs = array()) {
$attrs = $this->_merge_attrs($attrs, array('alt'=>false));
$this->_open();
$this->_label($label);
$this->controls->media($name);
if ($attrs['alt']) {
$this->controls->text($name . '_alt', 20, 'Alternative text');
}
$this->_description($attrs);
$this->_close();
}
public function categories($name = 'categories', $label = '', $attrs = array()) {
if (empty($label))
$label = __('Categories', 'newsletter');
$attrs = $this->_merge_attrs($attrs);
$this->_open('tnp-categories');
$this->_label($label);
$this->controls->categories_group($name);
$this->_description($attrs);
$this->_close();
}
public function terms($taxonomy, $label = '', $attrs = array()) {
$name = 'tax_' . $taxonomy;
if (empty($label))
$label = __('Terms', 'newsletter');
$attrs = $this->_merge_attrs($attrs);
$this->_open('tnp-categories');
$this->_label($label);
$terms = get_terms($taxonomy);
if (empty($terms)) {
echo 'No terms in use';
} else {
echo '<div class="newsletter-checkboxes-group">';
foreach ($terms as $term) {
/* @var $term WP_Term */
echo '<div class="newsletter-checkboxes-item">';
$this->controls->checkbox_group($name, $term->term_id, esc_html($term->name));
echo '</div>';
}
echo '<div style="clear: both"></div>';
echo '</div>';
}
$this->_description($attrs);
$this->_close();
}
public function language($name = 'language', $label = '', $attrs = array()) {
if (!Newsletter::instance()->is_multilanguage())
return;
if (empty($label))
$label = __('Language', 'newsletter');
$attrs = $this->_merge_attrs($attrs);
$this->_open('tnp-language');
$this->_label($label);
$this->controls->language($name);
$this->_description($attrs);
$this->_close();
}
/**
* Collects font details for a text: family, color, size and weight to be used
* directly on CSS rules. Size is a pure number.
*
* @param type $name
* @param type $label
* @param type $attrs
*/
public function font($name = 'font', $label = 'Font', $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('hide_family' => false, 'hide_color' => false, 'hide_size' => false), $attrs);
$this->_open('tnp-font');
$this->_label($label);
$this->controls->css_font($name);
$this->_description($attrs);
$this->_close();
}
/**
* Collects fout number values representing the padding of a box. The values can
* be found as {$name}_top, {$name}_bottom, {$name}_left, {$name}_right.
*
* @param type $name
* @param type $label
* @param type $attrs
*/
public function padding($name = 'block_padding', $label = 'Padding', $attrs = array()) {
$attrs = $this->_merge_base_attrs($attrs);
$attrs = array_merge(array('padding_top' => 0, 'padding_left' => 0, 'padding_right' => 0, 'padding_bottom' => 0), $attrs);
$field_only = !empty($attrs['field_only']);
if (!$field_only) {
$this->_open('tnp-padding');
$this->_label($label);
}
echo '<div class="tnp-padding-fields">';
echo '&larr;';
$this->controls->text($name . '_left', 5);
echo '&nbsp;&nbsp;&nbsp;';
echo '&uarr;';
$this->controls->text($name . '_top', 5);
echo '&nbsp;&nbsp;&nbsp;';
$this->controls->text($name . '_bottom', 5);
echo '&darr;';
echo '&nbsp;&nbsp;&nbsp;';
$this->controls->text($name . '_right', 5);
echo '&rarr;';
echo '</div>';
if (!$field_only) {
$this->_description($attrs);
$this->_close();
}
}
/**
* Background color selector for a block.
*/
public function block_background() {
$this->color('block_background', __('Block Background', 'newsletter'));
}
/**
* Padding selector for a block.
*/
public function block_padding() {
$this->padding('block_padding', __('Padding', 'newsletter'));
}
public function block_commons() {
$this->separator();
$this->_open('tnp-block-commons');
$this->_label('Padding and background');
$this->controls->color('block_background');
echo '&nbsp;&nbsp;&nbsp;';
$this->padding('block_padding', '', $attrs = array('field_only' => true));
$this->_close();
}
}

View File

@@ -0,0 +1,150 @@
<?php
defined('ABSPATH') || exit;
function tnp_post_thumbnail_src($post, $size = 'thumbnail', $alternative = '') {
if (is_object($post)) {
$post = $post->ID;
}
// Find a media id to be used as featured image
$media_id = get_post_thumbnail_id($post);
if (empty($media_id)) {
$attachments = get_children(array('numberpost' => 1, 'post_parent' => $post, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order'));
if (!empty($attachments)) {
foreach ($attachments as $id => &$attachment) {
$media_id = $id;
break;
}
}
}
if (!$media_id) {
return $alternative;
}
if (!defined('NEWSLETTER_MEDIA_RESIZE') || NEWSLETTER_MEDIA_RESIZE) {
if (is_array($size)) {
$src = tnp_media_resize($media_id, $size);
if (is_wp_error($src)) {
Newsletter::instance()->logger->error($src);
return $alternative;
} else {
return $src;
}
}
}
$media = wp_get_attachment_image_src($media_id, $size);
if (strpos($media[0], 'http') !== 0) {
$media[0] = 'http:' . $media[0];
}
return $media[0];
}
function tnp_post_excerpt($post, $length = 30) {
if (empty($post->post_excerpt)) {
$excerpt = wp_strip_all_tags(strip_shortcodes($post->post_content));
$excerpt = wp_trim_words($excerpt, $length);
} else {
$excerpt = wp_trim_words($post->post_excerpt, $length);
}
$excerpt = preg_replace("/\[vc_row.*?\]/", "", $excerpt);
return $excerpt;
}
function tnp_post_permalink($post) {
return get_permalink($post->ID);
}
function tnp_post_content($post) {
return $post->post_content;
}
function tnp_post_title($post) {
return $post->post_title;
}
function tnp_post_date($post, $format = null) {
if (empty($format)) {
$format = get_option('date_format');
}
return mysql2date($format, $post->post_date);
}
/**
* Tries to create a resized version of a media uploaded to the media library.
* Returns an empty string if the media does not exists or generally if the attached file
* cannot be found. If the resize fails for whatever reason, fall backs to the
* standard image source returned by WP which is usually not exactly the
* requested size.
*
* @param int $media_id
* @param array $size
* @return string
*/
function tnp_media_resize($media_id, $size) {
if (empty($media_id))
return '';
$relative_file = get_post_meta($media_id, '_wp_attached_file', true);
if (empty($relative_file))
return '';
$width = $size[0];
$height = $size[1];
$crop = false;
if (isset($size[2])) {
$crop = (boolean) $size[2];
}
$uploads = wp_upload_dir();
$absolute_file = $uploads['basedir'] . '/' . $relative_file;
// Relative and absolute name of the thumbnail.
$pathinfo = pathinfo($relative_file);
$relative_thumb = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . '-' . $width . 'x' .
$height . ($crop ? '-c' : '') . '.' . $pathinfo['extension'];
$absolute_thumb = $uploads['basedir'] . '/newsletter/thumbnails/' . $relative_thumb;
// Thumbnail generation if needed.
if (!file_exists($absolute_thumb) || filemtime($absolute_thumb) < filemtime($absolute_file)) {
$r = wp_mkdir_p($uploads['basedir'] . '/newsletter/thumbnails/' . $pathinfo['dirname']);
if (!$r) {
$src = wp_get_attachment_image_src($media_id, 'full');
return $src[0];
}
$editor = wp_get_image_editor($absolute_file);
if (is_wp_error($editor)) {
$src = wp_get_attachment_image_src($media_id, 'full');
return $src[0];
//return $editor;
//return $uploads['baseurl'] . '/' . $relative_file;
}
$original_size = $editor->get_size();
if ($width > $original_size['width'] || $height > $original_size['height']) {
$src = wp_get_attachment_image_src($media_id, 'full');
return $src[0];
}
$editor->set_quality(80);
$resized = $editor->resize($width, $height, $crop);
if (is_wp_error($resized)) {
$src = wp_get_attachment_image_src($media_id, 'full');
return $src[0];
}
$saved = $editor->save($absolute_thumb);
if (is_wp_error($saved)) {
$src = wp_get_attachment_image_src($media_id, 'full');
return $src[0];
//return $saved;
//return $uploads['baseurl'] . '/' . $relative_file;
}
}
return $uploads['baseurl'] . '/newsletter/thumbnails/' . $relative_thumb;
}

View File

@@ -0,0 +1,95 @@
<?php
defined('ABSPATH') || exit;
if (!defined('NEWSLETTER_LOG_DIR')) {
define('NEWSLETTER_LOG_DIR', WP_CONTENT_DIR . '/logs/newsletter');
}
class NewsletterLogger {
const NONE = 0;
const FATAL = 1;
const ERROR = 2;
const INFO = 3;
const DEBUG = 4;
var $level;
var $module;
var $file;
function __construct($module) {
$this->module = $module;
if (defined('NEWSLETTER_LOG_LEVEL')) $this->level = NEWSLETTER_LOG_LEVEL;
else $this->level = get_option('newsletter_log_level', self::ERROR);
$secret = get_option('newsletter_logger_secret');
if (strlen($secret) < 8) {
$secret = NewsletterModule::get_token(8);
update_option('newsletter_logger_secret', $secret);
}
if (!wp_mkdir_p(NEWSLETTER_LOG_DIR)) {
$this->level = self::NONE;
}
$this->file = NEWSLETTER_LOG_DIR . '/' . $module . '-' . date('Y-m') . '-' . $secret . '.txt';
}
/**
*
* @param string|WP_Error|array|stdClass $text
* @param int $level
*/
function log($text, $level = self::ERROR) {
global $current_user;
if ($level != self::FATAL && $this->level < $level) return;
if ($current_user) {
$user_id = $current_user->ID;
} else {
$user_id = 0;
}
$time = date('d-m-Y H:i:s ');
switch ($level) {
case self::FATAL: $time .= '- FATAL';
break;
case self::ERROR: $time .= '- ERROR';
break;
case self::INFO: $time .= '- INFO ';
break;
case self::DEBUG: $time .= '- DEBUG';
break;
}
if (is_wp_error($text)) {
/* @var $text WP_Error */
$text = $text->get_error_message() . ' (' . $text->get_error_code() . ') - ' . print_r($text->get_error_data(), true);
} else {
if (is_array($text) || is_object($text)) $text = print_r($text, true);
}
// The "logs" dir is created on Newsletter constructor.
$res = @file_put_contents($this->file, $time . ' - m: ' . size_format(memory_get_usage(), 1) . ', u: ' . $user_id . ' - ' . $text . "\n", FILE_APPEND | FILE_TEXT);
if ($res === false) {
$this->level = self::NONE;
}
}
function error($text) {
self::log($text, self::ERROR);
}
function info($text) {
$this->log($text, self::INFO);
}
function fatal($text) {
$this->log($text, self::FATAL);
}
function debug($text) {
$this->log($text, self::DEBUG);
}
}

View File

@@ -0,0 +1,321 @@
<?php
/**
* Wrapper mailer for old addons registering the "mail" method (ultra deprecated).
*/
class NewsletterMailMethodWrapper extends NewsletterMailer {
var $mail_method;
/**
* The reference to the mail method.
*
* @param callback $callable Must be an array with object and method to call, no other callback formats allowed.
*/
function __construct($callable) {
parent::__construct(strtolower(get_class($callable[0])), array());
$this->mail_method = $callable;
}
function get_description() {
if ($this->mail_method != null) {
return 'Mail method of ' . get_class($this->mail_method[0]);
} else {
return 'Undetectable mailer class';
}
}
function send($message) {
if ($this->mail_method != null) {
$r = call_user_func($this->mail_method, $message->to, $message->subject, array('html' => $message->body, 'text' => $message->body_text), $message->headers);
if (!$r) {
$message->error = 'Unreported error';
return new WP_Error(self::ERROR_GENERIC, 'Unreported error');
}
} else {
$message->error = 'Mail mathod not available';
return new WP_Error(self::ERROR_FATAL, 'Mail method not available');
}
return true;
}
}
/**
* Wrapper Mailer for old addons registering the "mail" method (deprecated).
*/
class NewsletterOldMailerWrapper extends NewsletterMailer {
var $mailer;
/**
* Old mailer plugin (actually untyped object)
* @param object $mailer
*/
function __construct($mailer) {
$this->mailer = $mailer;
// We have not a name, build it from the class name... and of course, no options.
parent::__construct(strtolower(get_class($mailer)), array());
$this->description = 'Mailer wrapper for ' . get_class($mailer);
}
/**
* Only send() needs to be implemented all other method will use the defail base-class implementation
*
* @param TNP_Mailer_Message $message
* @return \WP_Error|boolean
*/
function send($message) {
// The old mailer manages itself the from field
$r = $this->mailer->mail($message->to, $message->subject, array('html' => $message->body, 'text' => $message->body_text), $message->headers);
if (!$r) {
if (isset($this->mailer->result)) {
$message->error = $this->mailer->result;
return new WP_Error(self::ERROR_GENERIC, $this->mailer->result);
} else {
$message->error = 'Unknown error';
return new WP_Error(self::ERROR_GENERIC, 'Unknown error');
}
}
return true;
}
}
/**
* Standard Mailer which uses the wp_mail() function of WP.
*/
class NewsletterDefaultMailer extends NewsletterMailer {
var $filter_active = false;
/**
* Static to be accessed in the hook: on some installation the object $this is not working, we're still trying to understand why
* @var TNP_Mailer_Message
*/
var $current_message = null;
function __construct() {
parent::__construct('default', Newsletter::instance()->get_options('smtp'));
}
function get_description() {
// TODO: check if overloaded
return 'wp_mail() WordPress function (could be extended by a SMTP plugin)';
}
function fix_mailer($mailer) {
$newsletter = Newsletter::instance();
if (!empty($newsletter->options['content_transfer_encoding'])) {
$mailer->Encoding = $newsletter->options['content_transfer_encoding'];
} else {
$mailer->Encoding = 'base64';
}
// If there is not a current message, wp_mail() was not called by us
if (is_null($this->current_message)) {
return;
}
/* @var $mailer PHPMailer */
$mailer->Sender = $newsletter->options['return_path'];
if (!empty($this->current_message->current_message->body) && !empty($this->current_message->current_message->body_text)) {
$mailer->AltBody = $this->current_message->current_message->body_text;
}
}
function send($message) {
if (!$this->filter_active) {
add_action('phpmailer_init', array($this, 'fix_mailer'), 100);
$this->filter_active = true;
}
$newsletter = Newsletter::instance();
$wp_mail_headers = array();
// TODO: Manage the from address
$wp_mail_headers[] = 'From: "' . $newsletter->options['sender_name'] . '" <' . $newsletter->options['sender_email'] . '>';
if (!empty($newsletter->options['reply_to'])) {
$wp_mail_headers[] = 'Reply-To: ' . $newsletter->options['reply_to'];
}
// Manage from and from name
if (!empty($message->headers)) {
foreach ($message->headers as $key => $value) {
$wp_mail_headers[] = $key . ': ' . $value;
}
}
if (!empty($message->body)) {
$wp_mail_headers[] = 'Content-Type: text/html;charset=UTF-8';
$body = $message->body;
} else if (!empty($message->body_text)) {
$wp_mail_headers[] = 'Content-Type: text/plain;charset=UTF-8';
$body = $message->body_text;
} else {
$message->error = 'Empty body';
return new WP_Error(self::ERROR_GENERIC, 'Message format');
}
$this->current_message = $message;
$r = wp_mail($message->to, $message->subject, $body, $wp_mail_headers);
$this->current_message = null;
if (!$r) {
$last_error = error_get_last();
if (is_array($last_error)) {
$message->error = $last_error['message'];
if (stripos($message->error, 'Could not instantiate mail function') || stripos($message->error, 'Failed to connect to mailserver')) {
return new WP_Error(self::ERROR_FATAL, $last_error['message']);
} else {
return new WP_Error(self::ERROR_GENERIC, $last_error['message']);
}
} else {
$message->error = 'No error explanation reported';
return new WP_Error(self::ERROR_GENERIC, 'No error message reported');
}
}
return true;
}
}
/**
* Standard Mailer which uses the wp_mail() function of WP.
*/
class NewsletterDefaultSMTPMailer extends NewsletterMailer {
var $mailer = null;
function __construct($options) {
parent::__construct('internal-smtp', $options);
}
function get_description() {
return 'Internal SMTP (deprecated)';
}
/**
*
* @param TNP_Mailer_Message $message
* @return \WP_Error|boolean
*/
public function send($message) {
$logger = $this->get_logger();
$logger->debug('Start sending to ' . $message->to);
$mailer = $this->get_mailer();
if (!empty($message->body)) {
$mailer->IsHTML(true);
$mailer->Body = $message->body;
$mailer->AltBody = $message->body_text;
} else {
$mailer->IsHTML(false);
$mailer->Body = $message->body_text;
$mailer->AltBody = '';
}
$mailer->Subject = $message->subject;
$mailer->ClearCustomHeaders();
if (!empty($message->headers)) {
foreach ($message->headers as $key => $value) {
$mailer->AddCustomHeader($key . ': ' . $value);
}
}
if ($message->from) {
$logger->debug('Alternative from available');
$mailer->setFrom($message->from, $message->from_name);
} else {
$newsletter = Newsletter::instance();
$mailer->setFrom($newsletter->options['sender_email'], $newsletter->options['sender_name']);
}
$mailer->ClearAddresses();
$mailer->AddAddress($message->to);
$mailer->Send();
if ($mailer->IsError()) {
$logger->error($mailer->ErrorInfo);
// If the error is due to SMTP connection, the mailer cannot be reused since it does not clean up the connection
// on error.
//$this->mailer = null;
$message->error = $mailer->ErrorInfo;
return new WP_Error(self::ERROR_GENERIC, $mailer->ErrorInfo);
}
$logger->debug('Sent ' . $message->to);
//$logger->error('Time: ' . (microtime(true) - $start) . ' seconds');
return true;
}
/**
*
* @return PHPMailer
*/
function get_mailer() {
if ($this->mailer) {
return $this->mailer;
}
$logger = $this->get_logger();
$logger->debug('Setting up PHP mailer');
require_once ABSPATH . WPINC . '/class-phpmailer.php';
require_once ABSPATH . WPINC . '/class-smtp.php';
$this->mailer = new PHPMailer();
$this->mailer->IsSMTP();
$this->mailer->Host = $this->options['host'];
if (!empty($this->options['port'])) {
$this->mailer->Port = (int) $this->options['port'];
}
if (!empty($this->options['user'])) {
$this->mailer->SMTPAuth = true;
$this->mailer->Username = $this->options['user'];
$this->mailer->Password = $this->options['pass'];
}
$this->mailer->SMTPKeepAlive = true;
$this->mailer->SMTPSecure = $this->options['secure'];
$this->mailer->SMTPAutoTLS = false;
if ($this->options['ssl_insecure'] == 1) {
$this->mailer->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
}
$newsletter = Newsletter::instance();
// if (!empty($newsletter->options['content_transfer_encoding'])) {
// $this->mailer->Encoding = $newsletter->options['content_transfer_encoding'];
// } else {
// $this->mailer->Encoding = 'base64';
// }
$this->mailer->CharSet = 'UTF-8';
$this->mailer->From = $newsletter->options['sender_email'];
if (!empty($newsletter->options['return_path'])) {
$this->mailer->Sender = $newsletter->options['return_path'];
}
if (!empty($newsletter->options['reply_to'])) {
$this->mailer->AddReplyTo($newsletter->options['reply_to']);
}
$this->mailer->FromName = $newsletter->options['sender_name'];
return $this->mailer;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
<?php
defined('ABSPATH') || exit;
@require_once NEWSLETTER_INCLUDES_DIR . '/logger.php';
class NewsletterStore {
static $instance = null;
/**
* @var NewsletterLogger
*/
var $logger;
/**
*
* @return NewsletterStore
*/
static function instance() {
if (self::$instance == null) {
self::$instance = new NewsletterStore();
}
return self::$instance;
}
static function singleton() {
return self::instance();
}
function __construct() {
$this->logger = new NewsletterLogger('store');
}
function get_field($table, $id, $field_name) {
global $wpdb;
$field_name = (string)$field_name;
if (preg_match('/^[a-zA-Z_]+$/', $field_name) == 0) {
$this->logger->fatal('Invalis field name: ' . $field_name);
return false;
}
$id = (int)$id;
$r = $wpdb->get_var($wpdb->prepare("select $field_name from $table where id=%d limit 1", $id));
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $r;
}
function get_single($table, $id, $format = OBJECT) {
global $wpdb;
$id = (int)$id;
return $this->get_single_by_query($wpdb->prepare("select * from $table where id=%d limit 1", $id), $format);
}
function get_single_by_field($table, $field_name, $field_value, $format = OBJECT) {
global $wpdb;
$field_name = (string)$field_name;
$field_value = (string)$field_value;
if (preg_match('/^[a-zA-Z_]+$/', $field_name) == 0) {
$this->logger->error('Invalis field name: ' . $field_name);
return false;
}
return $this->get_single_by_query($wpdb->prepare("select * from $table where $field_name=%s limit 1", $field_value), $format);
}
function get_count($table, $where = null) {
global $wpdb;
$r = $wpdb->get_var("select count(*) from $table " . ($where != null ? $where : ''));
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $r;
}
/**
* Returns a single record executing the given query or null if no row can be found. If more rows are matching
* the query, only the first one is returned. Returns "false" on error (use the strict type checking ===) and a log
* is written.
*
* @global wpdb $wpdb
* @param string $query
* @param type $format
* @return boolean|mixed
*/
function get_single_by_query($query, $format = OBJECT) {
global $wpdb;
$r = $wpdb->get_row($query, $format);
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $r;
}
function sanitize($data) {
global $wpdb;
//if (strpos($wpdb->charset, 'utf8mb4') === 0) return $data;
if (strpos($wpdb->charset, 'utf8mb4') === 0) return $data;
foreach ($data as $key => $value) {
$data[$key] = preg_replace('%(?:\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})%xs', '', $value);
}
return $data;
}
/**
* Save a record on given table, updating it id the "id" value is set (as key or object property) or inserting it
* if "id" is not set. Accepts objects or associative arrays as data.
*
* Returns "false" is an error occurred or the saved data re-read from the database in given format.
*
* @global wpdb $wpdb
* @param type $table
* @param type $data
*/
function save($table, $data, $return_format = OBJECT) {
global $wpdb;
if (is_object($data)) {
$data = (array) $data;
}
// Remove transient fields
foreach (array_keys($data) as $key) {
if (substr($key, 0, 1) == '_') unset($data[$key]);
}
if (isset($data['id'])) {
$id = (int)$data['id'];
unset($data['id']);
if (!empty($data)) {
$r = $wpdb->update($table, $this->sanitize($data), array('id' => $id));
if ($r === false) {
$this->logger->fatal($wpdb->last_error);
$this->logger->fatal($wpdb->last_query);
die('Database error. If you were saving a newsletter try a table upgrade from the status panel.');
}
}
//$this->logger->debug('save: ' . $wpdb->last_query);
} else {
$r = $wpdb->insert($table, $this->sanitize($data));
if ($r === false) {
$this->logger->fatal($wpdb->last_error);
$this->logger->fatal($wpdb->last_query);
die('Database error. If you were saving a newsletter try a table upgrade from the status panel.');
}
$id = $wpdb->insert_id;
}
// if ($wpdb->last_error) {
// $this->logger->error('save: ' . $wpdb->last_error);
// return false;
// }
return $this->get_single($table, $id, $return_format);
}
function increment($table, $id, $field) {
global $wpdb;
$id = (int)$id;
$field = (string)$field;
if (preg_match('/^[a-zA-Z_]+$/', $field) == 0) {
$this->logger->error('Invalis field name: ' . $field);
return false;
}
$result = $wpdb->query($wpdb->prepare("update $table set $field=$field+1 where id=%d", $id));
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $result;
}
/**
* Deletes one or more rows by id (or an array of id)
*
* @param int|array $id
* @return int Number of rows deleted
*/
function delete($table, $id) {
global $wpdb;
if (is_array($id)) {
for ($i=0; $i<count($id); $i++) {
$id[$i] = (int)$id[$i];
}
$wpdb->query("delete from " . $table . " where id in (" . implode(',', $id) . ")");
} else {
$wpdb->delete($table, array('id' => (int)$id));
}
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $wpdb->rows_affected;
}
/**
*
* @global wpdb $wpdb
* @param type $table
* @param type $order_by
* @param type $format
* @return type
*/
function get_all($table, $where = null, $format = OBJECT) {
global $wpdb;
if ($where == null) {
$result = $wpdb->get_results("select * from $table", $format);
} else {
$result = $wpdb->get_results("select * from $table $where", $format);
}
return $result;
}
function set_field($table, $id, $field, $value) {
global $wpdb;
$field = (string)$field;
$id = (int)$id;
$value = (string)$value;
if (preg_match('/^[a-zA-Z_]+$/', $field) == 0) {
$this->logger->error('Invalis field name: ' . $field_name);
return false;
}
$result = $wpdb->query($wpdb->prepare("update $table set $field=%s where id=%d limit 1", $value, $id));
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $result;
}
function query($query) {
global $wpdb;
$result = $wpdb->query($query);
if ($wpdb->last_error) {
$this->logger->error($wpdb->last_error);
return false;
}
return $result;
}
}

View File

@@ -0,0 +1,225 @@
<?php
if (!defined('ABSPATH')) exit;
class NewsletterThemes {
var $module;
var $is_extension = false;
function __construct($module, $is_extension = false) {
$this->module = $module;
$this->is_extension = $is_extension;
}
/** Loads all themes of a module (actually only "emails" module makes sense). Themes are located inside the subfolder
* named as the module on plugin folder and on a subfolder named as the module on wp-content/newsletter folder (which
* must be manually created).
*
* @param type $module
* @return type
*/
function get_all() {
$list = array();
$dir = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes';
$handle = @opendir($dir);
if ($handle !== false) {
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..')
continue;
if (!is_file($dir . '/' . $file . '/theme.php'))
continue;
$list[$file] = $file;
}
closedir($handle);
}
if (!$this->is_extension) {
$dir = NEWSLETTER_DIR . '/' . $this->module . '/themes';
$handle = @opendir($dir);
if ($handle !== false) {
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..')
continue;
if (isset($list[$file]))
continue;
if (!is_file($dir . '/' . $file . '/theme.php'))
continue;
$list[$file] = $file;
}
closedir($handle);
}
}
return $list;
}
function themescmp($a, $b) {
$al = strtolower($a['name']);
$bl = strtolower($b['name']);
if ($al == 'default') {
return -1;
}
return (strcmp($al, $bl));
}
function get_all_with_data() {
$list = array();
$dir = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes';
$handle = @opendir($dir);
if ($handle !== false) {
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..') {
continue;
}
if (isset($list[$file])) {
continue;
}
if (!is_file($dir . '/' . $file . '/theme.php')) {
continue;
}
$data = get_file_data($dir . '/' . $file . '/theme.php', array('name' => 'Name', 'type' => 'Type', 'description'=>'Description'));
$data['id'] = $file;
if (empty($data['name'])) {
$data['name'] = $file;
}
if (empty($data['type'])) {
$data['type'] = 'standard';
}
$screenshot = $dir . '/' . $file . '/screenshot.png';
if (is_file($screenshot)) {
$data['screenshot'] = $this->get_theme_url($file) . '/screenshot.png';
} else {
$data['screenshot'] = plugins_url('newsletter') . '/images/theme-screenshot.png';
}
$list[$file] = $data;
}
closedir($handle);
}
if (!$this->is_extension) {
$dir = NEWSLETTER_DIR . '/' . $this->module . '/themes';
$handle = @opendir($dir);
if ($handle !== false) {
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..') {
continue;
}
if (!is_file($dir . '/' . $file . '/theme.php')) {
continue;
}
$data = get_file_data($dir . '/' . $file . '/theme.php', array('name' => 'Name', 'type' => 'Type', 'description'=>'Description'));
$data['id'] = $file;
if (empty($data['name'])) {
$data['name'] = $file;
}
if (empty($data['type'])) {
$data['type'] = 'standard';
}
$screenshot = $dir . '/' . $file . '/screenshot.png';
if (is_file($screenshot)) {
$data['screenshot'] = $this->get_theme_url($file) . '/screenshot.png';
} else {
$data['screenshot'] = plugins_url('newsletter') . '/images/theme-screenshot.png';
}
$list[$file] = $data;
}
closedir($handle);
}
}
usort($list, array($this, "themescmp"));
return $list;
}
/**
*
* @param type $theme
* @param type $options
* @param type $module
*/
function save_options($theme, &$options) {
add_option('newsletter_' . $this->module . '_theme_' . $theme, array(), null, 'no');
$theme_options = array();
foreach ($options as $key => &$value) {
if (substr($key, 0, 6) != 'theme_')
continue;
$theme_options[$key] = $value;
}
update_option('newsletter_' . $this->module . '_theme_' . $theme, $theme_options);
}
function get_options($theme) {
$options = get_option('newsletter_' . $this->module . '_theme_' . $theme);
// To avoid merge problems.
if (!is_array($options)) {
$options = array();
}
$file = $this->get_file_path($theme, 'theme-defaults.php');
if (is_file($file)) {
@include $file;
}
if (isset($theme_defaults) && is_array($theme_defaults)) {
$options = array_merge($theme_defaults, $options);
}
return $options;
}
function get_file_path($theme, $file) {
$path = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes/' . $theme . '/' . $file;
if (is_file($path)) {
return $path;
} else {
return NEWSLETTER_DIR . '/' . $this->module . '/themes/' . $theme . '/' . $file;
}
}
function get_theme_url($theme) {
if ($this->is_extension) {
return WP_CONTENT_URL . '/extensions/newsletter/' . $this->module . '/themes/' . $theme;
}
$path = NEWSLETTER_DIR . '/' . $this->module . '/themes/' . $theme;
if (is_dir($path)) {
return plugins_url('newsletter') . '/' . $this->module . '/themes/' . $theme;
} else {
return WP_CONTENT_URL . '/extensions/newsletter/' . $this->module . '/themes/' . $theme;
}
}
function get_default_options() {
if ($this->is_extension) {
$path2 = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes/' . $theme . '/languages';
@include $path2 . '/en_US.php';
@include $path2 . '/' . WPLANG . '.php';
} else {
$path1 = NEWSLETTER_DIR . '/' . $this->module . '/themes/' . $theme . '/languages';
$path2 = WP_CONTENT_DIR . '/extensions/newsletter/' . $this->module . '/themes/' . $theme . '/languages';
@include $path1 . '/en_US.php';
@include $path2 . '/en_US.php';
@include $path1 . '/' . WPLANG . '.php';
@include $path2 . '/' . WPLANG . '.php';
}
if (!is_array($options))
return array();
return $options;
}
}
function nt_option($name, $def = null) {
$options = get_option('newsletter_email');
$option = $options['theme_' . $name];
if (!isset($option))
return $def;
else
return $option;
}

View File

@@ -0,0 +1,252 @@
(function (blocks, editor, element, components) {
const el = element.createElement;
const {registerBlockType} = blocks;
const { RichText, InspectorControls, withColors, PanelColorSettings, getColorClassName, AlignmentToolbar, BlockControls } = editor;
const { Fragment } = element;
const { TextControl, RadioControl, Panel, PanelBody, PanelRow, SelectControl, RangeControl } = components;
const colorSamples = [
{
name: 'GREEN SEA',
slug: 'GREENSEA',
color: '#16A085'
},
{
name: 'NEPHRITIS',
slug: 'NEPHRITIS',
color: '#27AE60'
},
{
name: 'BELIZE HOLE',
slug: 'BELIZEHOLE',
color: '#2980B9'
},
{
name: 'WISTERIA',
slug: 'WISTERIA',
color: '#8E44AD'
},
{
name: 'MIDNIGHT BLUE',
slug: 'MIDNIGHTBLUE',
color: '#2C3E50'
},
{
name: 'ORANGE',
slug: 'ORANGE',
color: '#F39C12'
},
{
name: 'ALIZARIN',
slug: 'ALIZARIN',
color: '#E74C3C'
},
{
name: 'WHITE',
slug: 'WHITE',
color: '#FFFFFF'
},
{
name: 'CLOUDS',
slug: 'CLOUDS',
color: '#ECF0F1'
},
{
name: 'ASBESTOS',
slug: 'ASBESTOS',
color: '#7F8C8D'
}
];
registerBlockType('tnp/minimal', {
title: 'Newsletter subscription form',
icon: 'email',
category: 'common',
keywords: ['newsletter', 'subscription', 'form'],
attributes: {
formtype: {type: 'string', default: 'minimal'},
content: { type: 'array', source: 'children', selector: 'p', default: 'Subscribe to our newsletter!'},
list_ids: { type: 'string' },
rowColor: { type: 'string'},
customRowColor: { type: 'string'},
textColor: { type: 'string'},
customTextColor: { type: 'string'},
buttonColor: { type: 'string'},
customButtonColor: { type: 'string'},
padding: {type: 'integer', default: 20},
alignment: { type: 'string'}
},
edit: withColors('rowColor', 'textColor', 'buttonColor')(function (props) {
function onChangeContent( newContent ) {
props.setAttributes( { content: newContent } );
}
function onChangeAlignment( newAlignment ) {
props.setAttributes( { alignment: newAlignment } );
}
return el( Fragment, {},
el( InspectorControls, {},
// 1st Panel - Form Settings
el( PanelBody, { title: 'Form Settings', initialOpen: true },
/* Form type */
el( RadioControl,
{
label: 'Form type',
options : [
{ label: 'Minimal', value: 'minimal' },
{ label: 'Full', value: 'full' },
],
onChange: ( value ) => {
props.setAttributes( { formtype: value } );
},
selected: props.attributes.formtype
}
),
/* Lists field */
el( PanelRow, {},
el( TextControl,
{
label: 'Lists IDs (comma separated)',
onChange: ( value ) => {
props.setAttributes( { list_ids: value } );
},
value: props.attributes.list_ids
}
)
)
),
/* Style */
el( PanelColorSettings, {
title: 'Style',
colorSettings: [
{
colors: colorSamples, // here you can pass custom colors
value: props.rowColor.color,
label: 'Background color',
onChange: props.setRowColor,
},
{
colors: colorSamples, // here you can pass custom colors
value: props.textColor.color,
label: 'Text color',
onChange: props.setTextColor,
},
{
colors: colorSamples, // here you can pass custom colors
value: props.buttonColor.color,
label: 'Button color',
onChange: props.setButtonColor,
}
]
}),
el( RangeControl,
{
label: 'Padding',
min: 0,
max: 100,
onChange: ( value ) => {
props.setAttributes( { padding: value } );
},
value: props.attributes.padding
}
)
),
el(
"div",
{style: {backgroundColor: props.rowColor.color, color: props.textColor.color, padding: props.attributes.padding, textAlign: props.attributes.alignment}},
el(
BlockControls,
{ key: 'controls' },
el(
AlignmentToolbar,
{
value: props.attributes.alignment,
onChange: onChangeAlignment
}
)
),
el(RichText,
{
tagName: 'p',
format: 'string',
onChange: onChangeContent,
value: props.attributes.content,
// formattingControls: [ 'bold' ]
}),
el('div',
{style: {backgroundColor: 'lightGrey', margin: '20px', padding: '5px',
fontFamily: '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif'}},
el('svg',
{
width: 20,
height: 20
},
wp.element.createElement( 'path',
{
d: "M6 14H4V6h2V4H2v12h4M7.1 17h2.1l3.7-14h-2.1M14 4v2h2v8h-2v2h4V4"
}
)
),
' Newsletter Form'
),
))
}),
save: function (props) {
var rowClass = getColorClassName( 'row-color', props.attributes.rowColor );
var textClass = getColorClassName( 'text-color', props.attributes.textColor );
var buttonClass = getColorClassName( 'button-color', props.attributes.buttonColor );
formtype_attr = "";
if (props.attributes.formtype != "full") {
formtype_attr = " type=\"minimal\"";
}
lists_attr = "";
if (props.attributes.list_ids != "") {
lists_attr = " lists=\"" + props.attributes.list_ids + "\"";
}
button_color_attr = "";
button_color = buttonClass ? undefined : props.attributes.customButtonColor;
if (button_color != "") {
button_color_attr = " button_color=\"" + button_color + "\"";
}
var formStyles = {
backgroundColor: rowClass ? undefined : props.attributes.customRowColor,
color: textClass ? undefined : props.attributes.customTextColor,
padding: props.attributes.padding,
textAlign: props.attributes.alignment
};
return (
el('div', {style: formStyles},
el( RichText.Content, {
tagName: 'p',
value: props.attributes.content
}),
el(
"div",
{},
"[newsletter_form" + formtype_attr + lists_attr + button_color_attr + "]"
)));
}
});
})(
window.wp.blocks,
window.wp.editor,
window.wp.element,
window.wp.components,
);