Plugin Directory

Changeset 3354585


Ignore:
Timestamp:
09/02/2025 11:06:53 AM (6 months ago)
Author:
sendpulse
Message:

Updated to 2.2.1

Location:
sendpulse-email-marketing-newsletter
Files:
86 added
24 edited

Legend:

Unmodified
Added
Removed
  • sendpulse-email-marketing-newsletter/trunk

    • Property svn:ignore set to
      *.cache
      Makefile
      phpunit.xml
  • sendpulse-email-marketing-newsletter/trunk/changelog.txt

    r3327368 r3354585  
    7272= 2.2.0 - 2025-07-14 =
    7373* Fix vendor library crashing on PHP8.3
     74
     75= 2.2.1 - 29.07.2025 =
     76* Removed deprecated PHP code and compatibility with PHP < 7.2
     77* Updated minimum PHP requirement to 7.2 (recommended 8.2+)
     78* Improved security by preventing direct file access
     79* Updated plugin header and metadata for clarity
     80* Cleaned up unused Gulp build system from production package
     81* Refined plugin tags for better discoverability
     82* Fixed paths and error handling in custom error page template
     83* Verified compatibility with WordPress 6.8.2
  • sendpulse-email-marketing-newsletter/trunk/composer.json

    r1732734 r3354585  
    77  ],
    88  "require": {
    9     "tareq1988/wordpress-settings-api-class": "dev-master",
    10     "sendpulse/sendpulse-rest-api-php": "dev-master"
     9    "sendpulse/rest-api": "^2.0"
    1110  }
    1211}
  • sendpulse-email-marketing-newsletter/trunk/composer.lock

    r1732734 r3354585  
    22    "_readme": [
    33        "This file locks the dependencies of your project to a known state",
    4         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
     4        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
    55        "This file is @generated automatically"
    66    ],
    7     "hash": "f99d769714d1b66fe7d1df7260a981f4",
    8     "content-hash": "97660baa502a9af717823d937d1685c5",
     7    "content-hash": "82ccf865108d441c4ebcc292ceb29dc5",
    98    "packages": [
    109        {
    11             "name": "sendpulse/sendpulse-rest-api-php",
    12             "version": "dev-master",
     10            "name": "sendpulse/rest-api",
     11            "version": "2.0.1.2",
    1312            "source": {
    1413                "type": "git",
    1514                "url": "https://github.com/sendpulse/sendpulse-rest-api-php.git",
    16                 "reference": "47d66d03b6c9fcc3feae337dc3ae86c42bb364b3"
     15                "reference": "457ca31c0ff3a3f849182d053d50928085d432ae"
    1716            },
    1817            "require": {
    19                 "php": ">=5.4.0"
     18                "ext-curl": "*",
     19                "ext-json": "*",
     20                "php": ">=7.1.0"
    2021            },
    2122            "type": "library",
    2223            "autoload": {
    23                 "classmap": [
    24                     "api/"
    25                 ]
     24                "psr-4": {
     25                    "Sendpulse\\RestApi\\": "src/"
     26                }
    2627            },
    27             "description": "The Sendpulse API functions.",
    28             "time": "2017-06-27 12:29:09"
    29         },
    30         {
    31             "name": "tareq1988/wordpress-settings-api-class",
    32             "version": "dev-master",
    33             "source": {
    34                 "type": "git",
    35                 "url": "https://github.com/tareq1988/wordpress-settings-api-class.git",
    36                 "reference": "11a1685a3dd1b0451674c18288e5bd129dcbebe6"
    37             },
    38             "dist": {
    39                 "type": "zip",
    40                 "url": "https://api.github.com/repos/tareq1988/wordpress-settings-api-class/zipball/11a1685a3dd1b0451674c18288e5bd129dcbebe6",
    41                 "reference": "11a1685a3dd1b0451674c18288e5bd129dcbebe6",
    42                 "shasum": ""
    43             },
    44             "require": {
    45                 "php": ">=5.2.4"
    46             },
    47             "type": "library",
    48             "autoload": {
    49                 "classmap": [
    50                     "src/"
    51                 ]
    52             },
    53             "notification-url": "https://packagist.org/downloads/",
    5428            "license": [
    55                 "GPLv2"
     29                "MIT"
    5630            ],
    5731            "authors": [
    5832                {
    59                     "name": "Tareq Hasan",
    60                     "email": "[email protected]",
    61                     "homepage": "http://tareq.wedevs.com",
    62                     "role": "Developer"
     33                    "name": "Maksym Ustymenko",
     34                    "email": "[email protected]"
     35                },
     36                {
     37                    "name": "Alexey Moroz",
     38                    "email": "[email protected]"
     39                },
     40                {
     41                    "name": "Evgeniy Bilovol",
     42                    "email": "[email protected]"
    6343                }
    6444            ],
    65             "description": "WordPress settings API Abstraction Class",
    66             "homepage": "https://github.com/tareq1988/wordpress-settings-api-class",
     45            "description": "Sendpulse REST API client library",
    6746            "keywords": [
    68                 "settings-api",
    69                 "wordpress",
    70                 "wp"
     47                "api",
     48                "rest",
     49                "sendpulse"
    7150            ],
    72             "time": "2017-07-02 14:15:10"
     51            "time": "2024-06-03T10:49:25+00:00"
    7352        }
    7453    ],
     
    7655    "aliases": [],
    7756    "minimum-stability": "stable",
    78     "stability-flags": {
    79         "tareq1988/wordpress-settings-api-class": 20,
    80         "sendpulse/sendpulse-rest-api-php": 20
    81     },
     57    "stability-flags": [],
    8258    "prefer-stable": false,
    8359    "prefer-lowest": false,
    8460    "platform": [],
    85     "platform-dev": []
     61    "platform-dev": [],
     62    "plugin-api-version": "2.6.0"
    8663}
  • sendpulse-email-marketing-newsletter/trunk/custom-error-page.php

    r2933319 r3354585  
    66// Load WordPress environment
    77require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php');
    8 
    9 // Get the admin header
    108require_once(ABSPATH . 'wp-admin/admin-header.php');
    119
    12 $storage_text = '<b>storage</b>';
    13 $permission_text = '<b>0775</b>';
    14 $group_text = '<b>www-data</b>';
     10$storage_text    = wp_kses_post('<b>storage</b>');
     11$permission_text = wp_kses_post('<b>0775</b>');
     12$group_text      = wp_kses_post('<b>www-data</b>');
     13?>
    1514
    16 ?>
    1715    <div class="wrap">
    18         <h1><?php _e('"SendPulse Email Marketing Newsletter" Plugin cannot be activated.', 'sendpulse-email-marketing-newsletter'); ?></h1>
    19         <h4><?php _e('Something wrong with your hosting setup. Please, ask hosting team to check for correct permissions for WordPress folders, owner and group.', 'sendpulse-email-marketing-newsletter'); ?></h4>
    20         <h4><?php _e('Also check for error messages at server log files.', 'sendpulse-email-marketing-newsletter'); ?></h4>
     16        <h1><?php esc_html_e('"SendPulse Email Marketing Newsletter" Plugin cannot be activated.', 'sendpulse-email-marketing-newsletter'); ?></h1>
     17        <h4><?php esc_html_e('Something wrong with your hosting setup. Please, ask hosting team to check for correct permissions for WordPress folders, owner and group.', 'sendpulse-email-marketing-newsletter'); ?></h4>
     18        <h4><?php esc_html_e('Also check for error messages at server log files.', 'sendpulse-email-marketing-newsletter'); ?></h4>
    2119
    2220        <p>
    23             <?php echo sprintf(__('Please make sure the "sendpulse-email-marketing-newsletter/%s", folder is writable, has the correct permissions %s and group set to %s .', 'sendpulse-email-marketing-newsletter'), $storage_text, $permission_text, $group_text); ?><br>
    24             <?php _e('If you cannot change permissions on your own, ask your hosting company for help.', 'sendpulse-email-marketing-newsletter'); ?>
     21            <?php
     22            // translators: 1. Folder path, 2. Permissions value, 3. Group name.
     23            echo wp_kses_post( sprintf(__('Please make sure the "sendpulse-email-marketing-newsletter/%1$s", folder is writable, has the correct permissions %2$s and group set to %3$s.', 'sendpulse-email-marketing-newsletter'),
     24                $storage_text,
     25                $permission_text,
     26                $group_text
     27            ) );
     28            ?>
     29            <br>
     30            <?php esc_html_e('If you cannot change permissions on your own, ask your hosting company for help.', 'sendpulse-email-marketing-newsletter'); ?>
    2531        </p>
    26         <p><?php _e('"SendPulse Email Marketing Newsletter" Plugin will be deactivated to prevent your site from crashing.', 'sendpulse-email-marketing-newsletter'); ?></p>
     32        <p><?php esc_html_e('"SendPulse Email Marketing Newsletter" Plugin will be deactivated to prevent your site from crashing.', 'sendpulse-email-marketing-newsletter'); ?></p>
    2733        <h4>
    28             <?php _e('You will be redirected in ', 'sendpulse-email-marketing-newsletter'); ?>
    29             <span id="countdown" style="color: red">6</span> <?php _e('seconds back to your plugins page.', 'sendpulse-email-marketing-newsletter'); ?>
     34            <?php esc_html_e('You will be redirected in ', 'sendpulse-email-marketing-newsletter'); ?>
     35            <span id="countdown" style="color: red">6</span>
     36            <?php esc_html_e('seconds back to your plugins page.', 'sendpulse-email-marketing-newsletter'); ?>
    3037        </h4>
    3138    </div>
     39
    3240    <script>
    33         // Countdown function
    3441        function countdown() {
    35             var seconds = document.getElementById('countdown').innerHTML;
    36             seconds = parseInt(seconds, 10);
     42            var seconds = parseInt(document.getElementById('countdown').innerHTML, 10);
    3743
    38             if (seconds == 0) {
    39                 // Redirect to plugins page
     44            if (seconds === 0) {
    4045                window.location.href = "<?php echo esc_url(admin_url('plugins.php')); ?>";
    4146            } else {
    42                 seconds--;
    43                 document.getElementById('countdown').innerHTML = seconds;
    44                 setTimeout(countdown, 1000); // Call countdown function after 1 second
     47                document.getElementById('countdown').innerHTML = seconds - 1;
     48                setTimeout(countdown, 1000);
    4549            }
    4650        }
    47 
    48         // Start the countdown
    4951        countdown();
    5052    </script>
    5153
    52 <?php
    53 // Get the admin footer
    54 require_once(ABSPATH . 'wp-admin/admin-footer.php');
     54<?php require_once(ABSPATH . 'wp-admin/admin-footer.php'); ?>
  • sendpulse-email-marketing-newsletter/trunk/inc/class-sendpulse-newsletter-ajax.php

    r2791914 r3354585  
    88class Send_Pulse_Newsletter_Ajax {
    99
     10    private $log_key = 'sendpulse_import_log';
     11
     12    private function log_progress( $msg ) {
     13        $log = get_transient( $this->log_key );
     14        if ( ! $log ) {
     15            $log = [];
     16        }
     17
     18        $log[] = current_time( 'mysql' ) . ' ' . $msg;
     19        set_transient( $this->log_key, $log, 60 );
     20    }
    1021
    1122    /**
     
    1526     */
    1627    public function __construct() {
    17 
    18         add_action( 'wp_ajax_sendpulse_import', array( $this, 'import' ) );
    19 
    20     }
     28        add_action( 'wp_ajax_sendpulse_import', [ $this, 'import' ] );
     29        add_action( 'wp_ajax_sendpulse_get_import_data', [ $this, 'get_import_data' ] );
     30        add_action( 'wp_ajax_sendpulse_get_import_data', [ $this, 'ajax_get_import_data' ] );
     31        add_action( 'wp_ajax_sendpulse_get_import_log',  [ $this, 'get_import_log' ] );
     32    }
    2133
    2234    /**
     
    2436     */
    2537    public function import() {
     38        delete_transient( $this->log_key );
     39        /** @phpstan-ignore-next-line */
     40        $this->log_progress( __( 'Import started', 'sendpulse-email-marketing-newsletter' ) );
    2641
    2742        check_ajax_referer( 'sendpulse_import' );
    2843
    29         $book = isset( $_POST['book'] ) ? sanitize_text_field( $_POST['book'] ) : '';
    30         $role = isset( $_POST['role'] ) ? sanitize_text_field( $_POST['role'] ) : '';
    31 
    32         $msg = array(); // log emulation
     44        $book = isset( $_POST['book'] ) ? sanitize_text_field( wp_unslash( $_POST['book'] ) ) : '';
     45        $role = isset( $_POST['role'] ) ? sanitize_text_field( wp_unslash( $_POST['role'] ) ) : '';
     46        $msg  = [];
    3347
    3448        if ( empty( $book ) ) {
    35             $msg[] = ( __( 'Please, select Address Book', 'sendpulse-email-marketing-newsletter' ) );
     49            $msg[] = __( 'Please, select Address Book', 'sendpulse-email-marketing-newsletter' );
     50        }
     51        if ( empty( $role ) ) {
     52            $msg[] = __( 'Please, select Users Role', 'sendpulse-email-marketing-newsletter' );
    3653        }
    3754
    38         if ( empty( $role ) ) {
    39             $msg[] = ( __( 'Please, select Users Role', 'sendpulse-email-marketing-newsletter' ) );
     55        if ( ! empty( $msg ) ) {
     56            wp_send_json_success( [ 'msg' => implode( "\n", $msg ) ] );
    4057        }
    4158
    42         if ( empty( $msg ) ) {
     59        $api   = new Send_Pulse_Newsletter_API();
     60        $users = get_users( [ 'role' => $role ] );
    4361
    44             $msg[] = current_time( 'mysql' ) . ' ' . __( 'Import start', 'sendpulse-email-marketing-newsletter' );
     62        if ( empty( $users ) ) {
     63            $msg[] = __( 'No users found with selected role.', 'sendpulse-email-marketing-newsletter' );
     64            wp_send_json_success( [ 'msg' => implode( "\n", $msg ) ] );
     65        }
    4566
     67        foreach ( $users as $user ) {
     68            $email     = sanitize_email( $user->user_email );
     69            $variables = [ 'name' => $user->display_name ];
    4670
    47             $api = new Send_Pulse_Newsletter_API();
     71            $user_ip = Send_Pulse_Newsletter_Users::get_user_ip( $user->ID );
     72            if ( ! empty( $user_ip ) ) {
     73                $variables['subscribe_ip'] = $user_ip;
     74            }
    4875
    49             $emails = array();
    50 
    51             $users = get_users( array(
    52                     'role' => $role
     76            /* translators: %1$s: user email, %2$s: user display name */
     77            $this->log_progress(sprintf(__( 'Adding user: %1$s (%2$s)', 'sendpulse-email-marketing-newsletter' ),
     78                    $email,
     79                    $user->display_name
    5380                )
    5481            );
    5582
     83            $result = $api->add_contact_to_list( $email, $book, $variables );
    5684
    57             foreach ( $users as $user ) {
    58                 $email = array(
    59                     'email'     => $user->user_email,
    60                     'variables' => array(
    61                         'name' => $user->display_name
     85            if ( is_wp_error( $result ) ) {
     86                /* translators: %1$s: user email, %2$s: error message */
     87                $this->log_progress(sprintf(__( 'Error adding %1$s: %2$s', 'sendpulse-email-marketing-newsletter' ),
     88                        $email,
     89                        $result->get_error_message()
    6290                    )
    6391                );
    64 
    65                 $user_ip = Send_Pulse_Newsletter_Users::get_user_ip( $user->ID );
    66 
    67                 if ( $user_ip ) {
    68                     $email['variables']['subscribe_ip'] = $user_ip;
    69                 }
    70 
    71                 $emails[] = $email;
    72 
    73                 $msg[] = sprintf( '%s: %s %s', __( 'Add user', 'sendpulse-email-marketing-newsletter' ), $user->user_email, $user->display_name );
     92            } else {
     93                /* translators: %s: user email */
     94                $this->log_progress(sprintf(__( 'Successfully added %s', 'sendpulse-email-marketing-newsletter' ),
     95                        $email
     96                    )
     97                );
    7498            }
    75 
    76             $result = $api->addEmails( $book, $emails );
    77 
    78             if ( isset( $result->is_error ) && $result->is_error ) {
    79                 $msg[] = isset( $result->message ) ? $result->message : __( 'Something went wrong. Import unsuccessful', 'sendpulse-email-marketing-newsletter' );
    80             }
    81 
    82 
    83             $msg[] = current_time( 'mysql' ) . ' ' . __( 'Import finished', 'sendpulse-email-marketing-newsletter' );
    84 
    8599        }
    86100
    87         wp_send_json_success( array( 'msg' => implode( "\n", $msg ) ) );
     101        $this->log_progress( __( 'Import finished', 'sendpulse-email-marketing-newsletter' ) );
    88102
     103        /* translators: This message appears in the import log when the process completes */
     104        wp_send_json_success(
     105            [
     106                'msg' => __( 'Import finished. You can check the log.', 'sendpulse-email-marketing-newsletter' ),
     107            ]
     108        );
     109    }
    89110
    90     }
     111    public function get_import_data() {
     112        check_ajax_referer( 'sendpulse_import' );
     113
     114        $api = new Send_Pulse_Newsletter_API();
     115        $books = $api->listAddressBooks();
     116
     117        $roles = wp_roles()->roles;
     118        $formatted_roles = array();
     119
     120        foreach ( $roles as $key => $role ) {
     121            $formatted_roles[] = array(
     122                'value' => $key,
     123                'label' => $role['name'],
     124            );
     125        }
     126
     127        wp_send_json_success( array(
     128            'books' => $books,
     129            'roles' => $formatted_roles,
     130        ) );
     131    }
     132
     133    public function ajax_get_import_data() {
     134        check_ajax_referer( 'sendpulse_import' );
     135
     136        $books = [];
     137        $roles = [];
     138
     139        try {
     140            $api = new Send_Pulse_Newsletter_API();
     141            $books = $api->get_books(); // Returns array with ['id', 'name']
     142        } catch ( Exception $e ) {
     143            wp_send_json_error( [ 'message' => 'Failed to fetch books: ' . $e->getMessage() ] );
     144        }
     145
     146        // Get all roles from WP
     147        global $wp_roles;
     148        foreach ( $wp_roles->roles as $key => $role ) {
     149            $roles[] = [
     150                'value' => $key,
     151                'label' => $role['name']
     152            ];
     153        }
     154
     155        wp_send_json_success( [
     156            'books' => $books,
     157            'roles' => $roles
     158        ] );
     159    }
     160
     161    public function get_import_log() {
     162        check_ajax_referer( 'sendpulse_import' );
     163        $log = get_transient( $this->log_key );
     164        if ( ! is_array( $log ) ) {
     165            $log = [];
     166        }
     167
     168        wp_send_json_success([
     169            'log' => implode( "\n", $log )
     170        ]);
     171    }
     172
    91173
    92174}
  • sendpulse-email-marketing-newsletter/trunk/inc/class-sendpulse-newsletter-api.php

    r2938759 r3354585  
    11<?php
     2use Sendpulse\RestApi\ApiClient;
     3use Sendpulse\RestApi\Storage\SessionStorage;
     4use Sendpulse\RestApi\Storage\FileStorage;
    25
    3 /**
    4  * Extend library class.
    5  *
    6  * Class Send_Pulse_Newsletter_API
    7  */
    8 class Send_Pulse_Newsletter_API extends SendpulseApi {
     6class Send_Pulse_Newsletter_API
     7{
    98
    10     /**
    11      * @var string|int Id default address book for subscribe.
    12     */
    13     public $default_book;
     9    /**
     10     * @var ApiClient
     11    */
     12    protected $api;
    1413
     14    /**
     15     * @var string|int Id default address book for subscribe.
     16     */
     17    public $default_book;
    1518
    16     /**
    17      * Get client option. Api ready for using.
    18      *
    19      * Send_Pulse_Newsletter_API constructor.
    20      */
    21     public function __construct() {
    22         $user_id = $this->get_option( 'client_id' );
    23         $secret  = $this->get_option( 'client_secret' );
     19    /**
     20     * @var Send_Pulse_Newsletter_Requirement
     21     */
     22    protected $requirement;
     23
     24//    public function __construct($apiClient = null)
     25//    {
     26//        $user_id = $this->get_option('client_id');
     27//        $secret = $this->get_option('client_secret');
     28//
     29//        $this->requirement = new Send_Pulse_Newsletter_Requirement();
     30//
     31//      if (!$apiClient) {
     32//          $storage       = null;
     33//          $notice_action = '';
     34//
     35//          if ( $this->requirement->is_folder_writable( SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR ) !== true ) {
     36//              $storage       = new SessionStorage();
     37//              $notice_action = 'sp_emp_admin_activated_session_storage_notice';
     38//          } else {
     39//              $storage       = new FileStorage( SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR );
     40//              $notice_action = 'sp_emp_admin_activated_file_storage_notice';
     41//          }
     42//
     43//          $this->api = new ApiClient( $user_id, $secret, $storage );
     44//
     45//          add_action( 'admin_notices', array( $this, $notice_action ) );
     46//      }
     47//
     48//      $this->api = $apiClient;
     49//        $this->default_book = $this->get_option('default_book');
     50//    }
     51    public function __construct($apiClient = null)
     52    {
     53        $user_id = $this->get_option('client_id');
     54        $secret  = $this->get_option('client_secret');
    2455
    2556        $this->requirement = new Send_Pulse_Newsletter_Requirement();
    2657
    27         $storage = null;
    28         $notice_action = '';
     58        if (!$apiClient) {
     59            $storage       = null;
     60            $notice_action = '';
    2961
    30         switch (true) {
    31             case $this->requirement->is_folder_writable(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR) !== true:
    32                 $storage = new SessionStorage();
     62            if ($this->requirement->is_folder_writable(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR) !== true) {
     63                $storage       = new SessionStorage();
    3364                $notice_action = 'sp_emp_admin_activated_session_storage_notice';
    34                 break;
     65            } else {
     66                $storage       = new FileStorage(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR);
     67                $notice_action = 'sp_emp_admin_activated_file_storage_notice';
     68            }
    3569
    36             default:
    37                 $storage = new FileStorage(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR);
    38                 $notice_action = 'sp_emp_admin_activated_file_storage_notice';
    39                 break;
     70            $this->api = new ApiClient($user_id, $secret, $storage);
     71            add_action('admin_notices', [$this, $notice_action]);
     72        } else {
     73            $this->api = $apiClient;
    4074        }
    4175
    42         parent::__construct($user_id, $secret, $storage);
    43         add_action( 'admin_notices', array( $this, $notice_action ) );
    44 
    45         $this->default_book = $this->get_option( 'default_book' );
     76        $this->default_book = $this->get_option('default_book');
    4677    }
    4778
    4879
    49     /**
    50      * Get plugin API Settings option.
    51      *
    52      * @param $name string Option name.
    53      *
    54      * @return string Option value
    55      */
    56     public function get_option( $name ) {
    57         return Send_Pulse_Newsletter_Settings::get_option( $name, 'sp_api_setting' );
    58     }
     80    public function get_option($name)
     81    {
     82        return Send_Pulse_Newsletter_Settings::get_option($name, 'sp_api_setting');
     83    }
    5984
    60     public function sp_emp_admin_activated_session_storage_notice() {
    61         $notice_dismissed = get_option('sp_emp_session_storage_notice_dismissed');
     85    public function get_api()
     86    {
     87        return $this->api;
     88    }
    6289
    63         if ($notice_dismissed) {
    64             return; // Don't display the notice if it has been dismissed
    65         }
     90    public function listAddressBooks( $limit = 100, $offset = 0 ) {
     91        try {
     92            $response = $this->api->get('addressbooks', [
     93                'limit'  => $limit,
     94                'offset' => $offset,
     95            ]);
    6696
    67         $message = sprintf(
    68             '<div class="notice notice-warning is-dismissible">
    69             <p><strong>%s</strong></p>
    70             <p>%s</p>
    71             <p>%s<br>%s</p>
    72             <p>%s</p>
    73             <p>%s</p>
    74             <button type="button" class="notice-dismiss">
    75                 <span class="screen-reader-text">%s</span>
    76             </button>
    77         </div>',
    78             esc_html__( 'The "SendPulse Email Marketing Newsletter" plugin is activated in safe mode with the SessionStorage feature enabled. The feature stores data only for the time of current session.', 'sendpulse-email-marketing-newsletter' ),
    79             esc_html__( 'To use the file storage for data, change the directory rights in the plugin storage folder to 775 (/wp-content/plugins/sendpulse-email-marketing-newsletter/storage). ', 'sendpulse-email-marketing-newsletter' ),
    80             esc_html__( 'You should also make sure that the owner or group is set as www-data for the plugin to save data to the folder. ', 'sendpulse-email-marketing-newsletter' ),
    81             esc_html__( 'If you are using Docker, check the relevant resources on setting up the environment or contact a dedicated tech specialist.', 'sendpulse-email-marketing-newsletter' ),
    82             esc_html__( 'It is recommended to use only SessionStorage for blogs built with wordpress.com. SessionStorage works same as FileStorage.', 'sendpulse-email-marketing-newsletter' ),
    83             esc_html__( 'You can close this notification by clicking the close button and it will never show up again.', 'sendpulse-email-marketing-newsletter' ),
    84             esc_html__( 'Dismiss this notification and never show it again.', 'sendpulse-email-marketing-newsletter' )
    85         );
    86         echo wp_kses_post( $message );
    87     }
     97            return $response;
     98        } catch (Exception $e) {
     99            return new WP_Error('sendpulse_error', $e->getMessage());
     100        }
     101    }
    88102
    89     public function sp_emp_admin_activated_file_storage_notice() {
    90         $notice_dismissed = get_option('sp_emp_file_storage_notice_dismissed');
     103    public function get_books() {
     104        $books = $this->api->listAddressBooks();
    91105
    92         if ($notice_dismissed) {
    93             return; // Don't display the notice if it has been dismissed
    94         }
     106        return array_map(function ($book) {
     107            return [
     108                'id' => $book['id'] ?? 'UNKNOWN',
     109                'name' => $book['name'] ?? 'UNKNOWN',
     110            ];
     111        }, $books);
     112    }
    95113
    96         $message = sprintf(
    97             '<div class="notice notice-success is-dismissible">
    98             <p><strong>%s</strong></p>
    99             <p>%s</p>
    100             <button type="button" class="notice-dismiss">
    101                 <span class="screen-reader-text">%s</span>
    102             </button>
    103         </div>',
    104             esc_html__( 'The "SendPulse Email Marketing Newsletter" plugin has been successfully activated in normal mode with the FileStorage feature enabled.', 'sendpulse-email-marketing-newsletter' ),
    105             esc_html__( 'You can close this notification by clicking the close button and it will never show up again.', 'sendpulse-email-marketing-newsletter' ),
    106             esc_html__( 'Dismiss this notification and never show it again.', 'sendpulse-email-marketing-newsletter' ),
    107         );
    108         echo wp_kses_post( $message );
    109     }
     114    public function add_contact_to_list($email, $book_id, $variables = [])
     115    {
     116        try {
     117            $response = $this->api->post("addressbooks/{$book_id}/emails", [
     118                'emails' => [
     119                    [
     120                        'email' => $email,
     121                        'variables' => $variables
     122                    ]
     123                ],
     124                'update_existing' => true
     125            ]);
    110126
     127            if ( !$response ) {
     128                return new WP_Error('sendpulse_error', json_encode($response));
     129            }
    111130
     131            return $response;
     132
     133        } catch (Exception $e) {
     134            return new WP_Error('sendpulse_error', $e->getMessage());
     135        }
     136    }
     137
     138    public function sp_emp_admin_activated_session_storage_notice()
     139    {
     140        if (get_option('sp_emp_session_storage_notice_dismissed')) return;
     141        echo wp_kses_post(sprintf(
     142            '<div class="notice notice-warning is-dismissible"><p><strong>%s</strong></p><p>%s</p><p>%s<br>%s</p><p>%s</p><p>%s</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">%s</span></button></div>',
     143            esc_html__('The "SendPulse Email Marketing Newsletter" plugin is activated in safe mode with the SessionStorage feature enabled.', 'sendpulse-email-marketing-newsletter'),
     144            esc_html__('To use file storage, change directory rights to 775: /storage.', 'sendpulse-email-marketing-newsletter'),
     145            esc_html__('Ensure owner or group is www-data.', 'sendpulse-email-marketing-newsletter'),
     146            esc_html__('If using Docker, check file permissions or consult your sysadmin.', 'sendpulse-email-marketing-newsletter'),
     147            esc_html__('Use only SessionStorage on wordpress.com sites.', 'sendpulse-email-marketing-newsletter'),
     148            esc_html__('You can close this notification by clicking dismiss.', 'sendpulse-email-marketing-newsletter'),
     149            esc_html__('Dismiss this notification and never show it again.', 'sendpulse-email-marketing-newsletter')
     150        ));
     151    }
     152
     153    public function sp_emp_admin_activated_file_storage_notice()
     154    {
     155        if (get_option('sp_emp_file_storage_notice_dismissed')) return;
     156        echo wp_kses_post(sprintf(
     157            '<div class="notice notice-success is-dismissible"><p><strong>%s</strong></p><p>%s</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">%s</span></button></div>',
     158            esc_html__('The "SendPulse Email Marketing Newsletter" plugin is activated in normal mode using FileStorage.', 'sendpulse-email-marketing-newsletter'),
     159            esc_html__('You can close this notification by clicking dismiss.', 'sendpulse-email-marketing-newsletter'),
     160            esc_html__('Dismiss this notification and never show it again.', 'sendpulse-email-marketing-newsletter')
     161        ));
     162    }
    112163}
  • sendpulse-email-marketing-newsletter/trunk/inc/class-sendpulse-newsletter-settings.php

    r3306401 r3354585  
    11<?php
    2 
    3 
    42/**
    53 * Plugin settings class
     
    86 */
    97class Send_Pulse_Newsletter_Settings {
    10 
    11     /**
    12      * @var WeDevs_Settings_API Instance helper library
    13      */
    14     private $settings_api;
    15 
    16     /**
    17      * @var string Error message
    18      */
    19     private $error = '';
    20 
    21     /**
    22      * @var null|Send_Pulse_Newsletter_API Instance SP_API class
    23      */
    24     private $api = null;
    25 
    26     /**
    27      * @var string Plugin page slug
    28      */
    29     private $page = 'send_pulse_settings';
    30 
    31     /**
    32      * Send_Pulse_Newsletter constructor.
    33      */
    34     public function __construct() {
    35         $this->settings_api = new WeDevs_Settings_API();
    36 
    37         add_action( 'admin_init', array( $this, 'admin_init' ) );
    38         add_action( 'admin_menu', array( $this, 'admin_menu' ) );
    39         add_action( 'wsa_form_top_sp_import_setting', array( $this, 'start_import_controls' ) );
    40         add_action( 'wsa_form_bottom_sp_import_setting', array( $this, 'end_import_controls' ) );
    41     }
    42 
    43     /**
    44      * Init SendPulse API Class
    45      */
    46     protected function init_api() {
    47         try {
    48             $this->api = new Send_Pulse_Newsletter_API();
    49 
    50             if ( 'on' == $this->api->get_option( 'is_subscribe_after_register' ) && empty( $this->api->default_book ) ) {
    51                 $this->error = __( 'Select a target mailing list and save your settings', 'sendpulse-email-marketing-newsletter' );
    52             }
    53 
    54         } catch ( Exception $exception ) {
    55             $this->error = $exception->getMessage();
     8    /**
     9     * @var string Error message
     10     */
     11    private $error = '';
     12
     13    /**
     14     * @var null|Send_Pulse_Newsletter_API Instance SP_API class
     15     */
     16    private $api = null;
     17
     18    /**
     19     * @var string Plugin page slug
     20     */
     21    private $page = 'send_pulse_settings';
     22
     23    /**
     24     * Send_Pulse_Newsletter constructor.
     25     */
     26    public function __construct() {
     27        add_action( 'admin_init', array( $this, 'admin_init' ) );
     28        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
     29        add_action( 'wsa_form_top_sp_import_setting', array( $this, 'start_import_controls' ) );
     30        add_action( 'wsa_form_bottom_sp_import_setting', array( $this, 'end_import_controls' ) );
     31    }
     32
     33    /**
     34     * Init SendPulse API Class
     35     */
     36    protected function init_api() {
     37        try {
     38            $this->api = new Send_Pulse_Newsletter_API();
     39
     40            if ( 'on' == $this->api->get_option( 'is_subscribe_after_register' ) && empty( $this->api->default_book ) ) {
     41                $this->error = __( 'Select a target mailing list and save your settings', 'sendpulse-email-marketing-newsletter' );
     42            }
     43
     44        } catch ( Exception $exception ) {
     45            $this->error = $exception->getMessage();
     46        }
     47    }
     48
     49    /**
     50     * Display settings.
     51     */
     52    function admin_init() {
     53        $this->init_api();
     54
     55        foreach ( $this->get_settings_sections() as $section ) {
     56            $section_id = $section['id'];
     57
     58            register_setting( $section_id, $section_id, array(
     59                'sanitize_callback' => array( $this, 'sanitize_settings_fields' )
     60            ) );
     61
     62            add_settings_section(
     63                $section_id,
     64                $section['title'],
     65                function () use ( $section ) {
     66                    echo '<p>' . esc_html( $section['title'] ) . '</p>';
     67                },
     68                $this->page
     69            );
     70
     71            $fields = $this->get_settings_fields();
     72
     73            if ( isset( $fields[ $section_id ] ) ) {
     74                foreach ( $fields[ $section_id ] as $field ) {
     75                    add_settings_field(
     76                        $field['name'],
     77                        $field['label'],
     78                        array( $this, 'render_field' ),
     79                        $this->page,
     80                        $section_id,
     81                        array_merge( $field, [ 'section' => $section_id ] )
     82                    );
     83                }
     84            }
     85        }
     86
     87        $nonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : '';
     88        if (
     89            $this->error &&
     90            isset( $_GET['page'] ) &&
     91            $this->page == $_GET['page'] &&
     92            $nonce &&
     93            wp_verify_nonce( $nonce, 'sendpulse_admin_page' )
     94        ) {
     95            add_settings_error( 'general', 'settings_updated', $this->error, 'error' );
     96        }
     97    }
     98
     99    public function sanitize_settings_fields( $input ) {
     100        $sanitized = array();
     101
     102        foreach ( $input as $key => $value ) {
     103            switch ( $key ) {
     104                case 'client_id':
     105                case 'client_secret':
     106                case 'default_book':
     107                    $sanitized[ $key ] = sanitize_text_field( $value );
     108                    break;
     109                case 'is_subscribe_after_register':
     110                    $sanitized[ $key ] = $value === 'on' ? 'on' : '';
     111                    break;
     112                default:
     113                    $sanitized[ $key ] = sanitize_text_field( $value );
     114                    break;
     115            }
     116        }
     117
     118        return $sanitized;
     119    }
     120
     121    public function render_field( $args ) {
     122        $option      = get_option( $args['section'] );
     123        $name        = $args['name'];
     124        $value       = isset( $option[ $name ] ) ? $option[ $name ] : '';
     125        $desc        = isset( $args['desc'] ) ? $args['desc'] : '';
     126        $placeholder = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
     127
     128        switch ( $args['type'] ) {
     129            case 'text':
     130                printf(
     131                    '<input type="text" name="%1$s[%2$s]" id="%2$s" value="%3$s" class="regular-text" placeholder="%4$s" />%5$s',
     132                    esc_attr( $args['section'] ),
     133                    esc_attr( $name ),
     134                    esc_attr( $value ),
     135                    esc_attr( $placeholder ),
     136                    $desc ? '<p class="description">' . esc_html( $desc ) . '</p>' : ''
     137                );
     138                break;
     139
     140            case 'checkbox':
     141                $checked = checked( $value, 'on', false );
     142                printf(
     143                    '<input type="checkbox" name="%1$s[%2$s]" id="%2$s" %3$s />%4$s',
     144                    esc_attr( $args['section'] ),
     145                    esc_attr( $name ),
     146                    wp_kses_post($checked),
     147                    $desc ? '<p class="description">' . esc_html( $desc ) . '</p>' : ''
     148                );
     149                break;
     150
     151            case 'select':
     152                echo '<select name="' . esc_attr( $args['section'] ) . '[' . esc_attr( $name ) . ']" id="' . esc_attr( $name ) . '">';
     153                foreach ( $args['options'] as $key => $label ) {
     154                    printf(
     155                        '<option value="%1$s" %2$s>%3$s</option>',
     156                        esc_attr( $key ),
     157                        selected( $value, $key, false ),
     158                        esc_html( $label )
     159                    );
     160                }
     161                echo '</select>';
     162                if ( $desc ) {
     163                    echo '<p class="description">' . esc_html( $desc ) . '</p>';
     164                }
     165                break;
    56166        }
    57167    }
    58168
    59     /**
    60      * Display settings.
    61      */
    62     function admin_init() {
    63 
    64         $this->init_api();
    65 
    66         //set the settings
    67         $this->settings_api->set_sections( $this->get_settings_sections() );
    68         $this->settings_api->set_fields( $this->get_settings_fields() );
    69         //initialize settings
    70         $this->settings_api->admin_init();
    71 
    72         if ( $this->error
    73              && isset( $_GET['page'] )
    74              && ( $this->page == $_GET['page'] )
    75         ) {
    76             add_settings_error( 'general', 'settings_updated', $this->error, 'error' );
    77 
    78         }
    79     }
    80 
    81     /**
    82      * Add submenu in Settings
    83      */
    84     function admin_menu() {
    85         add_submenu_page(
    86             'edit.php?post_type=sendpulse_form',
    87             __( 'Settings' ),
    88             __( 'Settings' ),
    89             'delete_posts',
    90             'send_pulse_settings',
    91             array( $this, 'plugin_page' )
    92         );
    93     }
    94 
    95     /**
    96      * @return array Section
    97      */
    98     function get_settings_sections() {
    99         $sections = array(
    100             array(
    101                 'id'    => 'sp_api_setting',
    102                 'title' => __( 'API Settings', 'sendpulse-email-marketing-newsletter' )
    103             ),
    104             array(
    105                 'id'    => 'sp_import_setting',
    106                 'title' => __( 'Import', 'sendpulse-email-marketing-newsletter' )
    107             )
    108         );
    109 
    110         return $sections;
    111     }
    112 
    113     /**
    114      * Returns all the settings fields
    115      *
    116      * @return array settings fields
    117      */
    118     function get_settings_fields() {
    119         $settings_fields = array(
    120             'sp_api_setting' => array(
    121                 array(
    122                     'name'              => 'client_id',
    123                     'label'             => __( 'Client ID', 'sendpulse-email-marketing-newsletter' ),
    124                     'desc'              => __( 'Get from https://login.sendpulse.com/settings/', 'sendpulse-email-marketing-newsletter' ),
    125                     'placeholder'       => __( 'Client ID', 'sendpulse-email-marketing-newsletter' ),
    126                     'type'              => 'text',
    127                     'default'           => '',
    128                     'sanitize_callback' => 'sanitize_text_field'
    129                 ),
    130                 array(
    131                     'name'              => 'client_secret',
    132                     'label'             => __( 'Client Secret', 'sendpulse-email-marketing-newsletter' ),
    133                     'desc'              => __( 'Get from https://login.sendpulse.com/settings/', 'sendpulse-email-marketing-newsletter' ),
    134                     'placeholder'       => __( 'Client Secret', 'sendpulse-email-marketing-newsletter' ),
    135                     'type'              => 'text',
    136                     'default'           => '',
    137                     'sanitize_callback' => 'sanitize_text_field'
    138                 )
    139 
    140             )
    141         );
    142 
    143         $settings_fields['sp_api_setting'][] =
    144             array(
    145                 'name'  => 'is_subscribe_after_register',
    146                 'label' => __( 'Post-subscription option', 'sendpulse-email-marketing-newsletter' ),
    147                 'desc'  => __( 'Add all new WordPress subscribers to the selected mailing list', 'sendpulse-email-marketing-newsletter' ),
    148                 'type'  => 'checkbox'
    149             );
    150 
    151         // Add customer address book list
    152         $books = $this->get_lists_address_book();
    153 
    154         if ( ! empty( $books ) ) {
    155             $options = array_combine( wp_list_pluck( $books, 'id' ), wp_list_pluck( $books, 'name' ) );
    156 
    157             $settings_fields['sp_api_setting'][] = array(
    158                 'name'    => 'default_book',
    159                 'label'   => __( 'Target mailing list', 'sendpulse-email-marketing-newsletter' ),
    160                 'desc'    => __( 'Add a mailing list in your SendPulse account new subscribers will be transferred to', 'sendpulse-email-marketing-newsletter' ),
    161                 'type'    => 'select',
    162                 'default' => '',
    163                 'options' => $options
    164             );
    165         }
    166 
    167 
    168         if ( ! empty( $books ) ) {
    169 
    170             $editable_roles = array_reverse( get_editable_roles() );
    171 
    172             $role_options = array();
    173 
    174             foreach ( $editable_roles as $role => $details ) {
    175                 $role_options[ $role ] = translate_user_role( $details['name'] );
    176             }
    177 
    178 
    179             $settings_fields['sp_import_setting'] = array(
    180                 array(
    181                     'name'    => 'import_to_book',
    182                     'label'   => __( 'Import to Address Book', 'sendpulse-email-marketing-newsletter' ),
    183                     'desc'    => __( 'Address Book for wordpress users import', 'sendpulse-email-marketing-newsletter' ),
    184                     'type'    => 'select',
    185                     'default' => '',
    186                     'options' => $options
    187                 ),
    188                 array(
    189                     'name'    => 'import_users_group',
    190                     'label'   => __( 'Import Users Group', 'sendpulse-email-marketing-newsletter' ),
    191                     'desc'    => __( 'Users Group that will be imported', 'sendpulse-email-marketing-newsletter' ),
    192                     'type'    => 'select',
    193                     'default' => '',
    194                     'options' => $role_options
    195                 )
    196 
    197             );
    198         }
    199 
    200         return $settings_fields;
    201     }
    202 
    203     /**
    204      * Display setting page
    205      */
    206     function plugin_page() {
    207 
    208         settings_errors();
    209 
    210         echo '<div class="wrap">';
    211         $this->settings_api->show_navigation();
    212         $this->settings_api->show_forms();
    213         echo '</div>';
    214     }
    215 
    216 
    217     /**
    218      * Get the value of a settings field
    219      *
    220      * @param string $option settings field name
    221      * @param string $section the section name this field belongs to
    222      * @param string $default default text if it's not found
    223      *
    224      * @return mixed
    225      */
    226 
    227     public static function get_option( $option, $section, $default = '' ) {
    228 
    229         $options = get_option( $section );
    230 
    231         if ( isset( $options[ $option ] ) ) {
    232             return $options[ $option ];
    233         }
    234 
    235         return $default;
    236     }
    237 
    238 
    239     /**
    240      * Get customer address books list
    241      *
    242      * @return array Address books list
    243      */
    244     protected function get_lists_address_book() {
    245 
    246         $books = array();
    247 
    248         if ( $this->api ) {
    249             $response = $this->api->listAddressBooks();
    250 
    251             if ( is_array( $response ) ) {
    252                 $books = $response;
    253             } elseif ( is_object( $response ) && empty( get_object_vars( $response ) ) ) {
     169    /**
     170     * Add submenu in Settings
     171     */
     172    function admin_menu() {
     173        add_submenu_page(
     174            'edit.php?post_type=sendpulse_form',
     175            __( 'Settings', 'sendpulse-email-marketing-newsletter' ),
     176            __( 'Settings', 'sendpulse-email-marketing-newsletter' ),
     177            'delete_posts',
     178            'send_pulse_settings',
     179            array( $this, 'plugin_page' )
     180        );
     181
     182        // Import submenu page
     183        add_submenu_page(
     184            'edit.php?post_type=sendpulse_form',
     185            __( 'Import Users', 'sendpulse-email-marketing-newsletter' ),
     186            __( 'Import Users', 'sendpulse-email-marketing-newsletter' ),
     187            'manage_options',
     188            'send_pulse_import',
     189            array( $this, 'import_page' )
     190        );
     191    }
     192
     193    /**
     194     * @return array Section
     195     */
     196    function get_settings_sections() {
     197        $sections = array(
     198            array(
     199                'id'    => 'sp_api_setting',
     200                'title' => __( 'API Settings', 'sendpulse-email-marketing-newsletter' )
     201            ),
     202            array(
     203                'id'    => 'sp_import_setting',
     204                'title' => __( 'Import', 'sendpulse-email-marketing-newsletter' )
     205            )
     206        );
     207
     208        return $sections;
     209    }
     210
     211    /**
     212     * Returns all the settings fields
     213     *
     214     * @return array settings fields
     215     */
     216    function get_settings_fields() {
     217        $settings_fields = array(
     218            'sp_api_setting' => array(
     219                array(
     220                    'name'              => 'client_id',
     221                    'label'             => __( 'Client ID', 'sendpulse-email-marketing-newsletter' ),
     222                    'desc'              => __( 'Get from https://login.sendpulse.com/settings/', 'sendpulse-email-marketing-newsletter' ),
     223                    'placeholder'       => __( 'Client ID', 'sendpulse-email-marketing-newsletter' ),
     224                    'type'              => 'text',
     225                    'default'           => '',
     226                    'sanitize_callback' => 'sanitize_text_field'
     227                ),
     228                array(
     229                    'name'              => 'client_secret',
     230                    'label'             => __( 'Client Secret', 'sendpulse-email-marketing-newsletter' ),
     231                    'desc'              => __( 'Get from https://login.sendpulse.com/settings/', 'sendpulse-email-marketing-newsletter' ),
     232                    'placeholder'       => __( 'Client Secret', 'sendpulse-email-marketing-newsletter' ),
     233                    'type'              => 'text',
     234                    'default'           => '',
     235                    'sanitize_callback' => 'sanitize_text_field'
     236                )
     237
     238            )
     239        );
     240
     241        $settings_fields['sp_api_setting'][] =
     242            array(
     243                'name'  => 'is_subscribe_after_register',
     244                'label' => __( 'Post-subscription option', 'sendpulse-email-marketing-newsletter' ),
     245                'desc'  => __( 'Add all new WordPress subscribers to the selected mailing list', 'sendpulse-email-marketing-newsletter' ),
     246                'type'  => 'checkbox'
     247            );
     248
     249        // Add customer address book list
     250        $books = $this->get_lists_address_book();
     251
     252        if ( ! empty( $books ) ) {
     253            $options = array_combine( wp_list_pluck( $books, 'id' ), wp_list_pluck( $books, 'name' ) );
     254            $settings_fields['sp_api_setting'][] = array(
     255                'name'              => 'default_book',
     256                'label'             => __( 'Target mailing list', 'sendpulse-email-marketing-newsletter' ),
     257                'desc'              => __( 'Add a mailing list in your SendPulse account new subscribers will be transferred to', 'sendpulse-email-marketing-newsletter' ),
     258                'type'              => 'select',
     259                'default'           => '',
     260                'options'           => $options,
     261                'sanitize_callback' => 'sanitize_text_field'
     262            );
     263        }
     264
     265
     266        if ( ! empty( $books ) ) {
     267
     268            $editable_roles = array_reverse( get_editable_roles() );
     269
     270            $role_options = array();
     271
     272            foreach ( $editable_roles as $role => $details ) {
     273                $role_options[ $role ] = translate_user_role( $details['name'] );
     274            }
     275
     276
     277            $settings_fields['sp_import_setting'] = array(
     278                array(
     279                    'name'    => 'import_to_book',
     280                    'label'   => __( 'Import to Address Book', 'sendpulse-email-marketing-newsletter' ),
     281                    'desc'    => __( 'Address Book for wordpress users import', 'sendpulse-email-marketing-newsletter' ),
     282                    'type'    => 'select',
     283                    'default' => '',
     284                    'options' => $options
     285                ),
     286                array(
     287                    'name'    => 'import_users_group',
     288                    'label'   => __( 'Import Users Group', 'sendpulse-email-marketing-newsletter' ),
     289                    'desc'    => __( 'Users Group that will be imported', 'sendpulse-email-marketing-newsletter' ),
     290                    'type'    => 'select',
     291                    'default' => '',
     292                    'options' => $role_options
     293                )
     294
     295            );
     296        }
     297
     298        return $settings_fields;
     299    }
     300
     301    /**
     302     * Display setting page
     303     */
     304    public function plugin_page() {
     305        echo '<div class="wrap">';
     306        echo '<h1>' . esc_html__( 'SendPulse Settings', 'sendpulse-email-marketing-newsletter' ) . '</h1>';
     307        settings_errors();
     308
     309        echo '<div id="poststuff">';
     310        echo '<div class="metabox-holder columns-2">';
     311
     312        // Left Column
     313        echo '<div class="postbox-container">';
     314
     315        // Box 1: API Settings
     316        echo '<div class="postbox">';
     317        echo '<button type="button" class="handlediv" aria-expanded="true"><span class="screen-reader-text">Toggle panel: API Settings</span><span class="toggle-indicator" aria-hidden="true"></span></button>';
     318        echo '<h2 class="hndle"><span>' . esc_html__( 'API Settings', 'sendpulse-email-marketing-newsletter' ) . '</span></h2>';
     319        echo '<div class="inside">';
     320        echo '<form method="post" action="options.php">';
     321        settings_fields( 'sp_api_setting' );
     322        echo '<table class="form-table">';
     323        do_settings_fields( $this->page, 'sp_api_setting' );
     324        echo '</table>';
     325        submit_button( __( 'Save API Settings', 'sendpulse-email-marketing-newsletter' ) );
     326        echo '</form>';
     327        echo '</div>';
     328        echo '</div>'; // end .postbox
     329
     330        // Box 2: Import Settings
     331        echo '<div class="postbox">';
     332        echo '<button type="button" class="handlediv" aria-expanded="true"><span class="screen-reader-text">Toggle panel: Import Settings</span><span class="toggle-indicator" aria-hidden="true"></span></button>';
     333        echo '<h2 class="hndle"><span>' . esc_html__( 'Import Settings', 'sendpulse-email-marketing-newsletter' ) . '</span></h2>';
     334        echo '<div class="inside">';
     335        echo '<form method="post" action="options.php">';
     336        settings_fields( 'sp_import_setting' );
     337        echo '<table class="form-table">';
     338        do_settings_fields( $this->page, 'sp_import_setting' );
     339        echo '</table>';
     340        submit_button( __( 'Save Import Settings', 'sendpulse-email-marketing-newsletter' ) );
     341        echo '</form>';
     342        echo '</div>';
     343        echo '</div>'; // end .postbox
     344
     345        echo '</div>'; // end .postbox-container
     346
     347        echo '</div>'; // end .metabox-holder
     348        echo '</div>'; // end #poststuff
     349
     350        echo '</div>'; // end .wrap
     351    }
     352
     353    public function import_page() {
     354        $books = array();
     355        $roles = array();
     356
     357        $import_settings = get_option( 'sp_import_setting', array() );
     358        $saved_book_id = isset( $import_settings['import_to_book'] ) ? $import_settings['import_to_book'] : '';
     359        $saved_role = isset( $import_settings['import_users_group'] ) ? $import_settings['import_users_group'] : '';
     360
     361
     362        try {
     363            $api = new Send_Pulse_Newsletter_API();
     364            $books = $api->get_books(); // Returns list of address books (id + name)
     365        } catch ( Exception $e ) {
     366            $books[] = array(
     367                'id'   => 0,
     368                'name' => __( 'Error fetching books: ', 'sendpulse-email-marketing-newsletter' ) . $e->getMessage()
     369            );
     370        }
     371
     372        // Fetch WP roles
     373        global $wp_roles;
     374        foreach ( $wp_roles->roles as $role_key => $role_data ) {
     375            $roles[] = array(
     376                'value' => $role_key,
     377                'label' => $role_data['name'],
     378            );
     379        }
     380
     381        $nonce = wp_create_nonce( 'sendpulse_import' );
     382        ?>
     383        <div class="wrap">
     384            <h1><?php esc_html_e( 'SendPulse User Import', 'sendpulse-email-marketing-newsletter' ); ?></h1>
     385            <p><?php esc_html_e( 'Import WordPress users into your SendPulse address book.', 'sendpulse-email-marketing-newsletter' ); ?></p>
     386
     387            <div id="sendpulse-dynamic-fields">
     388                <h2><?php esc_html_e( 'Choose Address Book', 'sendpulse-email-marketing-newsletter' ); ?></h2>
     389                <select id="sp-book" class="sp-book-select">
     390                    <?php foreach ( $books as $book ) : ?>
     391                        <option value="<?php echo esc_attr( $book['id'] ); ?>" <?php selected( $saved_book_id, $book['id'] ); ?>>
     392                            <?php echo esc_html( $book['name'] ); ?>
     393                        </option>
     394                    <?php endforeach; ?>
     395                </select>
     396
     397                <h2><?php esc_html_e( 'Choose User Role', 'sendpulse-email-marketing-newsletter' ); ?></h2>
     398                <select id="sp-role" class="sp-role-select">
     399                    <?php foreach ( $roles as $role ) : ?>
     400                        <option value="<?php echo esc_attr( $role['value'] ); ?>" <?php selected( $saved_role, $role['value'] ); ?>>
     401                            <?php echo esc_html( $role['label'] ); ?>
     402                        </option>
     403                    <?php endforeach; ?>
     404                </select>
     405            </div>
     406
     407            <div class="sp-import-controls">
     408                <button id="sp-import" class="button button-primary button-large"
     409                        data-_ajax_nonce="<?php echo esc_attr( $nonce ); ?>"
     410                        data-action="sendpulse_import">
     411                    <?php esc_html_e( 'Start import', 'sendpulse-email-marketing-newsletter' ); ?>
     412                </button>
     413
     414                <textarea rows="10" cols="70" id="sp-import-log" class="sp-import-log" readonly
     415                          title="<?php esc_attr_e( 'Import Log', 'sendpulse-email-marketing-newsletter' ); ?>"></textarea>
     416            </div>
     417
     418
     419        </div>
     420        <?php
     421    }
     422
     423    /**
     424     * Get the value of a settings field
     425     *
     426     * @param string $option settings field name
     427     * @param string $section the section name this field belongs to
     428     * @param string $default default text if it's not found
     429     *
     430     * @return mixed
     431     */
     432
     433    public static function get_option( $option, $section, $default = '' ) {
     434        $options = get_option( $section );
     435
     436        if ( isset( $options[ $option ] ) ) {
     437            return $options[ $option ];
     438        }
     439
     440        return $default;
     441    }
     442
     443
     444    /**
     445     * Get customer address books list
     446     *
     447     * @return array Address books list
     448     */
     449    protected function get_lists_address_book() {
     450        $books = array();
     451
     452        if ( $this->api ) {
     453            $response = $this->api->listAddressBooks();
     454
     455            if ( is_array( $response ) ) {
     456                $books = $response;
     457            } elseif ( is_object( $response ) && empty( get_object_vars( $response ) ) ) {
    254458                $this->error = __( 'You have no books to show', 'sendpulse-email-marketing-newsletter' );
    255459            } else {
    256                 $this->error = __( 'Error API. Please try again later', 'sendpulse-email-marketing-newsletter' );
    257             }
    258         }
    259 
    260         return $books;
    261     }
    262 
    263     public function start_import_controls() { ?>
     460                $this->error = __( 'Error API. Please try again later', 'sendpulse-email-marketing-newsletter' );
     461            }
     462        }
     463
     464        return $books;
     465    }
     466
     467    public function start_import_controls() { ?>
    264468        <div class="sp-import-controls">
    265     <?php }
    266 
    267     public function end_import_controls() {
    268 
    269         echo get_submit_button( __( 'Start import', 'sendpulse-email-marketing-newsletter' ), 'primary large', 'sp-import', true, array(
    270             'data-_ajax_nonce' => wp_create_nonce( 'sendpulse_import' ),
    271             'data-action'      => 'sendpulse_import'
    272         ) ); ?>
     469    <?php }
     470
     471    public function end_import_controls() {
     472        echo wp_kses_post(
     473            get_submit_button(
     474                __( 'Start import', 'sendpulse-email-marketing-newsletter' ),
     475                'primary large',
     476                'sp-import',
     477                true,
     478                array(
     479                    'data-_ajax_nonce' => wp_create_nonce( 'sendpulse_import' ),
     480                    'data-action'      => 'sendpulse_import'
     481                )
     482            )
     483        );
     484        ?>
    273485
    274486        <textarea rows="5" cols="55" class="sp-import-log" id="sp-import-log"
    275                   title="<?php _e( 'Import Log', 'sendpulse-email-marketing-newsletter' ); ?>"></textarea>
     487                  title="<?php esc_attr_e( 'Import Log', 'sendpulse-email-marketing-newsletter' ); ?>"></textarea>
    276488        </div>
    277489
    278     <?php }
     490    <?php }
    279491
    280492}
  • sendpulse-email-marketing-newsletter/trunk/inc/class-sendpulse-newsletter-users.php

    r2791914 r3354585  
    22
    33/**
    4  * Add Wordpress users to address book.
     4 * Add WordPress users to address book.
    55 *
    66 * Class Send_Pulse_Newsletter_Users
     
    1212     */
    1313    public function __construct() {
    14 
    1514        $is_subscribe_after_register = Send_Pulse_Newsletter_Settings::get_option( 'is_subscribe_after_register', 'sp_api_setting' );
    1615
     
    4140     *
    4241     */
    43 
    4442    public static function get_user_ip( $user_id ) {
    4543        return get_user_meta( $user_id, '_sp_user_ip', true );
     
    5250     */
    5351    public function subscribe_after_register( $user_id ) {
    54 
    5552        $user = new WP_User( $user_id );
    56 
    5753        $user_ip = self::get_user_ip( $user_id );
    58 
    5954        $api = new Send_Pulse_Newsletter_API();
    60 
    6155
    6256        $emails = array(
     
    7367        }
    7468
    75         $result = $api->addEmails( $api->default_book, $emails );
     69        $vars = [ 'name' => $user->display_name ];
     70        if ( $user_ip ) {
     71            $vars['subscribe_ip'] = $user_ip;
     72        }
     73
     74        $result = $api->add_contact_to_list(
     75            $user->user_email,
     76            $api->default_book,
     77            $vars
     78        );
    7679
    7780        if ( isset( $result->is_error ) && $result->is_error ) {
    78             $msg = isset( $result->message ) ? $result->message : __( 'Something went wrong', 'sendpulse-email-marketing-newsletter' );
    79 
    80             error_log( 'SendPulse Newsletter: ' . $msg );
     81            $msg = $result->message ?? __( 'Something went wrong', 'sendpulse-email-marketing-newsletter' );
     82            return new WP_Error('sendpulse_error', json_encode($msg));
    8183        }
    8284    }
     
    8890     *
    8991     */
    90 
    9192    public static function define_user_ip() {
    92         $client  = @$_SERVER['HTTP_CLIENT_IP'];
    93         $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    94         $remote  = $_SERVER['REMOTE_ADDR'];
     93        $client  = isset($_SERVER['HTTP_CLIENT_IP']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ) : '';
     94        $forward = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) : '';
     95        $remote  = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
    9596
    9697        if ( filter_var( $client, FILTER_VALIDATE_IP ) ) {
     
    105106    }
    106107
    107 
    108108}
    109109
  • sendpulse-email-marketing-newsletter/trunk/inc/class-senpulse-newsletter-forms.php

    r3232169 r3354585  
    22
    33/**
    4  *
    5  *
    64 * Class Send_Pulse_Newsletter_Forms
    75 */
    86class Send_Pulse_Newsletter_Forms {
    9 
    107    private $post_type = 'sendpulse_form';
    11 
    128    public function __construct() {
    13 
    14 
    159        add_action( 'init', array( $this, 'register_forms_post' ) );
    16 
    17 
    1810        add_action( 'add_meta_boxes_sendpulse_form', array( $this, 'meta_box' ) );
    19 
    2011        add_action( 'save_post', array( $this, 'save_meta' ) );
    21 
    2212        add_filter( "manage_{$this->post_type}_posts_columns", array( $this, 'get_columns' ) );
    2313        add_action( "manage_{$this->post_type}_posts_custom_column", array( $this, 'render_column' ), 10, 2 );
    24 
    2514        add_filter( 'post_updated_messages', array( $this, 'change_form_updated_messages' ) );
    2615        add_filter( 'post_date_column_status', array( $this, 'change_date_column_status' ), 10, 2 );
    27 
    28 
    2916    }
    3017
     
    7663
    7764        $this->remove_built_in_metaboxes();
    78 
    79 
    8065    }
    8166
    8267    public function code_metabox_output( $post ) {
    8368        $code = get_post_meta( $post->ID, '_sp_form_code', true );
     69        wp_nonce_field( 'sp_form_code_save', 'sp_form_code_nonce' );
    8470        ?>
    8571        <textarea rows="20" cols="40" name="sp_form_code" id="sp_form_code"
    86                   placeholder="<?php _e( 'Paste code here', 'sendpulse-email-marketing-newsletter' ); ?>"><?php echo htmlspecialchars($code); ?></textarea>
    87         <p><?php echo sprintf( __( 'Code from <a href="%s">Constructor Form</a> (<a class="%s" href="%s" title="Open help page in new tab" target="_blank">Need help?</a>)', 'sendpulse-email-marketing-newsletter' ),
     72                  placeholder="<?php esc_attr_e( 'Paste code here', 'sendpulse-email-marketing-newsletter' ); ?>"><?php echo esc_textarea( $code ); ?></textarea>
     73        <p>
     74            <?php
     75            // translators: 1: URL to the Constructor Form, 2: CSS class name for the help link, 3: URL to the help article
     76            $translated_string = __( 'Code from <a href="%1$s">Constructor Form</a> (<a class="%2$s" href="%3$s" title="Open help page in new tab" target="_blank">Need help?</a>)', 'sendpulse-email-marketing-newsletter' );
     77            echo wp_kses_post( sprintf(
     78                $translated_string,
    8879                'https://login.sendpulse.com/emailservice/forms/constructor/',
    8980                'h-help',
    90                 'https://sendpulse.com/ru/blog/subscription-forms?utm_campaign=novinki-za-sentiabr&utm_source=sendpulse&utm_medium=email' ); ?></p>
     81                'https://sendpulse.com/ru/blog/subscription-forms?utm_campaign=novinki-za-sentiabr&utm_source=sendpulse&utm_medium=email'
     82            ) );
     83            ?>
     84        </p>
    9185        <?php
    9286    }
    9387
    9488    public function save_meta( $post_id ) {
    95         if ( array_key_exists( 'sp_form_code', $_POST ) ) {
    96             update_post_meta(
    97                 $post_id,
    98                 '_sp_form_code',
    99                 $_POST['sp_form_code']
    100             );
     89        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     90        $nonce = isset( $_POST['sp_form_code_nonce'] ) ? wp_unslash( $_POST['sp_form_code_nonce'] ) : '';
     91
     92        if ( ! wp_verify_nonce( $nonce, 'sp_form_code_save' ) ) {
     93            return;
     94        }
     95
     96        // Bail early on autosave
     97        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
     98            return;
     99        }
     100
     101        // Capability check
     102        if ( ! current_user_can( 'edit_post', $post_id ) ) {
     103            return;
     104        }
     105
     106        if ( isset( $_POST['sp_form_code'] ) ) {
     107            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     108            $raw_code = wp_unslash( $_POST['sp_form_code'] );
     109            update_post_meta( $post_id, '_sp_form_code', $raw_code );
    101110        }
    102111    }
    103112
    104113    public function shortcode_metabox_output( $post ) {
    105         $this->shortcode_text( $post->ID );
    106         $desc = __( 'You should paste this shortcode in themes files', 'sendpulse-email-marketing-newsletter' );
    107         ?>
    108 
    109         <p><?php echo $desc; ?></p>
    110         <?php
    111 
    112         $this->post_submit_meta_box( $post );
    113 
     114        $this->shortcode_text( $post->ID );?>
     115        <p><?php echo esc_html__( 'You should paste this shortcode in your page/post/widget', 'sendpulse-email-marketing-newsletter' ); ?></p>
     116        <?php $this->post_submit_meta_box( $post );
    114117    }
    115118
    116119    public function remove_built_in_metaboxes() {
    117 
    118         remove_meta_box( 'submitdiv', null, 'side' );
    119 
    120     }
    121 
    122     public function post_submit_meta_box( $post ) {
    123         ?>
    124 
     120        remove_meta_box( 'submitdiv', 'sendpulse_form', 'side' );
     121    }
     122
     123    public function post_submit_meta_box( $post ) { ?>
    125124        <div class="submitbox" id="submitpost">
    126125            <div style="display:none;">
    127                 <?php submit_button( __( 'Save' ), '', 'save' ); ?>
     126                <?php submit_button( __( 'Save', 'sendpulse-email-marketing-newsletter' ), '', 'save' ); ?>
    128127            </div>
    129128            <div id="major-publishing-actions">
    130129                <div id="delete-action">
    131130                    <?php
    132                     if ( current_user_can( "delete_post", $post->ID ) ) {
     131                    if ( current_user_can( 'delete_post', $post->ID ) ) {
    133132                        if ( ! EMPTY_TRASH_DAYS ) {
    134                             $delete_text = __( 'Delete Permanently' );
     133                            $delete_text = __( 'Delete Permanently', 'sendpulse-email-marketing-newsletter' );
    135134                        } else {
    136                             $delete_text = __( 'Move to Trash' );
     135                            $delete_text = __( 'Move to Trash', 'sendpulse-email-marketing-newsletter' );
    137136                        }
    138137                        ?>
    139138                        <a class="submitdelete deletion"
    140                            href="<?php echo get_delete_post_link( $post->ID ); ?>"><?php echo $delete_text; ?></a><?php
    141                     } ?>
     139                           href="<?php echo esc_url( get_delete_post_link( $post->ID ) ); ?>">
     140                            <?php echo esc_html( $delete_text ); ?>
     141                        </a>
     142                        <?php
     143                    }
     144                    ?>
    142145                </div>
    143146                <div id="publishing-action">
    144147                    <span class="spinner"></span>
    145148                    <input name="original_publish" type="hidden" id="original_publish"
    146                            value="<?php esc_attr_e( 'Save' ) ?>"/>
    147                     <?php submit_button( __( 'Save' ), 'primary large', 'publish', false ); ?>
     149                           value="<?php esc_attr_e( 'Save', 'sendpulse-email-marketing-newsletter' ); ?>" />
     150                    <?php submit_button( __( 'Save', 'sendpulse-email-marketing-newsletter' ), 'primary large', 'publish', false ); ?>
    148151                </div>
    149152                <div class="clear"></div>
    150153            </div>
    151 
    152154        </div>
    153 
    154     <?php }
     155        <?php
     156    }
    155157
    156158    public function get_columns( $columns ) {
    157 
    158159        $first_array = array_splice( $columns, 0, 2 );
    159160        $columns     = array_merge( $first_array, array( 'sp_shortcode' => __( 'Shortcode', 'sendpulse-email-marketing-newsletter' ) ), $columns );
    160 
    161 
    162161        return $columns;
    163 
    164162    }
    165163
    166164    public function render_column( $column_name, $post_id ) {
    167 
    168165        if ( 'sp_shortcode' == $column_name ) {
    169166            $this->shortcode_text( $post_id );
     
    174171    protected function shortcode_text( $post_id ) {
    175172        $shortcode = sprintf( '[sendpulse-form id="%s"]', esc_attr( $post_id ) );
    176         $desc      = __( 'You should paste this shortcode in themes files', 'sendpulse-email-marketing-newsletter' ); ?>
    177 
    178         <input type="text" value="<?php echo esc_attr( $shortcode ); ?>" title="<?php echo $desc; ?>"
     173        $desc      = __( 'You should paste this shortcode in your page/post/widget', 'sendpulse-email-marketing-newsletter' ); ?>
     174
     175        <input type="text" value="<?php echo esc_attr( $shortcode ); ?>" title="<?php echo esc_attr( $desc ); ?>"
    179176               readonly="readonly">
    180177        <?php
     
    208205    }
    209206
    210 
    211207}
    212208
  • sendpulse-email-marketing-newsletter/trunk/inc/class-senpulse-newsletter-loader.php

    r2933319 r3354585  
    1919
    2020    /**
    21      * @var string Plugin relative patch.
     21     * Send_Pulse_Newsletter constructor.
     22     *
     23     * @param string $plugin_url
    2224     *
    2325     */
    24 
    25     private $plugin_rel_patch;
    26 
    27 
    28     /**
    29      * Send_Pulse_Newsletter constructor.
    30      *
    31      * @var $plugin_url string
    32      * @var $plugin_rel_patch string
    33      *
    34      */
    35     public function __construct( $plugin_url, $plugin_rel_patch ) {
     26    public function __construct( $plugin_url ) {
    3627        $this->plugin_url = $plugin_url;
    37         $this->plugin_rel_patch = $plugin_rel_patch;
    38         add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
    3928        $this->inc();
    4029        add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
     
    4635    protected function inc() {
    4736        $vendor_dir = dirname( __FILE__ ) . '/../vendor/';
    48         include_once( $vendor_dir . 'tareq1988/wordpress-settings-api-class/src/class.settings-api.php' );
    49         include_once( $vendor_dir . 'sendpulse/sendpulse-rest-api-php/api/Storage/TokenStorageInterface.php' );
    50         include_once( $vendor_dir . 'sendpulse/sendpulse-rest-api-php/api/Storage/FileStorage.php' );
    51         include_once( $vendor_dir . 'sendpulse/sendpulse-rest-api-php/api/Storage/SessionStorage.php' );
    52         include_once( $vendor_dir . 'sendpulse/sendpulse-rest-api-php/api/sendpulseInterface.php' );
    53         include_once( $vendor_dir . 'sendpulse/sendpulse-rest-api-php/api/sendpulse.php' );
     37        include_once( $vendor_dir . 'sendpulse/rest-api/src/Contracts/TokenStorageInterface.php' );
     38        include_once( $vendor_dir . 'sendpulse/rest-api/src/Contracts/ApiInterface.php' );
     39        include_once( $vendor_dir . 'sendpulse/rest-api/src/Storage/FileStorage.php' );
     40        include_once( $vendor_dir . 'sendpulse/rest-api/src/Storage/SessionStorage.php' );
     41        include_once( $vendor_dir . 'sendpulse/rest-api/src/ApiClient.php' );
     42        include_once( $vendor_dir . 'sendpulse/rest-api/src/ApiClientException.php' );
    5443        include_once( 'class-senpulse-newsletter-forms.php' );
    5544        include_once( 'class-sendpulse-newsletter-api.php' );
     
    6049    }
    6150
     51    public function admin_assets() {
     52        wp_enqueue_style( 'sp-admin-style', $this->plugin_url . "assets/css/sp-newsletter-admin.css", array(), $this->version );
     53        wp_enqueue_script( 'sp-admin-dismiss-script', $this->plugin_url . "assets/js/sp-newsletter-admin-dismiss-script.js", array( 'jquery' ), $this->version, true );
     54        wp_enqueue_script( 'sp-admin-importer-script', $this->plugin_url . "assets/js/sp-newsletter-admin-importer.js", array( 'jquery' ), $this->version, true );
    6255
    63     public function admin_assets() {
    64         $prefix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
    65         wp_enqueue_style( 'sp-admin-style', $this->plugin_url . "assets/css/admin{$prefix}.css", array(), $this->version );
    66         wp_enqueue_script( 'sp-admin-script', $this->plugin_url . "assets/js/admin{$prefix}.js", array( 'jquery' ), $this->version, true );
    67         $data = array(
    68             'ajax_url' => admin_url( 'admin-ajax.php' )
    69         );
    70 
    71         wp_localize_script( 'sp-admin-script', 'sp_admin_params', $data );
    72     }
    73 
    74     function load_textdomain() {
    75         load_plugin_textdomain( 'sendpulse-email-marketing-newsletter', false, $this->plugin_rel_patch );
     56        wp_localize_script( 'sp-admin-importer-script', 'sp_admin_params', [
     57            'ajax_url' => admin_url( 'admin-ajax.php' ),
     58            '_ajax_nonce' => wp_create_nonce( 'sendpulse_import' )
     59        ] );
    7660    }
    7761   
  • sendpulse-email-marketing-newsletter/trunk/inc/class-senpulse-newsletter-requirement.php

    r2938759 r3354585  
    4141    }
    4242
    43     public function is_folder_writable($folder_path) {
    44         $writable = false;
     43    public function is_folder_writable( $folder_path ) {
     44        global $wp_filesystem;
    4545
    46         // Check if the folder exists
    47         if (file_exists($folder_path)) {
    48             // Check if the folder is writable
    49             if (is_writable($folder_path)) {
    50                 $writable = true;
    51             }
     46        // Initialize WP Filesystem
     47        if ( empty( $wp_filesystem ) ) {
     48            require_once ABSPATH . '/wp-admin/includes/file.php';
     49            WP_Filesystem();
    5250        }
    5351
    54         return $writable;
     52        // Check if the folder exists and is writable using WP_Filesystem
     53        if ( $wp_filesystem->is_dir( $folder_path ) && $wp_filesystem->is_writable( $folder_path ) ) {
     54            return true;
     55        }
     56
     57        return false;
    5558    }
    5659
  • sendpulse-email-marketing-newsletter/trunk/inc/class-senpulse-newsletter-shortcodes.php

    r3289328 r3354585  
    5555        }
    5656
    57         $host = parse_url($src, PHP_URL_HOST);
    58         if (!$host || !in_array(strtolower($host), array_map('strtolower', $allowed_hosts), true)) {
    59             return false;
    60         }
     57        $parts = wp_parse_url( $src );
     58        $host = $parts['host'] ?? '';
     59        if ( ! $host || ! in_array( strtolower( $host ), array_map( 'strtolower', $allowed_hosts ), true ) ) {
     60            return false;
     61        }
    6162
    6263        $allowed_attrs = ['src', 'async', 'sp-form-id', 'type'];
  • sendpulse-email-marketing-newsletter/trunk/readme.txt

    r3327368 r3354585  
    11=== SendPulse Email Marketing Newsletter ===
    22Contributors: SendPulse
    3 Tags: newsletter subscription form, email subscription form, newsletter email optin, email newsletter signup form, email marketing
    4 Requires PHP: 5.6
     3Tags: email marketing, newsletter, subscription form, email optin, autoresponder
     4Requires PHP: 7.2
    55Requires at least: 5.7
    66Tested up to: 6.8
    7 Stable tag: 2.2.0
     7Stable tag: 2.2.1
    88License: GPLv2 or later
    9 License URI: http://www.gnu.org/licenses/gpl-2.0.html
     9License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1010
    11 Add e-mail subscription form, send marketing newsletters and create autoresponders.
     11Add a customizable email subscription form to your site, send newsletters, and automate email campaigns with autoresponders using SendPulse.
    1212
    1313== Description ==
     
    1515SendPulse plugin for WordPress
    1616Add an email subscription form to your site. Each new subscriber will be automatically added to your mailing list. Create and send email campaigns with SendPulse, a multi-channel marketing automation platform.
    17 
    1817
    1918= FEATURES =
     
    5453
    5554= Requirement =
    56 * PHP version >= 5.6+ ([Recommended](https://wordpress.org/about/requirements/) >= 5.6+)
    57 
     55* PHP version >= 7.2+ ([Recommended](https://wordpress.org/about/requirements/) >= 7.2+)
    5856
    5957== Installation ==
     
    6967For example, `<?php echo do_shortcode('[sendpulse-form id="..."]')?>`.
    7068
    71 
    7269== Screenshots ==
    7370
     
    76733. API setting.
    77744. Import Wordpress user.
    78 
    79 == Changelog ==
    80 
    81 = 1.5.0 - 2017-08-22 =
    82 * Changed: Ability to use the constructor code from SendPulse dashboard.
    83 * Fixed: Support several forms on the page.
    84 
    85 = 2.0.0 - 2017-09-19 =
    86 * Added: Ability create multiple form with constructor code from SendPulse dashboard.
    87 * Removed: Plugin generated subscribe form in favor constructor code from SendPulse dashboard.
    88 
    89 = 2.0.1 - 2017-09-25 =
    90 * Changed: Documentation and help link.
    91 
    92 = 2.1.0 - 2017-10-18 =
    93 * Changed: Down minimal PHP version requirement.
    94 
    95 = 2.1.1 - 2022-07-16 =
    96 * Updated supported WP versions
    97 * Tested up to Wordpress 6.0.2
    98 * Updated translations
    99 * Various fixes
    100 
    101 = 2.1.3 - 2023-06-05 =
    102 * Updated supported WP versions
    103 * Tested up to Wordpress 6.2.2
    104 * On plugin activation automatic
    105 
    106 = 2.1.4 - 2023-07-14 =
    107 * Change info messages on plugin activation
    108 * Change message box classes
    109 * Change function to check write available on server
    110 
    111 = 2.1.5 - 2024-05-28 =
    112 * Update strings
    113 
    114 = 2.1.6 - 2025-01-30 =
    115 * Fix XSS
    116 
    117 = 2.1.7 - 2025-04-28 =
    118 * Fix XSS
    119 
    120 = 2.1.8 - 2025-05-07 =
    121 * Prevent DOMDocument error on empty input. Thanks to khizhnik
    122 
    123 = 2.1.9 - 2025-06-04 =
    124 * Added error message "You have no books to show" if your account has no available books instead of global message "Error API. Please try again later" for such case.
    125 
    126 = 2.2.0 - 2025-07-14 =
    127 * Fix vendor library crashing on PHP8.3
    128 
    129 == Upgrade Notice ==
    130 In version 2.0.0 of SendPulse Email Marketing Newsletter removed plugin generated subscribe form in favor constructor code from SendPulse dashboard.
    131 Its breaking change! Please use link https://login.sendpulse.com/emailservice/forms/constructor/ to generate new forms.
  • sendpulse-email-marketing-newsletter/trunk/sendpulse-newsletter.php

    r3327368 r3354585  
    44    Plugin URI: https://wordpress.org/plugins/sendpulse-email-marketing-newsletter/
    55    Description: Add e-mail subscription form, send marketing newsletters and create autoresponders.
    6     Version: 2.2.0
     6    Version: 2.2.1
    77    Author: SendPulse
    88    Author URI: https://sendpulse.com
     
    1010    License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1111    Text Domain: sendpulse-email-marketing-newsletter
    12     Domain Path: languages
     12    Domain Path: /languages
    1313 */
    1414
     
    1717}
    1818
    19 const SP_EMAIL_MARKETING_VERSION = '2.2.0';
     19if ( version_compare( PHP_VERSION, '7.2.0', '<' ) ) {
     20    if ( is_admin() ) {
     21        require_once ABSPATH . 'wp-admin/includes/plugin.php';
     22        deactivate_plugins( plugin_basename( __FILE__ ) );
     23        wp_die(
     24            esc_html__( 'The "SendPulse Email Marketing Newsletter" plugin requires PHP version 7.2.0 or higher. Please upgrade your PHP version.', 'sendpulse-email-marketing-newsletter' ),
     25            esc_html__( 'Plugin Incompatible', 'sendpulse-email-marketing-newsletter' ),
     26            array( 'back_link' => true )
     27        );
     28    } else {
     29        exit;
     30    }
     31}
     32
     33require_once __DIR__ . '/vendor/autoload.php';
     34
     35const SP_EMAIL_MARKETING_VERSION = '2.2.1';
    2036define('SP_EMAIL_MARKETING_PLUGIN_BASE_NAME', plugin_basename(__FILE__));
    2137define('SP_EMAIL_MARKETING_PLUGIN_BASE_DIR', plugin_dir_path(__FILE__));
     
    2743
    2844// Deactivate plugin if critical error
    29 function deactivate_plugin_by_slug($plugin_slug) {
    30     global $wpdb;
     45function deactivate_plugin_by_slug( $plugin_slug ) {
     46    $plugins = get_option( 'active_plugins', array() );
    3147
    32     $plugin = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->options WHERE option_name = %s", 'active_plugins'));
    33 
    34     if ($plugin && isset($plugin->option_value)) {
    35         $plugins = maybe_unserialize($plugin->option_value);
    36         if (is_array($plugins)) {
    37             $key = array_search($plugin_slug, $plugins);
    38             if ($key !== false) {
    39                 unset($plugins[$key]);
    40                 $wpdb->query($wpdb->prepare("UPDATE $wpdb->options SET option_value = %s WHERE option_name = %s", serialize($plugins), 'active_plugins'));
    41             }
     48    if ( is_array( $plugins ) ) {
     49        $key = array_search( $plugin_slug, $plugins );
     50        if ( $key !== false ) {
     51            unset( $plugins[ $key ] );
     52            update_option( 'active_plugins', $plugins );
    4253        }
    4354    }
     
    4859// Create session folder if not exist
    4960function sp_emp_plugin_activation() {
     61    global $wp_filesystem;
    5062
    51     if (!is_dir(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR)) {
    52         mkdir(SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR, 0775);
     63    // Load the WP Filesystem
     64    require_once ABSPATH . 'wp-admin/includes/file.php';
     65
     66    if ( ! WP_Filesystem() ) {
     67        return; // Could not initialize filesystem
     68    }
     69
     70    if ( ! $wp_filesystem->is_dir( SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR ) ) {
     71        $wp_filesystem->mkdir( SP_EMAIL_MARKETING_PLUGIN_STORAGE_DIR, FS_CHMOD_DIR );
    5372    }
    5473}
     74
    5575
    5676// Remove dissmised options from wp_options on plugin deactivation
     
    7898add_action('wp_ajax_dismiss_sp_emp_session_storage_notice', 'sp_emp_dismiss_session_storage_notice');
    7999
    80 // Enqueue JavaScript for dismiss button
    81 function sp_emp_enqueue_dismiss_script() {
    82     wp_enqueue_script('sp-emp-dismiss-script', plugin_dir_url(__FILE__) . 'assets/js/dismiss-script.js', array('jquery'), '1.0', true);
    83 
    84     // Localize the script with the AJAX URL
    85     wp_localize_script('sp-emp-dismiss-script', 'sp_emp_dismiss_script_vars', array(
    86         'ajaxurl' => admin_url('admin-ajax.php'),
    87     ));
    88 }
    89 
    90 add_action('admin_enqueue_scripts', 'sp_emp_enqueue_dismiss_script');
    91 
    92 
    93100if ($requirement->is_success() ) {
    94101    include_once('inc/class-senpulse-newsletter-loader.php');
    95102
    96103    new Send_Pulse_Newsletter_Loader(
    97         plugins_url('/', __FILE__),
    98         basename(dirname(__FILE__)) . '/languages/'
     104        plugins_url('/', __FILE__)
    99105    );
    100106} else {
  • sendpulse-email-marketing-newsletter/trunk/vendor/autoload.php

    r2791914 r3354585  
    44
    55if (PHP_VERSION_ID < 50600) {
    6     echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
    7     exit(1);
     6    if (!headers_sent()) {
     7        header('HTTP/1.1 500 Internal Server Error');
     8    }
     9    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
     10    if (!ini_get('display_errors')) {
     11        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
     12            fwrite(STDERR, $err);
     13        } elseif (!headers_sent()) {
     14            echo $err;
     15        }
     16    }
     17    trigger_error(
     18        $err,
     19        E_USER_ERROR
     20    );
    821}
    922
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/ClassLoader.php

    r2791914 r3354585  
    4343class ClassLoader
    4444{
    45     /** @var ?string */
     45    /** @var \Closure(string):void */
     46    private static $includeFile;
     47
     48    /** @var string|null */
    4649    private $vendorDir;
    4750
    4851    // PSR-4
    4952    /**
    50      * @var array[]
    51      * @psalm-var array<string, array<string, int>>
     53     * @var array<string, array<string, int>>
    5254     */
    5355    private $prefixLengthsPsr4 = array();
    5456    /**
    55      * @var array[]
    56      * @psalm-var array<string, array<int, string>>
     57     * @var array<string, list<string>>
    5758     */
    5859    private $prefixDirsPsr4 = array();
    5960    /**
    60      * @var array[]
    61      * @psalm-var array<string, string>
     61     * @var list<string>
    6262     */
    6363    private $fallbackDirsPsr4 = array();
     
    6565    // PSR-0
    6666    /**
    67      * @var array[]
    68      * @psalm-var array<string, array<string, string[]>>
     67     * List of PSR-0 prefixes
     68     *
     69     * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
     70     *
     71     * @var array<string, array<string, list<string>>>
    6972     */
    7073    private $prefixesPsr0 = array();
    7174    /**
    72      * @var array[]
    73      * @psalm-var array<string, string>
     75     * @var list<string>
    7476     */
    7577    private $fallbackDirsPsr0 = array();
     
    7981
    8082    /**
    81      * @var string[]
    82      * @psalm-var array<string, string>
     83     * @var array<string, string>
    8384     */
    8485    private $classMap = array();
     
    8889
    8990    /**
    90      * @var bool[]
    91      * @psalm-var array<string, bool>
     91     * @var array<string, bool>
    9292     */
    9393    private $missingClasses = array();
    9494
    95     /** @var ?string */
     95    /** @var string|null */
    9696    private $apcuPrefix;
    9797
    9898    /**
    99      * @var self[]
     99     * @var array<string, self>
    100100     */
    101101    private static $registeredLoaders = array();
    102102
    103103    /**
    104      * @param ?string $vendorDir
     104     * @param string|null $vendorDir
    105105     */
    106106    public function __construct($vendorDir = null)
    107107    {
    108108        $this->vendorDir = $vendorDir;
    109     }
    110 
    111     /**
    112      * @return string[]
     109        self::initializeIncludeClosure();
     110    }
     111
     112    /**
     113     * @return array<string, list<string>>
    113114     */
    114115    public function getPrefixes()
     
    122123
    123124    /**
    124      * @return array[]
    125      * @psalm-return array<string, array<int, string>>
     125     * @return array<string, list<string>>
    126126     */
    127127    public function getPrefixesPsr4()
     
    131131
    132132    /**
    133      * @return array[]
    134      * @psalm-return array<string, string>
     133     * @return list<string>
    135134     */
    136135    public function getFallbackDirs()
     
    140139
    141140    /**
    142      * @return array[]
    143      * @psalm-return array<string, string>
     141     * @return list<string>
    144142     */
    145143    public function getFallbackDirsPsr4()
     
    149147
    150148    /**
    151      * @return string[] Array of classname => path
    152      * @psalm-return array<string, string>
     149     * @return array<string, string> Array of classname => path
    153150     */
    154151    public function getClassMap()
     
    158155
    159156    /**
    160      * @param string[] $classMap Class to filename map
    161      * @psalm-param array<string, string> $classMap
     157     * @param array<string, string> $classMap Class to filename map
    162158     *
    163159     * @return void
     
    176172     * appending or prepending to the ones previously set for this prefix.
    177173     *
    178      * @param string          $prefix  The prefix
    179      * @param string[]|string $paths   The PSR-0 root directories
    180      * @param bool            $prepend Whether to prepend the directories
     174     * @param string              $prefix  The prefix
     175     * @param list<string>|string $paths   The PSR-0 root directories
     176     * @param bool                $prepend Whether to prepend the directories
    181177     *
    182178     * @return void
     
    184180    public function add($prefix, $paths, $prepend = false)
    185181    {
     182        $paths = (array) $paths;
    186183        if (!$prefix) {
    187184            if ($prepend) {
    188185                $this->fallbackDirsPsr0 = array_merge(
    189                     (array) $paths,
     186                    $paths,
    190187                    $this->fallbackDirsPsr0
    191188                );
     
    193190                $this->fallbackDirsPsr0 = array_merge(
    194191                    $this->fallbackDirsPsr0,
    195                     (array) $paths
     192                    $paths
    196193                );
    197194            }
     
    202199        $first = $prefix[0];
    203200        if (!isset($this->prefixesPsr0[$first][$prefix])) {
    204             $this->prefixesPsr0[$first][$prefix] = (array) $paths;
     201            $this->prefixesPsr0[$first][$prefix] = $paths;
    205202
    206203            return;
     
    208205        if ($prepend) {
    209206            $this->prefixesPsr0[$first][$prefix] = array_merge(
    210                 (array) $paths,
     207                $paths,
    211208                $this->prefixesPsr0[$first][$prefix]
    212209            );
     
    214211            $this->prefixesPsr0[$first][$prefix] = array_merge(
    215212                $this->prefixesPsr0[$first][$prefix],
    216                 (array) $paths
     213                $paths
    217214            );
    218215        }
     
    223220     * appending or prepending to the ones previously set for this namespace.
    224221     *
    225      * @param string          $prefix  The prefix/namespace, with trailing '\\'
    226      * @param string[]|string $paths   The PSR-4 base directories
    227      * @param bool            $prepend Whether to prepend the directories
     222     * @param string              $prefix  The prefix/namespace, with trailing '\\'
     223     * @param list<string>|string $paths   The PSR-4 base directories
     224     * @param bool                $prepend Whether to prepend the directories
    228225     *
    229226     * @throws \InvalidArgumentException
     
    233230    public function addPsr4($prefix, $paths, $prepend = false)
    234231    {
     232        $paths = (array) $paths;
    235233        if (!$prefix) {
    236234            // Register directories for the root namespace.
    237235            if ($prepend) {
    238236                $this->fallbackDirsPsr4 = array_merge(
    239                     (array) $paths,
     237                    $paths,
    240238                    $this->fallbackDirsPsr4
    241239                );
     
    243241                $this->fallbackDirsPsr4 = array_merge(
    244242                    $this->fallbackDirsPsr4,
    245                     (array) $paths
     243                    $paths
    246244                );
    247245            }
     
    253251            }
    254252            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
    255             $this->prefixDirsPsr4[$prefix] = (array) $paths;
     253            $this->prefixDirsPsr4[$prefix] = $paths;
    256254        } elseif ($prepend) {
    257255            // Prepend directories for an already registered namespace.
    258256            $this->prefixDirsPsr4[$prefix] = array_merge(
    259                 (array) $paths,
     257                $paths,
    260258                $this->prefixDirsPsr4[$prefix]
    261259            );
     
    264262            $this->prefixDirsPsr4[$prefix] = array_merge(
    265263                $this->prefixDirsPsr4[$prefix],
    266                 (array) $paths
     264                $paths
    267265            );
    268266        }
     
    273271     * replacing any others previously set for this prefix.
    274272     *
    275      * @param string          $prefix The prefix
    276      * @param string[]|string $paths  The PSR-0 base directories
     273     * @param string              $prefix The prefix
     274     * @param list<string>|string $paths  The PSR-0 base directories
    277275     *
    278276     * @return void
     
    291289     * replacing any others previously set for this namespace.
    292290     *
    293      * @param string          $prefix The prefix/namespace, with trailing '\\'
    294      * @param string[]|string $paths  The PSR-4 base directories
     291     * @param string              $prefix The prefix/namespace, with trailing '\\'
     292     * @param list<string>|string $paths  The PSR-4 base directories
    295293     *
    296294     * @throws \InvalidArgumentException
     
    426424    {
    427425        if ($file = $this->findFile($class)) {
    428             includeFile($file);
     426            $includeFile = self::$includeFile;
     427            $includeFile($file);
    429428
    430429            return true;
     
    477476
    478477    /**
    479      * Returns the currently registered loaders indexed by their corresponding vendor directories.
    480      *
    481      * @return self[]
     478     * Returns the currently registered loaders keyed by their corresponding vendor directories.
     479     *
     480     * @return array<string, self>
    482481     */
    483482    public static function getRegisteredLoaders()
     
    556555        return false;
    557556    }
     557
     558    /**
     559     * @return void
     560     */
     561    private static function initializeIncludeClosure()
     562    {
     563        if (self::$includeFile !== null) {
     564            return;
     565        }
     566
     567        /**
     568         * Scope isolated include.
     569         *
     570         * Prevents access to $this/self from included files.
     571         *
     572         * @param  string $file
     573         * @return void
     574         */
     575        self::$includeFile = \Closure::bind(static function($file) {
     576            include $file;
     577        }, null, null);
     578    }
    558579}
    559 
    560 /**
    561  * Scope isolated include.
    562  *
    563  * Prevents access to $this/self from included files.
    564  *
    565  * @param  string $file
    566  * @return void
    567  * @private
    568  */
    569 function includeFile($file)
    570 {
    571     include $file;
    572 }
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/InstalledVersions.php

    r2791914 r3354585  
    9999        foreach (self::getInstalled() as $installed) {
    100100            if (isset($installed['versions'][$packageName])) {
    101                 return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
     101                return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
    102102            }
    103103        }
     
    120120    public static function satisfies(VersionParser $parser, $packageName, $constraint)
    121121    {
    122         $constraint = $parser->parseConstraints($constraint);
     122        $constraint = $parser->parseConstraints((string) $constraint);
    123123        $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
    124124
     
    329329                    $installed[] = self::$installedByVendor[$vendorDir];
    330330                } elseif (is_file($vendorDir.'/composer/installed.php')) {
    331                     $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
     331                    /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
     332                    $required = require $vendorDir.'/composer/installed.php';
     333                    $installed[] = self::$installedByVendor[$vendorDir] = $required;
    332334                    if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
    333335                        self::$installed = $installed[count($installed) - 1];
     
    341343            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
    342344            if (substr(__DIR__, -8, 1) !== 'C') {
    343                 self::$installed = require __DIR__ . '/installed.php';
     345                /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
     346                $required = require __DIR__ . '/installed.php';
     347                self::$installed = $required;
    344348            } else {
    345349                self::$installed = array();
    346350            }
    347351        }
    348         $installed[] = self::$installed;
     352
     353        if (self::$installed !== array()) {
     354            $installed[] = self::$installed;
     355        }
    349356
    350357        return $installed;
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/autoload_classmap.php

    r2791914 r3354585  
    88return array(
    99    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    10     'FileStorage' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/Storage/FileStorage.php',
    11     'MemcacheStorage' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/Storage/MemcacheStorage.php',
    12     'MemcachedStorage' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/Storage/MemcachedStorage.php',
    13     'SendpulseApi' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/sendpulse.php',
    14     'SendpulseApi_Interface' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/sendpulseInterface.php',
    15     'SessionStorage' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/Storage/SessionStorage.php',
    16     'TokenStorageInterface' => $vendorDir . '/sendpulse/sendpulse-rest-api-php/api/Storage/TokenStorageInterface.php',
    17     'WeDevs_Settings_API' => $vendorDir . '/tareq1988/wordpress-settings-api-class/src/class.settings-api.php',
    1810);
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/autoload_psr4.php

    r2791914 r3354585  
    77
    88return array(
     9    'Sendpulse\\RestApi\\' => array($vendorDir . '/sendpulse/rest-api/src'),
    910);
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/autoload_static.php

    r2791914 r3354585  
    77class ComposerStaticInite1798030ff62ec93eeab468f970388ff
    88{
     9    public static $prefixLengthsPsr4 = array (
     10        'S' =>
     11        array (
     12            'Sendpulse\\RestApi\\' => 18,
     13        ),
     14    );
     15
     16    public static $prefixDirsPsr4 = array (
     17        'Sendpulse\\RestApi\\' =>
     18        array (
     19            0 => __DIR__ . '/..' . '/sendpulse/rest-api/src',
     20        ),
     21    );
     22
    923    public static $classMap = array (
    1024        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
    11         'FileStorage' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/Storage/FileStorage.php',
    12         'MemcacheStorage' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/Storage/MemcacheStorage.php',
    13         'MemcachedStorage' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/Storage/MemcachedStorage.php',
    14         'SendpulseApi' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/sendpulse.php',
    15         'SendpulseApi_Interface' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/sendpulseInterface.php',
    16         'SessionStorage' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/Storage/SessionStorage.php',
    17         'TokenStorageInterface' => __DIR__ . '/..' . '/sendpulse/sendpulse-rest-api-php/api/Storage/TokenStorageInterface.php',
    18         'WeDevs_Settings_API' => __DIR__ . '/..' . '/tareq1988/wordpress-settings-api-class/src/class.settings-api.php',
    1925    );
    2026
     
    2228    {
    2329        return \Closure::bind(function () use ($loader) {
     30            $loader->prefixLengthsPsr4 = ComposerStaticInite1798030ff62ec93eeab468f970388ff::$prefixLengthsPsr4;
     31            $loader->prefixDirsPsr4 = ComposerStaticInite1798030ff62ec93eeab468f970388ff::$prefixDirsPsr4;
    2432            $loader->classMap = ComposerStaticInite1798030ff62ec93eeab468f970388ff::$classMap;
    2533
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/installed.json

    r2933319 r3354585  
    22    "packages": [
    33        {
    4             "name": "sendpulse/sendpulse-rest-api-php",
    5             "version": "dev-master",
    6             "version_normalized": "dev-master",
     4            "name": "sendpulse/rest-api",
     5            "version": "2.0.1.2",
     6            "version_normalized": "2.0.1.2",
    77            "source": {
    88                "type": "git",
    99                "url": "https://github.com/sendpulse/sendpulse-rest-api-php.git",
    10                 "reference": "47d66d03b6c9fcc3feae337dc3ae86c42bb364b3"
     10                "reference": "457ca31c0ff3a3f849182d053d50928085d432ae"
    1111            },
    1212            "require": {
    13                 "php": ">=5.4.0"
     13                "ext-curl": "*",
     14                "ext-json": "*",
     15                "php": ">=7.1.0"
    1416            },
    15             "time": "2017-06-27T12:29:09+00:00",
     17            "time": "2024-06-03T10:49:25+00:00",
    1618            "type": "library",
    1719            "installation-source": "source",
    1820            "autoload": {
    19                 "classmap": [
    20                     "api/"
    21                 ]
     21                "psr-4": {
     22                    "Sendpulse\\RestApi\\": "src/"
     23                }
    2224            },
    23             "description": "The Sendpulse API functions.",
    24             "install-path": "../sendpulse/sendpulse-rest-api-php"
    25         },
    26         {
    27             "name": "tareq1988/wordpress-settings-api-class",
    28             "version": "dev-master",
    29             "version_normalized": "dev-master",
    30             "source": {
    31                 "type": "git",
    32                 "url": "https://github.com/tareq1988/wordpress-settings-api-class.git",
    33                 "reference": "11a1685a3dd1b0451674c18288e5bd129dcbebe6"
    34             },
    35             "dist": {
    36                 "type": "zip",
    37                 "url": "https://api.github.com/repos/tareq1988/wordpress-settings-api-class/zipball/11a1685a3dd1b0451674c18288e5bd129dcbebe6",
    38                 "reference": "11a1685a3dd1b0451674c18288e5bd129dcbebe6",
    39                 "shasum": ""
    40             },
    41             "require": {
    42                 "php": ">=5.2.4"
    43             },
    44             "time": "2017-07-02T14:15:10+00:00",
    45             "type": "library",
    46             "installation-source": "source",
    47             "autoload": {
    48                 "classmap": [
    49                     "src/"
    50                 ]
    51             },
    52             "notification-url": "https://packagist.org/downloads/",
    5325            "license": [
    54                 "GPLv2"
     26                "MIT"
    5527            ],
    5628            "authors": [
    5729                {
    58                     "name": "Tareq Hasan",
    59                     "email": "[email protected]",
    60                     "homepage": "http://tareq.wedevs.com",
    61                     "role": "Developer"
     30                    "name": "Maksym Ustymenko",
     31                    "email": "[email protected]"
     32                },
     33                {
     34                    "name": "Alexey Moroz",
     35                    "email": "[email protected]"
     36                },
     37                {
     38                    "name": "Evgeniy Bilovol",
     39                    "email": "[email protected]"
    6240                }
    6341            ],
    64             "description": "WordPress settings API Abstraction Class",
    65             "homepage": "https://github.com/tareq1988/wordpress-settings-api-class",
     42            "description": "Sendpulse REST API client library",
    6643            "keywords": [
    67                 "settings-api",
    68                 "wordpress",
    69                 "wp"
     44                "api",
     45                "rest",
     46                "sendpulse"
    7047            ],
    71             "install-path": "../tareq1988/wordpress-settings-api-class"
     48            "install-path": "../sendpulse/rest-api"
    7249        }
    7350    ],
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/installed.php

    r2933319 r3354585  
    22    'root' => array(
    33        'name' => '__root__',
    4         'pretty_version' => 'dev-master',
    5         'version' => 'dev-master',
    6         'reference' => '132ef1d09e4b6ca275b5b03f75c68fa6f5afcd1a',
     4        'pretty_version' => '1.0.0+no-version-set',
     5        'version' => '1.0.0.0',
     6        'reference' => null,
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    1212    'versions' => array(
    1313        '__root__' => array(
    14             'pretty_version' => 'dev-master',
    15             'version' => 'dev-master',
    16             'reference' => '132ef1d09e4b6ca275b5b03f75c68fa6f5afcd1a',
     14            'pretty_version' => '1.0.0+no-version-set',
     15            'version' => '1.0.0.0',
     16            'reference' => null,
    1717            'type' => 'library',
    1818            'install_path' => __DIR__ . '/../../',
     
    2020            'dev_requirement' => false,
    2121        ),
    22         'sendpulse/sendpulse-rest-api-php' => array(
    23             'pretty_version' => 'dev-master',
    24             'version' => 'dev-master',
    25             'reference' => '47d66d03b6c9fcc3feae337dc3ae86c42bb364b3',
     22        'sendpulse/rest-api' => array(
     23            'pretty_version' => '2.0.1.2',
     24            'version' => '2.0.1.2',
     25            'reference' => '457ca31c0ff3a3f849182d053d50928085d432ae',
    2626            'type' => 'library',
    27             'install_path' => __DIR__ . '/../sendpulse/sendpulse-rest-api-php',
    28             'aliases' => array(),
    29             'dev_requirement' => false,
    30         ),
    31         'tareq1988/wordpress-settings-api-class' => array(
    32             'pretty_version' => 'dev-master',
    33             'version' => 'dev-master',
    34             'reference' => '11a1685a3dd1b0451674c18288e5bd129dcbebe6',
    35             'type' => 'library',
    36             'install_path' => __DIR__ . '/../tareq1988/wordpress-settings-api-class',
     27            'install_path' => __DIR__ . '/../sendpulse/rest-api',
    3728            'aliases' => array(),
    3829            'dev_requirement' => false,
  • sendpulse-email-marketing-newsletter/trunk/vendor/composer/platform_check.php

    r2791914 r3354585  
    55$issues = array();
    66
    7 if (!(PHP_VERSION_ID >= 50400)) {
    8     $issues[] = 'Your Composer dependencies require a PHP version ">= 5.4.0". You are running ' . PHP_VERSION . '.';
     7if (!(PHP_VERSION_ID >= 70100)) {
     8    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
    99}
    1010
Note: See TracChangeset for help on using the changeset viewer.