Poll, Survey, Quiz, Slideshow, Form, Story & Landing Page - Version 19.7.4

Version Description

  • updated plugin name
    • added poll on disabling plugin
    • renamed Form block to Classic Form
    • internal code improvements
Download this release

Release Info

Developer artemopinionstage
Plugin Icon 128x128 Poll, Survey, Quiz, Slideshow, Form, Story & Landing Page
Version 19.7.4
Comparing to
See all releases

Code changes from version 19.7.3 to 19.7.4

admin/content-popup-template.html.php CHANGED
@@ -1,27 +1,27 @@
1
  <?php
2
  // block direct access to plugin PHP files:
3
- defined( 'ABSPATH' ) or die();
4
 
5
- require_once( plugin_dir_path( __FILE__ ).'../includes/opinionstage-client-session.php' );
6
 
7
  $opinionstage_user_logged_in = opinionstage_user_logged_in();
8
 
9
- // Note: all html put here (not moved to js build system) in order to preserve ability to use Wordpress translate APIs
10
  ?>
11
  <style type="text/css">
12
  .content__image {
13
- background-image: url(<?php echo plugins_url('', dirname(__FILE__) ) . '/admin/images/form-not-found.png' ?>);
14
- background-repeat: no-repeat;
15
- background-size: cover;
16
  }
17
  </style>
18
  <template data-opinionstage-content-popup-template>
19
- <div class='opinionstage-content-popup-contents' data-opinionstage-content-popup data-opinionstage-client-logged-in="<?php echo $opinionstage_user_logged_in ?>">
20
  <header class='header'>
21
  <div class='header__container'>
22
  <div class='header__logo'>
23
- <a href='<?php echo OPINIONSTAGE_SERVER_BASE ?>' target='_blank'>
24
- <img src='<?php echo plugins_url('admin/images/os-logo-header.png', plugin_dir_path( __FILE__ )) ?>'>
25
  </a>
26
  </div>
27
  <div class='header__action'>
@@ -36,11 +36,11 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
36
  :modal-is-opened="isModalOpened"
37
  :widget-type="widgetType"
38
  @widget-selected="selectWidgetAndExit"
39
- client-widgets-url="<?php echo OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API ?>"
40
- shared-widgets-url="<?php echo OPINIONSTAGE_CONTENT_POPUP_SHARED_WIDGETS_API ?>"
41
- client-widgets-has-new-url="<?php echo OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API_RECENT_UPDATE ?>"
42
- access-key="<?php echo opinionstage_user_access_token() ?>"
43
- plugin-version="<?php echo OPINIONSTAGE_WIDGET_VERSION ?>"
44
  >
45
  </popup-content>
46
  </section>
@@ -51,7 +51,7 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
51
  <div class='page-content'>
52
  <div class='content-actions'>
53
  <div class='content-actions__left'>
54
- <h1 class="main-title">My Items</h1>
55
  </div>
56
  <div class="content-actions__right">
57
  <div class='filter'>
@@ -61,27 +61,27 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
61
  <div class='filter__itm'
62
  @click="selectWidgetType('all')"
63
  :class="{ active: selectedWidgetType === 'all' }"
64
- >all Items</div>
65
  <div class='filter__itm'
66
  @click="selectWidgetType('poll')"
67
  :class="{ active: selectedWidgetType === 'poll' }"
68
- >poll</div>
69
  <div class='filter__itm'
70
  @click="selectWidgetType('survey')"
71
  :class="{ active: selectedWidgetType === 'survey' }"
72
- >survey</div>
73
  <div class='filter__itm'
74
  @click="selectWidgetType('trivia')"
75
  :class="{ active: selectedWidgetType === 'trivia' }"
76
- >trivia quiz</div>
77
  <div class='filter__itm'
78
  @click="selectWidgetType('outcome')"
79
  :class="{ active: selectedWidgetType === 'outcome' }"
80
- >personality quiz</div>
81
  <div class='filter__itm'
82
  @click="selectWidgetType('form')"
83
  :class="{ active: selectedWidgetType === 'form' }"
84
- >form</div>
85
  </div>
86
  </div>
87
  </div>
@@ -95,7 +95,7 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
95
  <span class="os-search__icon icon-os-common-tip"></span>
96
  </div>
97
  <div class="content-actions__sep"></div>
98
- <a href="<?php echo admin_url( 'admin.php?page=' . OPINIONSTAGE_MENU_SLUG ); ?>" target='_blank' class="btn-create">CREATE</a>
99
  </div>
100
  </div>
101
  <div class='content__list'>
@@ -109,30 +109,30 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
109
  </a>
110
  <p class='content__info'><a target="_blank" :href='widget.editUrl'>{{ widget.title }}</a></p>
111
  <div class='content__links'>
112
- <button class='popup-content-btn content__links-itm' @click="select(widget)">insert</button>
113
  <div class="dropdown dropdown-popup-action">
114
  <div class="popup-action popup-content-btn"></div>
115
  <div class="popup-action-dropdown dropdown-content">
116
- <a class='content__links-itm' target="_blank" :href='widget.landingPageUrl'>view</a>
117
- <a class='content__links-itm' target="_blank" :href='widget.editUrl' v-show="!widget.template">edit</a>
118
- <a class='content__links-itm' target="_blank" :href='widget.statsUrl' v-show="!widget.template">Results</a>
119
  </div>
120
  </div>
121
  </div>
122
  </div>
123
  <div class='content__loading' v-if='dataLoading'>
124
- loading...
125
  </div>
126
  <div v-else>
127
  <button
128
  class='btn-show-more'
129
  v-if='!noMoreData'
130
  @click='showMore'
131
- >Click for more</button>
132
  </div>
133
  </div>
134
  <div v-else>
135
- No items found
136
  </div>
137
  </div>
138
  </div>
@@ -157,9 +157,9 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
157
  </div>
158
  <div class='page-content' v-else>
159
  <h1 class='main-title'>
160
- <b>Connect WordPress with Opinion Stage to get started</b>
161
  </h1>
162
- <a id="os-start-login" data-os-login="" href="<?php echo admin_url( 'admin.php?page=opinionstage-getting-started' ); ?>" class="opinionstage-blue-btn">CONNECT</a>
163
  </div>
164
  </div>
165
  <div v-else>
@@ -179,10 +179,10 @@ $opinionstage_user_logged_in = opinionstage_user_logged_in();
179
  <template id="opinionstage-notification">
180
  <div class="opinionstage-section-notification">
181
  <p class="opinionstage-section-notification__title">
182
- Your content has been updated, please click the button to update your view
183
  </p>
184
  <div class="opinionstage-section-notification__controls">
185
- <button class='btn-blue' @click="initiateUpdate">Update view</button>
186
  </div>
187
  </div>
188
  </template>
1
  <?php
2
  // block direct access to plugin PHP files:
3
+ defined( 'ABSPATH' ) || die();
4
 
5
+ require_once plugin_dir_path( __FILE__ ) . '../includes/opinionstage-client-session.php';
6
 
7
  $opinionstage_user_logged_in = opinionstage_user_logged_in();
8
 
9
+ // Note: all html put here (not moved to js build system) in order to preserve ability to use WordPress translate APIs.
10
  ?>
11
  <style type="text/css">
12
  .content__image {
13
+ background-image: url(<?php echo esc_url( plugins_url( '', dirname( __FILE__ ) ) . '/admin/images/form-not-found.png' ); ?>);
14
+ background-repeat: no-repeat;
15
+ background-size: cover;
16
  }
17
  </style>
18
  <template data-opinionstage-content-popup-template>
19
+ <div class='opinionstage-content-popup-contents' data-opinionstage-content-popup data-opinionstage-client-logged-in="<?php echo esc_attr( $opinionstage_user_logged_in ); ?>">
20
  <header class='header'>
21
  <div class='header__container'>
22
  <div class='header__logo'>
23
+ <a href='<?php echo esc_url( OPINIONSTAGE_SERVER_BASE ); ?>' target='_blank'>
24
+ <img src='<?php echo esc_url( plugins_url( 'admin/images/os-logo-header.png', plugin_dir_path( __FILE__ ) ) ); ?>'>
25
  </a>
26
  </div>
27
  <div class='header__action'>
36
  :modal-is-opened="isModalOpened"
37
  :widget-type="widgetType"
38
  @widget-selected="selectWidgetAndExit"
39
+ client-widgets-url="<?php echo esc_url( OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API ); ?>"
40
+ shared-widgets-url="<?php echo esc_url( OPINIONSTAGE_CONTENT_POPUP_SHARED_WIDGETS_API ); ?>"
41
+ client-widgets-has-new-url="<?php echo esc_url( OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API_RECENT_UPDATE ); ?>"
42
+ access-key="<?php echo esc_js( opinionstage_user_access_token() ); ?>"
43
+ plugin-version="<?php echo esc_js( OPINIONSTAGE_WIDGET_VERSION ); ?>"
44
  >
45
  </popup-content>
46
  </section>
51
  <div class='page-content'>
52
  <div class='content-actions'>
53
  <div class='content-actions__left'>
54
+ <h1 class="main-title"><?php esc_html_e( 'My Items', 'social-polls-by-opinionstage' ); ?></h1>
55
  </div>
56
  <div class="content-actions__right">
57
  <div class='filter'>
61
  <div class='filter__itm'
62
  @click="selectWidgetType('all')"
63
  :class="{ active: selectedWidgetType === 'all' }"
64
+ ><?php esc_html_e( 'all items', 'social-polls-by-opinionstage' ); ?></div>
65
  <div class='filter__itm'
66
  @click="selectWidgetType('poll')"
67
  :class="{ active: selectedWidgetType === 'poll' }"
68
+ ><?php esc_html_e( 'poll', 'social-polls-by-opinionstage' ); ?></div>
69
  <div class='filter__itm'
70
  @click="selectWidgetType('survey')"
71
  :class="{ active: selectedWidgetType === 'survey' }"
72
+ ><?php esc_html_e( 'survey', 'social-polls-by-opinionstage' ); ?></div>
73
  <div class='filter__itm'
74
  @click="selectWidgetType('trivia')"
75
  :class="{ active: selectedWidgetType === 'trivia' }"
76
+ ><?php esc_html_e( 'trivia quiz', 'social-polls-by-opinionstage' ); ?></div>
77
  <div class='filter__itm'
78
  @click="selectWidgetType('outcome')"
79
  :class="{ active: selectedWidgetType === 'outcome' }"
80
+ ><?php esc_html_e( 'personality quiz', 'social-polls-by-opinionstage' ); ?></div>
81
  <div class='filter__itm'
82
  @click="selectWidgetType('form')"
83
  :class="{ active: selectedWidgetType === 'form' }"
84
+ ><?php esc_html_e( 'classic form', 'social-polls-by-opinionstage' ); ?></div>
85
  </div>
86
  </div>
87
  </div>
95
  <span class="os-search__icon icon-os-common-tip"></span>
96
  </div>
97
  <div class="content-actions__sep"></div>
98
+ <a href="<?php echo esc_url( admin_url( 'admin.php?page=' . OPINIONSTAGE_MENU_SLUG ) ); ?>" target='_blank' class="btn-create"><?php esc_html_e( 'CREATE', 'social-polls-by-opinionstage' ); ?></a>
99
  </div>
100
  </div>
101
  <div class='content__list'>
109
  </a>
110
  <p class='content__info'><a target="_blank" :href='widget.editUrl'>{{ widget.title }}</a></p>
111
  <div class='content__links'>
112
+ <button class='popup-content-btn content__links-itm' @click="select(widget)"><?php esc_html_e( 'insert', 'social-polls-by-opinionstage' ); ?></button>
113
  <div class="dropdown dropdown-popup-action">
114
  <div class="popup-action popup-content-btn"></div>
115
  <div class="popup-action-dropdown dropdown-content">
116
+ <a class='content__links-itm' target="_blank" :href='widget.landingPageUrl'><?php esc_html_e( 'view', 'social-polls-by-opinionstage' ); ?></a>
117
+ <a class='content__links-itm' target="_blank" :href='widget.editUrl' v-show="!widget.template"><?php esc_html_e( 'edit', 'social-polls-by-opinionstage' ); ?></a>
118
+ <a class='content__links-itm' target="_blank" :href='widget.statsUrl' v-show="!widget.template"><?php esc_html_e( 'Results', 'social-polls-by-opinionstage' ); ?></a>
119
  </div>
120
  </div>
121
  </div>
122
  </div>
123
  <div class='content__loading' v-if='dataLoading'>
124
+ <?php esc_html_e( 'loading...', 'social-polls-by-opinionstage' ); ?>
125
  </div>
126
  <div v-else>
127
  <button
128
  class='btn-show-more'
129
  v-if='!noMoreData'
130
  @click='showMore'
131
+ ><?php esc_html_e( 'Click for more', 'social-polls-by-opinionstage' ); ?></button>
132
  </div>
133
  </div>
134
  <div v-else>
135
+ <?php esc_html_e( 'No items found', 'social-polls-by-opinionstage' ); ?>
136
  </div>
137
  </div>
138
  </div>
157
  </div>
158
  <div class='page-content' v-else>
159
  <h1 class='main-title'>
160
+ <b><?php esc_html_e( 'all items', 'social-polls-by-opinionstage' ); ?></b>
161
  </h1>
162
+ <a id="os-start-login" data-os-login="" href="<?php echo esc_url( admin_url( 'admin.php?page=opinionstage-getting-started' ) ); ?>" class="opinionstage-blue-btn"><?php esc_html_e( 'CONNECT', 'social-polls-by-opinionstage' ); ?></a>
163
  </div>
164
  </div>
165
  <div v-else>
179
  <template id="opinionstage-notification">
180
  <div class="opinionstage-section-notification">
181
  <p class="opinionstage-section-notification__title">
182
+ <?php esc_html_e( 'Your content has been updated, please click the button to update your view', 'social-polls-by-opinionstage' ); ?>
183
  </p>
184
  <div class="opinionstage-section-notification__controls">
185
+ <button class='btn-blue' @click="initiateUpdate"><?php esc_html_e( 'Update view', 'social-polls-by-opinionstage' ); ?></button>
186
  </div>
187
  </div>
188
  </template>
admin/content-popup.php CHANGED
@@ -1,27 +1,35 @@
1
  <?php
2
- // block direct access to plugin PHP files:
3
- defined( 'ABSPATH' ) or die();
4
 
5
- add_action( 'media_buttons', 'opinionstage_content_popup_add_editor_button');
6
- add_action( 'admin_enqueue_scripts', 'opinionstage_content_popup_js');
7
  add_action( 'admin_footer', 'opinionstage_content_popup_html' );
8
 
 
 
 
9
  function opinionstage_content_popup_add_editor_button() {
10
- require( plugin_dir_path( __FILE__ ).'content-popup-button.php' );
11
  }
12
 
 
 
 
13
  function opinionstage_content_popup_js() {
14
 
15
- // asset loader hotfix TODO: improve this loader machanism
16
  opinionstage_register_javascript_asset(
17
  'content-popup',
18
  'content-popup.js',
19
- array('jquery')
20
  );
21
 
22
- opinionstage_enqueue_js_asset('content-popup');
23
  }
24
 
 
 
 
25
  function opinionstage_content_popup_html() {
26
  require_once OPINIONSTAGE_PLUGIN_DIR . 'admin/content-popup-template.html.php';
27
  }
1
  <?php
2
+ defined( 'ABSPATH' ) || die();
 
3
 
4
+ add_action( 'media_buttons', 'opinionstage_content_popup_add_editor_button' );
5
+ add_action( 'admin_enqueue_scripts', 'opinionstage_content_popup_js' );
6
  add_action( 'admin_footer', 'opinionstage_content_popup_html' );
7
 
8
+ /**
9
+ * Include content popup button
10
+ */
11
  function opinionstage_content_popup_add_editor_button() {
12
+ require plugin_dir_path( __FILE__ ) . 'content-popup-button.php';
13
  }
14
 
15
+ /**
16
+ * Include content popup JS
17
+ */
18
  function opinionstage_content_popup_js() {
19
 
20
+ // asset loader hotfix TODO: improve this loader machanism.
21
  opinionstage_register_javascript_asset(
22
  'content-popup',
23
  'content-popup.js',
24
+ array( 'jquery' )
25
  );
26
 
27
+ opinionstage_enqueue_js_asset( 'content-popup' );
28
  }
29
 
30
+ /**
31
+ * Include content popup HTML
32
+ */
33
  function opinionstage_content_popup_html() {
34
  require_once OPINIONSTAGE_PLUGIN_DIR . 'admin/content-popup-template.html.php';
35
  }
admin/css/admin-feedback.css ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #opinionistage-deactivate-feedback-modal {
2
+ display: none;
3
+ position: fixed;
4
+ height: 100%;
5
+ width: 100%;
6
+ bottom: 0;
7
+ left: 0;
8
+ background-color: rgba(0,0,0,.8);
9
+ z-index: 9999;
10
+ -webkit-user-select: none;
11
+ -moz-user-select: none;
12
+ -ms-user-select: none;
13
+ user-select: none;
14
+ }
15
+ .opinionstage-dialog-box-content {
16
+ background-color: #fff;
17
+ position: absolute;
18
+ top: 50%;
19
+ left: 50%;
20
+ transform: translate(-50%, -50%);
21
+ -webkit-border-radius: 3px;
22
+ border-radius: 3px;
23
+ -webkit-box-shadow: 2px 8px 23px 3px rgba(0,0,0,.2);
24
+ box-shadow: 2px 8px 23px 3px rgba(0,0,0,.2);
25
+ overflow: hidden;
26
+ width: 550px;
27
+ }
28
+
29
+ .opinionstage-dialog-box-content .opinionstage-modal-logo {
30
+ position: relative;
31
+ left: -3px;
32
+ bottom: -2px;
33
+ padding: 0
34
+ }
35
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-header {
36
+ padding: 18px 15px;
37
+ -webkit-box-shadow: 0 0 8px rgba(0,0,0,.1);
38
+ box-shadow: 0 0 8px rgba(0,0,0,.1);
39
+ text-align: left;
40
+ }
41
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-header .opinionstage-modal-header {
42
+ font-size: 15px;
43
+ text-transform: uppercase;
44
+ font-weight: bold;
45
+ }
46
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-form-caption {
47
+ font-size: 15px;
48
+ font-weight: bold;
49
+ }
50
+ .opinionstage-dialog-box-content .opinionstage-choices-wrapper {
51
+ padding-top: 20px;
52
+ }
53
+ .opinionstage-dialog-box-content .opinionstage-dialog-message {
54
+ padding: 30px 30px 0;
55
+ text-align: left;
56
+ }
57
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons {
58
+ border-top: none;
59
+ text-align: left;
60
+ padding: 20px 30px 30px;
61
+ overflow: hidden;
62
+ }
63
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons button {
64
+ border: none;
65
+ }
66
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-skip,
67
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-submit {
68
+ cursor: pointer;
69
+ }
70
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-skip:focus,
71
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-submit:focus {
72
+ outline: none;
73
+ }
74
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-submit {
75
+ position: relative;
76
+ background-color: #32adbc;
77
+ -webkit-border-radius: 3px;
78
+ border-radius: 3px;
79
+ color: #fff;
80
+ line-height: 1;
81
+ padding: 12px 20px;
82
+ font-size: 13px;
83
+ width: 180px;
84
+ height: 38px;
85
+ transition: all 1s ease;
86
+ }
87
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-submit.opinionstage-loading {
88
+ padding-left: 35px;
89
+ opacity: .9;
90
+ }
91
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-submit.opinionstage-loading .opinionstage-loading-ring {
92
+ opacity: 1;
93
+ }
94
+ .opinionstage-loading-ring {
95
+ width: 28px;
96
+ height: 28px;
97
+ position: absolute;
98
+ left: 5px;
99
+ top: 7px;
100
+ opacity: 0;
101
+ transition: opacity 1s ease;
102
+ }
103
+ .opinionstage-loading-ring:after {
104
+ content: " ";
105
+ display: block;
106
+ width: 20px;
107
+ height: 20px;
108
+ border-radius: 50%;
109
+ border: 2px solid #fff;
110
+ border-color: #fff transparent #fff transparent;
111
+ animation: opinionstage-loading-ring 1.2s linear infinite;
112
+ }
113
+ .opinionstage-dialog-box-content .opinionstage-dialog-buttons .opinionstage-dialog-skip {
114
+ font-size: 13px;
115
+ color: #a4afb7;
116
+ padding: 13px 0;
117
+ background: none;
118
+ float: right;
119
+ width: auto;
120
+ }
121
+
122
+ .opinionstage-dialog-box-content .opinionstage-feedback-text {
123
+ display: block;
124
+ margin: 10px 0 0 30px;
125
+ padding: 5px;
126
+ font-size: 13px;
127
+ -webkit-box-shadow: none;
128
+ box-shadow: none;
129
+ background-color: #fff;
130
+ width: 92%;
131
+ }
132
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-input:not(:checked)~.opinionstage-feedback-text {
133
+ display: none;
134
+ }
135
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-input {
136
+ margin-top: 2px;
137
+ }
138
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-form-caption,
139
+ .opinionstage-dialog-box-content .opinionstage-deactivate-feedback-dialog-input-wrapper {
140
+ margin-bottom: 10px;
141
+ }
142
+
143
+
144
+ .opinionstage-close {
145
+ position: absolute;
146
+ right: 32px;
147
+ top: 22px;
148
+ width: 20px;
149
+ height: 20px;
150
+ cursor: pointer;
151
+ }
152
+ .opinionstage-close:before,
153
+ .opinionstage-close:after {
154
+ position: absolute;
155
+ left: 15px;
156
+ content: ' ';
157
+ height: 17px;
158
+ width: 2px;
159
+ background-color: #333;
160
+ }
161
+ .opinionstage-close:before {
162
+ transform: rotate(45deg);
163
+ }
164
+ .opinionstage-close:after {
165
+ transform: rotate(-45deg);
166
+ }
167
+
168
+ @keyframes opinionstage-loading-ring {
169
+ 0% {
170
+ transform: rotate(0deg);
171
+ }
172
+ 100% {
173
+ transform: rotate(360deg);
174
+ }
175
+ }
admin/js/admin-feedback.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function ($) {
2
+ var OpinionStageDialogApp = {
3
+ cacheElements: function cacheElements() {
4
+ this.cache = {
5
+ $deactivateLink: $('#the-list').find('[data-slug="social-polls-by-opinionstage"] span.deactivate a'),
6
+ $modal: $('#opinionistage-deactivate-feedback-modal'),
7
+ $skipButton: $('#opinionstage-dialog-skip'),
8
+ $closeButton: $('#opinionstage-dialog-close'),
9
+ $submitButton: $('#opinionstage-dialog-submit'),
10
+ $dialogForm: $('#opinionstage-deactivate-feedback-dialog-form')
11
+ }
12
+ },
13
+ deactivate: function deactivate(e) {
14
+ location.href = this.cache.$deactivateLink.attr('href');
15
+ },
16
+ bindEvents: function bindEvents() {
17
+ var self = this;
18
+ self.cache.$deactivateLink.on('click', function (e) {
19
+ e.preventDefault();
20
+ self.cache.$modal.fadeIn();
21
+ });
22
+
23
+ self.cache.$modal.on('click', function (e) {
24
+ if ($(e.target).is(self.cache.$modal)) {
25
+ self.cache.$modal.fadeOut();
26
+ }
27
+ });
28
+ self.cache.$closeButton.on('click', function (e) {
29
+ self.cache.$modal.fadeOut();
30
+ })
31
+
32
+ self.cache.$skipButton.on('click', function (e) {
33
+ self.deactivate();
34
+ })
35
+ self.cache.$submitButton.on('click', function (e) {
36
+ e.preventDefault();
37
+ self.sendFeedback();
38
+ $(this).addClass('opinionstage-loading');
39
+ })
40
+ },
41
+ sendFeedback: function sendFeedback(){
42
+ var self = this,
43
+ formData = self.cache.$dialogForm.serialize();
44
+ $.post(ajaxurl, formData, this.deactivate.bind(this));
45
+ },
46
+ init: function init() {
47
+ this.cacheElements();
48
+ this.bindEvents();
49
+ }
50
+ }
51
+
52
+ $(function () {
53
+ OpinionStageDialogApp.init();
54
+ });
55
+
56
+ }(jQuery));
admin/views/settings.php CHANGED
@@ -1,111 +1,113 @@
1
  <?php
2
- // block direct access to plugin PHP files:
3
- defined( 'ABSPATH' ) or die();
 
 
4
  ?>
5
  <div id="opinionstage-content">
6
  <div class="opinionstage-header-wrapper">
7
- <?php if ( !$os_client_logged_in ) {?>
8
  <div class="opinionstage-logo-wrapper">
9
  <div class="opinionstage-logo"></div>
10
- </div>
11
  <div class="opinionstage-status-content">
12
- <div class='opinionstage-status-title'><b class="opinionstage-title" style="font-size: 20px;">Connect WordPress with Opinion Stage to get started</b></div>
13
- <form action="<?php echo OPINIONSTAGE_LOGIN_PATH ?>" method="get" class="opinionstage-connect-form">
14
- <input type="hidden" name="utm_source" value="<?php echo OPINIONSTAGE_UTM_SOURCE ?>">
15
- <input type="hidden" name="utm_campaign" value="<?php echo OPINIONSTAGE_UTM_CAMPAIGN ?>">
16
- <input type="hidden" name="utm_medium" value="<?php echo OPINIONSTAGE_UTM_CONNECT_MEDIUM ?>">
17
- <input type="hidden" name="o" value="<?php echo OPINIONSTAGE_WIDGET_API_KEY ?>">
18
- <input type="hidden" name="callback" value="<?php echo opinionstage_callback_url()?>">
19
- <input id="os-email" type="email" name="email" placeholder="Your email" data-os-email-input required>
20
- <button class="opinionstage-connect-btn opinionstage-blue-btn" type="submit" id="os-start-login" data-os-login>CONNECT</button>
21
  </form>
22
  </div>
23
  <?php } else { ?>
24
  <div class="opinionstage-logo-wrapper">
25
  <div class="opinionstage-logo"></div>
26
- <div class="opinionstage-connectivity-status"><?php echo($os_options["email"]); ?>
27
- <form method="POST" action="<?php echo get_admin_url(null, 'admin.php?page='.OPINIONSTAGE_DISCONNECT_PAGE)?>" class="opinionstage-connect-form">
28
- <button class="opinionstage-disconnect" type="submit">Disconnect</button>
29
  </form>
30
  </div>
31
- </div>
32
- <?php } ?>
33
  </div>
34
  <div class="opinionstage-dashboard">
35
  <div class="opinionstage-dashboard-left">
36
  <div id="opinionstage-section-create" class="opinionstage-dashboard-section">
37
  <div class="opinionstage-section-header">
38
- <div class="opinionstage-section-title">Create</div>
39
- <?php echo opinionstage_help_links('Need help adding items to your site?', 'https://help.opinionstage.com/wordpress-plugin/how-to-add-items-to-your-wordpress-site', 'opinionstage-need-help-link'); ?>
40
  </div>
41
  <div class="opinionstage-section-content" style="position: relative;">
42
  <div class="opinionstage-section-raw">
43
  <div class="opinionstage-section-cell opinionstage-icon-cell">
44
- <div class="os-icon-plugin"><img src="<?php echo plugins_url( 'images/poll.png', dirname(__FILE__) ); ?>" ></div>
45
  </div>
46
  <div class="opinionstage-section-cell opinionstage-description-cell">
47
- <div class="title">Poll</div>
48
- <div class="example">Get opinions, run contests & competitions</div>
49
  </div>
50
  <div class="opinionstage-section-cell opinionstage-btn-cell">
51
- <?php echo opinionstage_create_poll_link('opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template'); ?>
52
- <?php echo opinionstage_template_poll_link('opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template'); ?>
53
  </div>
54
  </div>
55
  <div class="opinionstage-section-raw">
56
  <div class="opinionstage-section-cell opinionstage-icon-cell">
57
- <div class="os-icon-plugin"><img src="<?php echo plugins_url( 'images/personality.png', dirname(__FILE__) ); ?>" ></div>
58
  </div>
59
  <div class="opinionstage-section-cell opinionstage-description-cell">
60
- <div class="title">Personality Quiz</div>
61
- <div class="example">Create a personality test or a product/service selector</div>
62
  </div>
63
  <div class="opinionstage-section-cell opinionstage-btn-cell">
64
- <?php echo opinionstage_create_personality_link('opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template'); ?>
65
- <?php echo opinionstage_template_personality_quiz_link('opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template') ?>
66
  </div>
67
  </div>
68
  <div class="opinionstage-section-raw">
69
  <div class="opinionstage-section-cell opinionstage-icon-cell">
70
- <div class="os-icon-plugin"><img src="<?php echo plugins_url( 'images/trivia.png', dirname(__FILE__) ); ?>" ></div>
71
  </div>
72
  <div class="opinionstage-section-cell opinionstage-description-cell">
73
- <div class="title">Trivia Quiz</div>
74
- <div class="example">Create a knowledge test or assessment</div>
75
  </div>
76
  <div class="opinionstage-section-cell opinionstage-btn-cell">
77
- <?php echo opinionstage_create_trivia_link('opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template'); ?>
78
- <?php echo opinionstage_template_trivia_link('opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template'); ?>
79
  </div>
80
  </div>
81
  <div class="opinionstage-section-raw">
82
  <div class="opinionstage-section-cell opinionstage-icon-cell">
83
- <div class="os-icon-plugin"><img src="<?php echo plugins_url( 'images/survey.png', dirname(__FILE__) ); ?>" ></div>
84
  </div>
85
  <div class="opinionstage-section-cell opinionstage-description-cell">
86
- <div class="title">Survey</div>
87
- <div class="example">Gather feedback from your users</div>
88
  </div>
89
  <div class="opinionstage-section-cell opinionstage-btn-cell">
90
- <?php echo opinionstage_create_survey_link('opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template'); ?>
91
- <?php echo opinionstage_template_survey_link('opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template'); ?>
92
  </div>
93
  </div>
94
  <div class="opinionstage-section-raw">
95
  <div class="opinionstage-section-cell opinionstage-icon-cell">
96
- <div class="os-icon-plugin"><img src="<?php echo plugins_url( 'images/form.png', dirname(__FILE__) ); ?>" ></div>
97
  </div>
98
  <div class="opinionstage-section-cell opinionstage-description-cell">
99
- <div class="title">Form</div>
100
- <div class="example">Gather information from your users</div>
101
  </div>
102
  <div class="opinionstage-section-cell opinionstage-btn-cell">
103
- <?php echo opinionstage_create_form_link('opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template'); ?>
104
- <?php echo opinionstage_template_form_link('opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template'); ?>
105
  </div>
106
  </div>
107
  </div>
108
  </div>
109
- </div>
110
  </div>
111
  </div>
1
  <?php
2
+ /**
3
+ *
4
+ */
5
+ defined( 'ABSPATH' ) || die();
6
  ?>
7
  <div id="opinionstage-content">
8
  <div class="opinionstage-header-wrapper">
9
+ <?php if ( ! $os_client_logged_in ) { ?>
10
  <div class="opinionstage-logo-wrapper">
11
  <div class="opinionstage-logo"></div>
12
+ </div>
13
  <div class="opinionstage-status-content">
14
+ <div class='opinionstage-status-title'><b class="opinionstage-title" style="font-size: 20px;"><?php esc_html_e( 'Connect WordPress with Opinion Stage to get started', 'social-polls-by-opinionstage' ); ?></b></div>
15
+ <form action="<?php echo esc_url( OPINIONSTAGE_LOGIN_PATH ); ?>" method="get" class="opinionstage-connect-form">
16
+ <input type="hidden" name="utm_source" value="<?php echo esc_attr( OPINIONSTAGE_UTM_SOURCE ); ?>">
17
+ <input type="hidden" name="utm_campaign" value="<?php echo esc_attr( OPINIONSTAGE_UTM_CAMPAIGN ); ?>">
18
+ <input type="hidden" name="utm_medium" value="<?php echo esc_attr( OPINIONSTAGE_UTM_CONNECT_MEDIUM ); ?>">
19
+ <input type="hidden" name="o" value="<?php echo esc_attr( OPINIONSTAGE_WIDGET_API_KEY ); ?>">
20
+ <input type="hidden" name="callback" value="<?php echo esc_attr( opinionstage_callback_url() ); ?>">
21
+ <input id="os-email" type="email" name="email" placeholder="<?php esc_html_e( 'Your email', 'social-polls-by-opinionstage' ); ?>" data-os-email-input required>
22
+ <button class="opinionstage-connect-btn opinionstage-blue-btn" type="submit" id="os-start-login" data-os-login><?php esc_html_e( 'CONNECT', 'social-polls-by-opinionstage' ); ?></button>
23
  </form>
24
  </div>
25
  <?php } else { ?>
26
  <div class="opinionstage-logo-wrapper">
27
  <div class="opinionstage-logo"></div>
28
+ <div class="opinionstage-connectivity-status"><?php echo esc_html( $os_options['email'] ); ?>
29
+ <form method="POST" action="<?php echo esc_url( get_admin_url( null, 'admin.php?page=' . OPINIONSTAGE_DISCONNECT_PAGE ) ); ?>" class="opinionstage-connect-form">
30
+ <button class="opinionstage-disconnect" type="submit"><?php esc_html_e( 'Disconnect', 'social-polls-by-opinionstage' ); ?></button>
31
  </form>
32
  </div>
33
+ </div>
34
+ <?php } ?>
35
  </div>
36
  <div class="opinionstage-dashboard">
37
  <div class="opinionstage-dashboard-left">
38
  <div id="opinionstage-section-create" class="opinionstage-dashboard-section">
39
  <div class="opinionstage-section-header">
40
+ <div class="opinionstage-section-title"><?php esc_html_e( 'Create', 'social-polls-by-opinionstage' ); ?></div>
41
+ <?php echo esc_html( opinionstage_help_links( __( 'Need help adding items to your site?', 'social-polls-by-opinionstage' ), 'https://help.opinionstage.com/wordpress-plugin/how-to-add-items-to-your-wordpress-site', 'opinionstage-need-help-link' ) ); ?>
42
  </div>
43
  <div class="opinionstage-section-content" style="position: relative;">
44
  <div class="opinionstage-section-raw">
45
  <div class="opinionstage-section-cell opinionstage-icon-cell">
46
+ <div class="os-icon-plugin"><img src="<?php echo esc_url( plugins_url( 'images/poll.png', dirname( __FILE__ ) ) ); ?>" ></div>
47
  </div>
48
  <div class="opinionstage-section-cell opinionstage-description-cell">
49
+ <div class="title"><?php esc_html_e( 'Poll', 'social-polls-by-opinionstage' ); ?></div>
50
+ <div class="example"><?php esc_html_e( 'Get opinions, run contests & competitions', 'social-polls-by-opinionstage' ); ?></div>
51
  </div>
52
  <div class="opinionstage-section-cell opinionstage-btn-cell">
53
+ <?php echo esc_html( opinionstage_create_poll_link( 'opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template' ) ); ?>
54
+ <?php echo esc_html( opinionstage_template_poll_link( 'opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template' ) ); ?>
55
  </div>
56
  </div>
57
  <div class="opinionstage-section-raw">
58
  <div class="opinionstage-section-cell opinionstage-icon-cell">
59
+ <div class="os-icon-plugin"><img src="<?php echo esc_url( plugins_url( 'images/personality.png', dirname( __FILE__ ) ) ); ?>" ></div>
60
  </div>
61
  <div class="opinionstage-section-cell opinionstage-description-cell">
62
+ <div class="title"><?php esc_html_e( 'Personality Quiz', 'social-polls-by-opinionstage' ); ?></div>
63
+ <div class="example"><?php esc_html_e( 'Create a personality test or a product/service selector', 'social-polls-by-opinionstage' ); ?></div>
64
  </div>
65
  <div class="opinionstage-section-cell opinionstage-btn-cell">
66
+ <?php echo esc_html( opinionstage_create_personality_link( 'opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template' ) ); ?>
67
+ <?php echo esc_html( opinionstage_template_personality_quiz_link( 'opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template' ) ); ?>
68
  </div>
69
  </div>
70
  <div class="opinionstage-section-raw">
71
  <div class="opinionstage-section-cell opinionstage-icon-cell">
72
+ <div class="os-icon-plugin"><img src="<?php echo esc_url( plugins_url( 'images/trivia.png', dirname( __FILE__ ) ) ); ?>" ></div>
73
  </div>
74
  <div class="opinionstage-section-cell opinionstage-description-cell">
75
+ <div class="title"><?php esc_html_e( 'Trivia Quiz', 'social-polls-by-opinionstage' ); ?></div>
76
+ <div class="example"><?php esc_html_e( 'Create a knowledge test or assessment', 'social-polls-by-opinionstage' ); ?></div>
77
  </div>
78
  <div class="opinionstage-section-cell opinionstage-btn-cell">
79
+ <?php echo esc_html( opinionstage_create_trivia_link( 'opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template' ) ); ?>
80
+ <?php echo esc_html( opinionstage_template_trivia_link( 'opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template' ) ); ?>
81
  </div>
82
  </div>
83
  <div class="opinionstage-section-raw">
84
  <div class="opinionstage-section-cell opinionstage-icon-cell">
85
+ <div class="os-icon-plugin"><img src="<?php echo esc_url( plugins_url( 'images/survey.png', dirname( __FILE__ ) ) ); ?>" ></div>
86
  </div>
87
  <div class="opinionstage-section-cell opinionstage-description-cell">
88
+ <div class="title"><?php esc_html_e( 'Survey', 'social-polls-by-opinionstage' ); ?></div>
89
+ <div class="example"><?php esc_html_e( 'Gather feedback from your users', 'social-polls-by-opinionstage' ); ?></div>
90
  </div>
91
  <div class="opinionstage-section-cell opinionstage-btn-cell">
92
+ <?php echo esc_html( opinionstage_create_survey_link( 'opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template' ) ); ?>
93
+ <?php echo esc_html( opinionstage_template_survey_link( 'opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template' ) ); ?>
94
  </div>
95
  </div>
96
  <div class="opinionstage-section-raw">
97
  <div class="opinionstage-section-cell opinionstage-icon-cell">
98
+ <div class="os-icon-plugin"><img src="<?php echo esc_url( plugins_url( 'images/form.png', dirname( __FILE__ ) ) ); ?>" ></div>
99
  </div>
100
  <div class="opinionstage-section-cell opinionstage-description-cell">
101
+ <div class="title"><?php esc_html_e( 'Classic Form', 'social-polls-by-opinionstage' ); ?></div>
102
+ <div class="example"><?php esc_html_e( 'Gather information from your users', 'social-polls-by-opinionstage' ); ?></div>
103
  </div>
104
  <div class="opinionstage-section-cell opinionstage-btn-cell">
105
+ <?php echo esc_html( opinionstage_create_form_link( 'opinionstage-blue-btn opinionstage-create-btn os_create_new_btn template' ) ); ?>
106
+ <?php echo esc_html( opinionstage_template_form_link( 'opinionstage-blue-bordered-btn opinionstage-create-btn os_use_template_btn template' ) ); ?>
107
  </div>
108
  </div>
109
  </div>
110
  </div>
111
+ </div>
112
  </div>
113
  </div>
admin/views/view_my_items.php CHANGED
@@ -1,127 +1,125 @@
1
- <?php
2
- // block direct access to plugin PHP files:
3
- defined( 'ABSPATH' ) or die(1); ?>
4
  <style type="text/css">
5
  .content-item-image.quiz{
6
- background-image: url(<?php echo plugins_url('', dirname(__FILE__) ) . '/images/form-not-found.png' ?>);
7
- background-repeat: no-repeat;
8
- background-size: cover;
9
  }
10
  </style>
11
  <div id="opinionstage-content">
12
- <div class="opinionstage-header-wrapper">
13
  <?php if ( $os_client_logged_in ) { ?>
14
  <div class="opinionstage-logo-wrapper">
15
  <div class="opinionstage-logo"></div>
16
- <div class="opinionstage-connectivity-status"><?php echo($os_options["email"]); ?>
17
- <form method="POST" action="<?php echo get_admin_url(null, 'admin.php?page='.OPINIONSTAGE_DISCONNECT_PAGE)?>" class="opinionstage-connect-form">
18
- <button class="opinionstage-disconnect" type="submit">Disconnect</button>
19
  </form>
20
  </div>
21
- </div>
22
  <?php } ?>
23
  </div>
24
  <div id="container" class="opinionstage-dashboard">
25
  <div class="opinionstage-item-view-dashboard">
26
  <div id="opinionstage-section-create" class="opinionstage-dashboard-section">
27
  <div class="opinionstage-section-header">
28
- <div class="opinionstage-section-title">My Items</div>
29
  <div class="opinionstage-header-inner-container">
30
  <div class="opinionstage-header-inner-section">
31
- <a href="https://help.opinionstage.com/wordpress-plugin/how-to-add-items-to-your-wordpress-site" target="_blank" class="">Need help adding items to your site?</a>
32
- <div style="padding: 0px 9px; width: 150px; display: inline-block;">
33
  <select id="itemList">
34
- <option value="all">ALL ITEMS</option>
35
- <option value="poll">POLL</option>
36
- <option value="survey">SURVEY</option>
37
- <option value="trivia">TRIVIA QUIZ</option>
38
- <option value="personality">PERSONALITY QUIZ</option>
39
- <option value="form">FORM</option>
40
  </select>
41
  </div>
42
  <div class="search search-container">
43
  <input id="searchItem" class="std-input" name="search" placeholder="Search" type="text">
44
- </div>
45
- </div>
46
- <a href="<?php echo admin_url( 'admin.php?page=opinionstage-settings' ); ?>" class="opinionstage-connect-btn opinionstage-blue-btn opinionstage-item-create" style="margin-left: 20px; font-weight: 600; padding-left: 0; padding-right: 0;">CREATE</a>
47
  </div>
48
- </div>
 
 
 
49
  </div>
50
- <p class="result_progress" style="display: block; font-size: 16px; text-align: center;">Loading...</p>
51
  <table id="check"></table>
52
- <p class="no_item" style="display: none; font-size: 15px; text-align: center;">No items found</p>
53
- <div id="loadMore" class="btn btn_aqua btn_full-width" style="display: none;">Click for more</div>
54
- <div id="showLess" style="display: none;">Show less</div>
55
  </div>
56
  </div>
57
  </div>
58
  <script type="text/javascript">
59
- jQuery(document).ready(function($){
60
- $.ajax({
61
- url: '<?php echo OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API; ?>?type=all&page=1&per_page=99',
62
  headers: {
63
  'Accept':'application/vnd.api+json',
64
  'Content-Type':'application/vnd.api+json',
65
- 'OSWP-Plugin-Version':'<?php echo OPINIONSTAGE_WIDGET_VERSION ?>',
66
- 'OSWP-Client-Token': '<?php echo opinionstage_user_access_token() ?>'
67
- },
68
- method: 'GET',
69
  dataType: 'json',
70
  success: function(data){
71
  dropdownOptions = data;
72
  if(dropdownOptions.data.length == 0){
73
- var adminUrlCreateLink = "<?php echo admin_url( 'admin.php?page=opinionstage-settings'); ?>";
74
  var viewtext = '<tbody><tr><td><p><span style="font-weight: 600; font-size: 15px; color:#212120;">No items yet..., </span><a href="'+adminUrlCreateLink+'" style="font-weight: 600; font-size: 15px; color:#3499c2;">Add your first item</a></p></td></tr></tbody>';
75
  $('.result_progress').css('display', 'none');
76
  $(viewtext).appendTo('#container table#check');
77
  }else{
78
  for (var i = 0; i < dropdownOptions.data.length; i++) {
79
- var previewBlockOsTitle = dropdownOptions.data[i].attributes['title'];
80
- var previewBlockOsType = dropdownOptions.data[i].attributes['type'];
81
- var previewBlockOsDate = dropdownOptions.data[i].attributes['updated-at'];
82
- previewBlockOsDate = new Date(previewBlockOsDate);
83
  previewBlockOsDate = previewBlockOsDate.toDateString();
84
  var resDateOs = previewBlockOsDate.split(" ");
85
- previewBlockOsDate = resDateOs[2]+' '+resDateOs[1]+' '+resDateOs[3];
86
- var previewBlockOsImageUrl = dropdownOptions.data[i].attributes['image-url'];
87
- var previewBlockOsView = dropdownOptions.data[i].attributes['landing-page-url'];
88
- var previewBlockOsEdit = dropdownOptions.data[i].attributes['edit-url'];
89
- var previewBlockOsStatistics = dropdownOptions.data[i].attributes['stats-url'];
90
- var viewtext = '<tbody id="count"><tr class="settingBorderOs"><td class="image"><a href="'+previewBlockOsView+'" target="_blank"><div class="content-item-image quiz"><img height="90" src="'+previewBlockOsImageUrl+'" width="120"><div class="content-item-label">'+previewBlockOsType+'</div></div></a></td><td class="long"><div style="position: relative;height: 85px;"><a href="'+previewBlockOsEdit+'" class="opinionstage-item-title" target="_blank">'+previewBlockOsTitle+'</a><table><tbody><tr><td><span class="os-icon-plugin icon-os-common-date"></span><div class="label">'+previewBlockOsDate+'</div></td></tr></tbody></table></div></td><td class="action"><div class="opinionstage-item-action-container"><a href="'+previewBlockOsView+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> View </a><a href="'+previewBlockOsEdit+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> Edit </a><a href="'+previewBlockOsStatistics+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> Results </div></a></td></tr></tbody>';
91
- $('.result_progress').css('display', 'none');
92
  $(viewtext).appendTo('#container table#check');
93
- }
94
- }
95
  },
96
  complete: function(data) {
97
  size_li = $("table#check tbody#count").size();
98
  dropdownDataLength = dropdownOptions.data.length;
99
 
100
  loadMore(size_li, dropdownDataLength, "all");
101
- var data = {
102
  'action': 'opinionstage_ajax_item_count',
103
  'oswp_item_count' : dropdownOptions.data.length
104
- };
105
 
106
  jQuery.post(ajaxurl, data, function(response) {
107
  if(response){
108
 
109
  }
110
- });
111
 
112
- jQuery('#itemList').on('change', function() {
113
- var selectedValue = this.value;
114
- var contentLabel = jQuery(".content-item-label");
115
- var item_count = 0;
116
 
117
  jQuery('.no_item').css('display', 'none');
118
- contentLabel.each(function() {
119
- getContainer = jQuery( this ).parent().parent().parent().parent();
120
- if(selectedValue != 'all' && selectedValue != jQuery( this ).text().toLowerCase()){
121
- getContainer.parent().css('display', 'none');
122
- getContainer.parent().removeClass('countItem');
123
- }
124
- else {
125
  jQuery("#searchItem").val('');
126
  getContainer.parent().css('display', 'table-row-group');
127
  getContainer.parent().addClass('countItem');
@@ -129,32 +127,32 @@ defined( 'ABSPATH' ) or die(1); ?>
129
  }
130
  });
131
 
132
- if (item_count == 0) {
133
- jQuery('.no_item').css('display', 'block');
134
- }
135
 
136
- size = $("table#check tbody.countItem").size();
137
- $("#loadMore").fadeOut(500);
138
- loadMore(size, item_count, "filter");
139
  });
140
 
141
  $("#searchItem").on("keyup",function search(e) {
142
- if(e.keyCode == 13) {
143
- var searchItem = $(this).val();
144
- var listTitle = jQuery('td.long a');
145
- var dropdownValue = jQuery('#itemList').val();
146
- var contentList = jQuery(".content-item-label");
147
 
148
- listTitle.each(function() {
149
- var title = jQuery( this ).text().toLowerCase();
150
- outerContainer = jQuery( this ).parent().parent().parent().parent();
151
 
152
- if ( dropdownValue == 'all' ) {
153
- if(!title.includes(searchItem)) {
154
- outerContainer.css('display', 'none');
155
- }
156
- else {
157
- outerContainer.css('display', 'table-row-group');
158
  }
159
  }
160
  else {
@@ -165,27 +163,27 @@ defined( 'ABSPATH' ) or die(1); ?>
165
  outerContainer.css('display', 'none');
166
  }
167
  else {
168
- outerContainer.css('display', 'table-row-group');
169
  }
170
  }
171
  }
172
  });
173
  }
174
- });
175
- }
176
- });
177
  },
178
  error: function(){
179
- console.log(data.statusText);
180
  }
181
  });
182
 
183
 
184
  function loadMore(size, dataLength, item) {
185
  if(dataLength == size && dataLength > 10){
186
- setTimeout(function(){$('#showLess').trigger('click');},500);
187
- }
188
- // Show the div in 5s
189
  var countItemOS = 10;
190
  if(dataLength > countItemOS){
191
  $("#loadMore").delay(2000).fadeIn(500);
@@ -194,28 +192,28 @@ defined( 'ABSPATH' ) or die(1); ?>
194
  x=10;
195
  $('table#check ttbody#count:lt('+x+')').show();
196
  $('#loadMore').click(function () {
197
- x= (x+10 <= size) ? x+10 : size;
198
 
199
- if (item == 'all') {
200
- $('table#check tbody#count:lt('+x+')').show(500);
201
  }
202
  else {
203
  $('table#check tbody#countItem:lt('+x+')').show(500);
204
  }
205
 
206
- if(size == x){
207
  $("#loadMore").hide(500);
208
  }
209
  });
210
  $('#showLess').on('click', null, function () {
211
- x=(x-0<0) ? 10 : x-0;
212
- if (item == 'all') {
213
- $('table#check tbody#count').not(':lt('+x+')').hide();
214
- }
215
  else {
216
  $('table#check tbody#countItem').not(':lt('+x+')').hide();
217
  }
218
- });
219
  }
220
  });
221
  </script>
1
+ <?php
2
+ defined( 'ABSPATH' ) || die(); ?>
 
3
  <style type="text/css">
4
  .content-item-image.quiz{
5
+ background-image: url(<?php echo esc_url( plugins_url( '', dirname( __FILE__ ) ) . '/images/form-not-found.png' ); ?>);
6
+ background-repeat: no-repeat;
7
+ background-size: cover;
8
  }
9
  </style>
10
  <div id="opinionstage-content">
11
+ <div class="opinionstage-header-wrapper">
12
  <?php if ( $os_client_logged_in ) { ?>
13
  <div class="opinionstage-logo-wrapper">
14
  <div class="opinionstage-logo"></div>
15
+ <div class="opinionstage-connectivity-status"><?php echo esc_html( $os_options['email'] ); ?>
16
+ <form method="POST" action="<?php echo esc_url( get_admin_url( null, 'admin.php?page=' . OPINIONSTAGE_DISCONNECT_PAGE ) ); ?>" class="opinionstage-connect-form">
17
+ <button class="opinionstage-disconnect" type="submit" ><?php esc_html_e( 'Disconnect', 'social-polls-by-opinionstage' ); ?></button>
18
  </form>
19
  </div>
20
+ </div>
21
  <?php } ?>
22
  </div>
23
  <div id="container" class="opinionstage-dashboard">
24
  <div class="opinionstage-item-view-dashboard">
25
  <div id="opinionstage-section-create" class="opinionstage-dashboard-section">
26
  <div class="opinionstage-section-header">
27
+ <div class="opinionstage-section-title"><?php esc_html_e( 'My Items', 'social-polls-by-opinionstage' ); ?></div>
28
  <div class="opinionstage-header-inner-container">
29
  <div class="opinionstage-header-inner-section">
30
+ <a href="https://help.opinionstage.com/wordpress-plugin/how-to-add-items-to-your-wordpress-site" target="_blank" ><?php esc_html_e( 'Need help adding items to your site?', 'social-polls-by-opinionstage' ); ?></a>
31
+ <div style="padding: 0 9px; width: 150px; display: inline-block;">
32
  <select id="itemList">
33
+ <option value="all"><?php esc_html_e( 'ALL ITEMS', 'social-polls-by-opinionstage' ); ?></option>
34
+ <option value="poll"><?php esc_html_e( 'POLL', 'social-polls-by-opinionstage' ); ?></option>
35
+ <option value="survey"><?php esc_html_e( 'SURVEY', 'social-polls-by-opinionstage' ); ?></option>
36
+ <option value="trivia"><?php esc_html_e( 'TRIVIA QUIZ', 'social-polls-by-opinionstage' ); ?></option>
37
+ <option value="personality"><?php esc_html_e( 'PERSONALITY QUIZ', 'social-polls-by-opinionstage' ); ?></option>
38
+ <option value="form"><?php esc_html_e( 'CLASSIC FORM', 'social-polls-by-opinionstage' ); ?></option>
39
  </select>
40
  </div>
41
  <div class="search search-container">
42
  <input id="searchItem" class="std-input" name="search" placeholder="Search" type="text">
 
 
 
43
  </div>
44
+ </div>
45
+ <a href="<?php echo esc_url( admin_url( 'admin.php?page=opinionstage-settings' ) ); ?>" class="opinionstage-connect-btn opinionstage-blue-btn opinionstage-item-create" style="margin-left: 20px; font-weight: 600; padding-left: 0; padding-right: 0;"><?php esc_html_e( 'CREATE', 'social-polls-by-opinionstage' ); ?></a>
46
+ </div>
47
+ </div>
48
  </div>
49
+ <p class="result_progress" style="display: block; font-size: 16px; text-align: center;"><?php esc_html_e( 'Loading...', 'social-polls-by-opinionstage' ); ?></p>
50
  <table id="check"></table>
51
+ <p class="no_item" style="display: none; font-size: 15px; text-align: center;"><?php esc_html_e( 'No items found', 'social-polls-by-opinionstage' ); ?></p>
52
+ <div id="loadMore" class="btn btn_aqua btn_full-width" style="display: none;"><?php esc_html_e( 'Click for more', 'social-polls-by-opinionstage' ); ?></div>
53
+ <div id="showLess" style="display: none;"><?php esc_html_e( 'Show less', 'social-polls-by-opinionstage' ); ?></div>
54
  </div>
55
  </div>
56
  </div>
57
  <script type="text/javascript">
58
+ jQuery(document).ready(function($){
59
+ $.ajax({
60
+ url: '<?php echo esc_url( OPINIONSTAGE_CONTENT_POPUP_CLIENT_WIDGETS_API ); ?>?type=all&page=1&per_page=99',
61
  headers: {
62
  'Accept':'application/vnd.api+json',
63
  'Content-Type':'application/vnd.api+json',
64
+ 'OSWP-Plugin-Version':'<?php echo esc_js( OPINIONSTAGE_WIDGET_VERSION ); ?>',
65
+ 'OSWP-Client-Token': '<?php echo esc_js( opinionstage_user_access_token() ); ?>'
66
+ },
67
+ method: 'GET',
68
  dataType: 'json',
69
  success: function(data){
70
  dropdownOptions = data;
71
  if(dropdownOptions.data.length == 0){
72
+ var adminUrlCreateLink = "<?php echo esc_url( admin_url( 'admin.php?page=opinionstage-settings' ) ); ?>";
73
  var viewtext = '<tbody><tr><td><p><span style="font-weight: 600; font-size: 15px; color:#212120;">No items yet..., </span><a href="'+adminUrlCreateLink+'" style="font-weight: 600; font-size: 15px; color:#3499c2;">Add your first item</a></p></td></tr></tbody>';
74
  $('.result_progress').css('display', 'none');
75
  $(viewtext).appendTo('#container table#check');
76
  }else{
77
  for (var i = 0; i < dropdownOptions.data.length; i++) {
78
+ var previewBlockOsTitle = dropdownOptions.data[i].attributes['title'];
79
+ var previewBlockOsType = dropdownOptions.data[i].attributes['type'];
80
+ var previewBlockOsDate = dropdownOptions.data[i].attributes['updated-at'];
81
+ previewBlockOsDate = new Date(previewBlockOsDate);
82
  previewBlockOsDate = previewBlockOsDate.toDateString();
83
  var resDateOs = previewBlockOsDate.split(" ");
84
+ previewBlockOsDate = resDateOs[2]+' '+resDateOs[1]+' '+resDateOs[3];
85
+ var previewBlockOsImageUrl = dropdownOptions.data[i].attributes['image-url'];
86
+ var previewBlockOsView = dropdownOptions.data[i].attributes['landing-page-url'];
87
+ var previewBlockOsEdit = dropdownOptions.data[i].attributes['edit-url'];
88
+ var previewBlockOsStatistics = dropdownOptions.data[i].attributes['stats-url'];
89
+ var viewtext = '<tbody id="count"><tr class="settingBorderOs"><td class="image"><a href="'+previewBlockOsView+'" target="_blank"><div class="content-item-image quiz"><img height="90" src="'+previewBlockOsImageUrl+'" width="120"><div class="content-item-label">'+previewBlockOsType+'</div></div></a></td><td class="long"><div style="position: relative;height: 85px;"><a href="'+previewBlockOsEdit+'" class="opinionstage-item-title" target="_blank">'+previewBlockOsTitle+'</a><table><tbody><tr><td><span class="os-icon-plugin icon-os-common-date"></span><div class="label">'+previewBlockOsDate+'</div></td></tr></tbody></table></div></td><td class="action"><div class="opinionstage-item-action-container"><a href="'+previewBlockOsView+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> View </a><a href="'+previewBlockOsEdit+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> Edit </a><a href="'+previewBlockOsStatistics+'" class="opinionstage-blue-bordered-btn opinionstage-edit-content " target="_blank"> Results </div></a></td></tr></tbody>';
90
+ $('.result_progress').css('display', 'none');
91
  $(viewtext).appendTo('#container table#check');
92
+ }
93
+ }
94
  },
95
  complete: function(data) {
96
  size_li = $("table#check tbody#count").size();
97
  dropdownDataLength = dropdownOptions.data.length;
98
 
99
  loadMore(size_li, dropdownDataLength, "all");
100
+ var data = {
101
  'action': 'opinionstage_ajax_item_count',
102
  'oswp_item_count' : dropdownOptions.data.length
103
+ };
104
 
105
  jQuery.post(ajaxurl, data, function(response) {
106
  if(response){
107
 
108
  }
109
+ });
110
 
111
+ jQuery('#itemList').on('change', function() {
112
+ var selectedValue = this.value;
113
+ var contentLabel = jQuery(".content-item-label");
114
+ var item_count = 0;
115
 
116
  jQuery('.no_item').css('display', 'none');
117
+ contentLabel.each(function () {
118
+ getContainer = jQuery(this).parent().parent().parent().parent();
119
+ if (selectedValue != 'all' && selectedValue != jQuery(this).text().toLowerCase()) {
120
+ getContainer.parent().css('display', 'none');
121
+ getContainer.parent().removeClass('countItem');
122
+ } else {
 
123
  jQuery("#searchItem").val('');
124
  getContainer.parent().css('display', 'table-row-group');
125
  getContainer.parent().addClass('countItem');
127
  }
128
  });
129
 
130
+ if (item_count == 0) {
131
+ jQuery('.no_item').css('display', 'block');
132
+ }
133
 
134
+ size = $("table#check tbody.countItem").size();
135
+ $("#loadMore").fadeOut(500);
136
+ loadMore(size, item_count, "filter");
137
  });
138
 
139
  $("#searchItem").on("keyup",function search(e) {
140
+ if(e.keyCode == 13) {
141
+ var searchItem = $(this).val();
142
+ var listTitle = jQuery('td.long a');
143
+ var dropdownValue = jQuery('#itemList').val();
144
+ var contentList = jQuery(".content-item-label");
145
 
146
+ listTitle.each(function() {
147
+ var title = jQuery( this ).text().toLowerCase();
148
+ outerContainer = jQuery( this ).parent().parent().parent().parent();
149
 
150
+ if ( dropdownValue == 'all' ) {
151
+ if(!title.includes(searchItem)) {
152
+ outerContainer.css('display', 'none');
153
+ }
154
+ else {
155
+ outerContainer.css('display', 'table-row-group');
156
  }
157
  }
158
  else {
163
  outerContainer.css('display', 'none');
164
  }
165
  else {
166
+ outerContainer.css('display', 'table-row-group');
167
  }
168
  }
169
  }
170
  });
171
  }
172
+ });
173
+ }
174
+ });
175
  },
176
  error: function(){
177
+ console.log(data.statusText);
178
  }
179
  });
180
 
181
 
182
  function loadMore(size, dataLength, item) {
183
  if(dataLength == size && dataLength > 10){
184
+ setTimeout(function(){$('#showLess').trigger('click');},500);
185
+ }
186
+ // Show the div in 5s
187
  var countItemOS = 10;
188
  if(dataLength > countItemOS){
189
  $("#loadMore").delay(2000).fadeIn(500);
192
  x=10;
193
  $('table#check ttbody#count:lt('+x+')').show();
194
  $('#loadMore').click(function () {
195
+ x= (x+10 <= size) ? x+10 : size;
196
 
197
+ if (item == 'all') {
198
+ $('table#check tbody#count:lt('+x+')').show(500);
199
  }
200
  else {
201
  $('table#check tbody#countItem:lt('+x+')').show(500);
202
  }
203
 
204
+ if(size == x){
205
  $("#loadMore").hide(500);
206
  }
207
  });
208
  $('#showLess').on('click', null, function () {
209
+ x=(x-0<0) ? 10 : x-0;
210
+ if (item == 'all') {
211
+ $('table#check tbody#count').not(':lt('+x+')').hide();
212
+ }
213
  else {
214
  $('table#check tbody#countItem').not(':lt('+x+')').hide();
215
  }
216
+ });
217
  }
218
  });
219
  </script>
assets/gutenberg/build/index.asset.php CHANGED
@@ -1 +1 @@
1
- <?php return array('dependencies' => array('wp-blocks', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '1e645334cbee233c81a82c81a9ce0809');
1
+ <?php return array('dependencies' => array('wp-blocks', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => 'b0839c5c9b1dfc054b84b6d692a1caac');
assets/gutenberg/build/index.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function r(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(o,i,function(t){return e[t]}.bind(null,i));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t,r){},function(e,t,r){"use strict";r.r(t);var o=r(2),i=r(1),n=r(0),a=(r(3),{widgetType:{type:"string",source:"attribute",attribute:"data-type",selector:"div[data-type]"},embedUrl:{source:"attribute",attribute:"data-test-url",selector:"div[data-test-url]"},lockEmbed:{source:"attribute",attribute:"data-lock-embed",selector:"div[data-lock-embed]"},buttonText:{source:"attribute",attribute:"data-button-text",selector:"div[data-button-text]"},insertItemImage:{source:"attribute",attribute:"data-image-url",selector:"div[data-image-url]"},insertItemOsTitle:{source:"attribute",attribute:"data-title-url",selector:"div[data-title-url]"},insertItemOsView:{source:"attribute",attribute:"data-view-url",selector:"div[data-view-url]"},insertItemOsEdit:{source:"attribute",attribute:"data-edit-url",selector:"div[data-edit-url]"},insertItemOsStatistics:{source:"attribute",attribute:"data-statistics-url",selector:"div[data-statistics-url]"}}),s="opinion-stage",c={html:!1};function l(e){var t=e.name,r=e.className,a=e.attributes,s=e.setAttributes,c=e.clientId,l=(a.widgetType,a.embedUrl),p=(a.lockEmbed,a.buttonText),b=a.insertItemImage,d=a.insertItemOsTitle,m=a.insertItemOsView,g=a.insertItemOsEdit,O=a.insertItemOsStatistics;if("false"===OPINIONSTAGE_GUTENBERG_DATA.userLoggedIn)return Object(n.createElement)("div",{className:r},Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("p",{class:"components-heading"},"Please connect WordPress to Opinion Stage to start adding widgets"),Object(n.createElement)("a",{href:OPINIONSTAGE_GUTENBERG_DATA.loginPageUrl,class:"components-button is-button is-default is-block is-primary"},"Connect")));var y=function(e){switch(e){case"opinion-stage/block-os-poll":return"poll";case"opinion-stage/block-os-survey":return"survey";case"opinion-stage/block-os-trivia":return"trivia";case"opinion-stage/block-os-personality":return"personality";case"opinion-stage/block-os-form":return"form";default:console.warn("unknown block name:",e)}}(t),v=function(e){switch(e){case"poll":return Object(i.__)("Poll");case"survey":return Object(i.__)("Survey");case"trivia":return Object(i.__)("Trivia Quiz");case"personality":return Object(i.__)("Personality Quiz");case"form":return Object(i.__)("Form")}}(y),_=function(e){var t=function(e){switch(e){case"poll":return"poll";case"survey":return"survey";case"trivia":return"trivia";case"personality":return"personality";case"form":return"form"}}(e.type),r={widgetType:t,lockEmbed:!0,buttonText:"Change",embedUrl:e.landingPageUrl.replace(/^https?:\/\/[^/]+\//,"/"),insertItemImage:e.imageUrl,insertItemOsTitle:e.title,insertItemOsView:e.landingPageUrl,insertItemOsEdit:e.editUrl,insertItemOsStatistics:e.statsUrl};if(t===y)s(r);else{var i=Object(o.createBlock)(function(e){switch(e){case"poll":return"opinion-stage/block-os-poll";case"survey":return"opinion-stage/block-os-survey";case"trivia":return"opinion-stage/block-os-trivia";case"personality":return"opinion-stage/block-os-personality";case"form":return"opinion-stage/block-os-form";default:console.warn("unknown block widget type:",e)}}(t));i.attributes=r,wp.data.dispatch("core/block-editor").replaceBlock(c,i)}},f=function(e){OpinionStage.contentPopup.open({preselectWidgetType:u(y),onWidgetSelect:_})},E="".concat(OPINIONSTAGE_GUTENBERG_DATA.createNewWidgetUrl,"&w_type=").concat(function(e){switch(e){case"poll":return"poll";case"survey":return"survey";case"trivia":return"quiz";case"personality":return"outcome";case"form":return"contact_form"}}(y)),j=Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("button",{class:"components-button is-button is-default is-block is-primary",onClick:f},"Select a ",v),Object(n.createElement)("a",{href:E,target:"_blank",class:"components-button is-button is-default is-block is-primary"},"Create a new ",v));return l&&""!==l?"Change"===p&&(j=Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("div",{class:"components-preview__block"},Object(n.createElement)("div",{class:"components-preview__leftBlockImage"},Object(n.createElement)("img",{src:b,alt:d,class:"image"}),Object(n.createElement)("div",{class:"overlay"},Object(n.createElement)("div",{class:"text"},Object(n.createElement)("a",{href:m,target:"_blank"}," View "),Object(n.createElement)("a",{href:g,target:"_blank"}," Edit "),Object(n.createElement)("a",{href:O,target:"_blank"}," Statistics "),Object(n.createElement)("input",{type:"button",value:p,class:"components-button is-button is-default is-large left-align",onClick:f})))),Object(n.createElement)("div",{class:"components-preview__rightBlockContent"},Object(n.createElement)("div",{class:"components-placeholder__label"},v,": ",d))))):s({buttonText:"Embed"}),Object(n.createElement)("div",{className:r},j)}function u(e){switch(e){case"poll":return OpinionStage.contentPopup.WIDGET_POLL;case"survey":return OpinionStage.contentPopup.WIDGET_SURVEY;case"trivia":return OpinionStage.contentPopup.WIDGET_TRIVIA_QUIZ;case"personality":return OpinionStage.contentPopup.WIDGET_PERSONALITY_QUIZ;case"form":return OpinionStage.contentPopup.WIDGET_FORM}}function p(e){var t=e.attributes,r=t.widgetType,o=t.embedUrl,i=t.lockEmbed,a=t.buttonText,s=t.insertItemImage,c=t.insertItemOsTitle,l=t.insertItemOsView,u=t.insertItemOsEdit,p=t.insertItemOsStatistics;return Object(n.createElement)("div",{class:b(r),"data-type":r,"data-image-url":s,"data-title-url":c,"data-view-url":l,"data-statistics-url":p,"data-edit-url":u,"data-test-url":o,"data-lock-embed":i,"data-button-text":a},'[os-widget path="',o,'"]',Object(n.createElement)("span",null))}function b(e){if(!e)return null;switch(e){case"poll":return"os-poll-wrapper";case"survey":return"os-survey-wrapper";case"trivia":return"os-trivia-wrapper";case"personality":return"os-personality-wrapper";case"form":return"os-form-wrapper";default:console.warn("unknown widget type:",e)}}Object(o.registerBlockType)("opinion-stage/block-os-poll",{title:"Poll",icon:"chart-bar",description:Object(i.__)("Embed an Opinion Stage Poll","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("poll","social-polls-by-opinionstage"),Object(i.__)("social poll","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-survey",{title:"Survey",icon:"list-view",description:Object(i.__)("Embed an Opinion Stage Survey","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("survey","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-trivia",{title:"Trivia Quiz",icon:"yes",description:Object(i.__)("Embed an Opinion Stage Trivia Quiz","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("quiz","social-polls-by-opinionstage"),Object(i.__)("trivia","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-personality",{title:"Personality Quiz",icon:"smiley",description:Object(i.__)("Embed an Opinion Stage Personality Quiz","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("personality","social-polls-by-opinionstage"),Object(i.__)("quiz","social-polls-by-opinionstage"),Object(i.__)("outcome","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-form",{title:"Form",icon:"editor-justify",description:Object(i.__)("Embed an Opinion Stage Form","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("form","social-polls-by-opinionstage"),Object(i.__)("contact form","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p})}]);
1
+ !function(e){var t={};function r(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(o,i,function(t){return e[t]}.bind(null,i));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t,r){},function(e,t,r){"use strict";r.r(t);var o=r(2),i=r(1),n=r(0),a=(r(3),{widgetType:{type:"string",source:"attribute",attribute:"data-type",selector:"div[data-type]"},embedUrl:{source:"attribute",attribute:"data-test-url",selector:"div[data-test-url]"},lockEmbed:{source:"attribute",attribute:"data-lock-embed",selector:"div[data-lock-embed]"},buttonText:{source:"attribute",attribute:"data-button-text",selector:"div[data-button-text]"},insertItemImage:{source:"attribute",attribute:"data-image-url",selector:"div[data-image-url]"},insertItemOsTitle:{source:"attribute",attribute:"data-title-url",selector:"div[data-title-url]"},insertItemOsView:{source:"attribute",attribute:"data-view-url",selector:"div[data-view-url]"},insertItemOsEdit:{source:"attribute",attribute:"data-edit-url",selector:"div[data-edit-url]"},insertItemOsStatistics:{source:"attribute",attribute:"data-statistics-url",selector:"div[data-statistics-url]"}}),s="opinion-stage",c={html:!1};function l(e){var t=e.name,r=e.className,a=e.attributes,s=e.setAttributes,c=e.clientId,l=(a.widgetType,a.embedUrl),p=(a.lockEmbed,a.buttonText),b=a.insertItemImage,d=a.insertItemOsTitle,m=a.insertItemOsView,g=a.insertItemOsEdit,O=a.insertItemOsStatistics;if("false"===OPINIONSTAGE_GUTENBERG_DATA.userLoggedIn)return Object(n.createElement)("div",{className:r},Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("p",{class:"components-heading"},"Please connect WordPress to Opinion Stage to start adding widgets"),Object(n.createElement)("a",{href:OPINIONSTAGE_GUTENBERG_DATA.loginPageUrl,class:"components-button is-button is-default is-block is-primary"},"Connect")));var y=function(e){switch(e){case"opinion-stage/block-os-poll":return"poll";case"opinion-stage/block-os-survey":return"survey";case"opinion-stage/block-os-trivia":return"trivia";case"opinion-stage/block-os-personality":return"personality";case"opinion-stage/block-os-form":return"form";default:console.warn("unknown block name:",e)}}(t),v=function(e){switch(e){case"poll":return Object(i.__)("Poll");case"survey":return Object(i.__)("Survey");case"trivia":return Object(i.__)("Trivia Quiz");case"personality":return Object(i.__)("Personality Quiz");case"form":return Object(i.__)("Classic Form")}}(y),_=function(e){var t=function(e){switch(e){case"poll":return"poll";case"survey":return"survey";case"trivia":return"trivia";case"personality":return"personality";case"form":return"form"}}(e.type),r={widgetType:t,lockEmbed:!0,buttonText:"Change",embedUrl:e.landingPageUrl.replace(/^https?:\/\/[^/]+\//,"/"),insertItemImage:e.imageUrl,insertItemOsTitle:e.title,insertItemOsView:e.landingPageUrl,insertItemOsEdit:e.editUrl,insertItemOsStatistics:e.statsUrl};if(t===y)s(r);else{var i=Object(o.createBlock)(function(e){switch(e){case"poll":return"opinion-stage/block-os-poll";case"survey":return"opinion-stage/block-os-survey";case"trivia":return"opinion-stage/block-os-trivia";case"personality":return"opinion-stage/block-os-personality";case"form":return"opinion-stage/block-os-form";default:console.warn("unknown block widget type:",e)}}(t));i.attributes=r,wp.data.dispatch("core/block-editor").replaceBlock(c,i)}},f=function(e){OpinionStage.contentPopup.open({preselectWidgetType:u(y),onWidgetSelect:_})},E="".concat(OPINIONSTAGE_GUTENBERG_DATA.createNewWidgetUrl,"&w_type=").concat(function(e){switch(e){case"poll":return"poll";case"survey":return"survey";case"trivia":return"quiz";case"personality":return"outcome";case"form":return"contact_form"}}(y)),j=Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("button",{class:"components-button is-button is-default is-block is-primary",onClick:f},"Select a ",v),Object(n.createElement)("a",{href:E,target:"_blank",class:"components-button is-button is-default is-block is-primary"},"Create a new ",v));return l&&""!==l?"Change"===p&&(j=Object(n.createElement)("div",{class:"os-widget-wrapper components-placeholder"},Object(n.createElement)("p",{class:"components-heading"},Object(n.createElement)("img",{src:OPINIONSTAGE_GUTENBERG_DATA.brandLogoUrl,alt:""})),Object(n.createElement)("div",{class:"components-preview__block"},Object(n.createElement)("div",{class:"components-preview__leftBlockImage"},Object(n.createElement)("img",{src:b,alt:d,class:"image"}),Object(n.createElement)("div",{class:"overlay"},Object(n.createElement)("div",{class:"text"},Object(n.createElement)("a",{href:m,target:"_blank"}," View "),Object(n.createElement)("a",{href:g,target:"_blank"}," Edit "),Object(n.createElement)("a",{href:O,target:"_blank"}," Statistics "),Object(n.createElement)("input",{type:"button",value:p,class:"components-button is-button is-default is-large left-align",onClick:f})))),Object(n.createElement)("div",{class:"components-preview__rightBlockContent"},Object(n.createElement)("div",{class:"components-placeholder__label"},v,": ",d))))):s({buttonText:"Embed"}),Object(n.createElement)("div",{className:r},j)}function u(e){switch(e){case"poll":return OpinionStage.contentPopup.WIDGET_POLL;case"survey":return OpinionStage.contentPopup.WIDGET_SURVEY;case"trivia":return OpinionStage.contentPopup.WIDGET_TRIVIA_QUIZ;case"personality":return OpinionStage.contentPopup.WIDGET_PERSONALITY_QUIZ;case"form":return OpinionStage.contentPopup.WIDGET_FORM}}function p(e){var t=e.attributes,r=t.widgetType,o=t.embedUrl,i=t.lockEmbed,a=t.buttonText,s=t.insertItemImage,c=t.insertItemOsTitle,l=t.insertItemOsView,u=t.insertItemOsEdit,p=t.insertItemOsStatistics;return Object(n.createElement)("div",{class:b(r),"data-type":r,"data-image-url":s,"data-title-url":c,"data-view-url":l,"data-statistics-url":p,"data-edit-url":u,"data-test-url":o,"data-lock-embed":i,"data-button-text":a},'[os-widget path="',o,'"]',Object(n.createElement)("span",null))}function b(e){if(!e)return null;switch(e){case"poll":return"os-poll-wrapper";case"survey":return"os-survey-wrapper";case"trivia":return"os-trivia-wrapper";case"personality":return"os-personality-wrapper";case"form":return"os-form-wrapper";default:console.warn("unknown widget type:",e)}}Object(o.registerBlockType)("opinion-stage/block-os-poll",{title:"Poll",icon:"chart-bar",description:Object(i.__)("Embed an Opinion Stage Poll","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("poll","social-polls-by-opinionstage"),Object(i.__)("social poll","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-survey",{title:"Survey",icon:"list-view",description:Object(i.__)("Embed an Opinion Stage Survey","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("survey","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-trivia",{title:"Trivia Quiz",icon:"yes",description:Object(i.__)("Embed an Opinion Stage Trivia Quiz","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("quiz","social-polls-by-opinionstage"),Object(i.__)("trivia","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-personality",{title:"Personality Quiz",icon:"smiley",description:Object(i.__)("Embed an Opinion Stage Personality Quiz","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("personality","social-polls-by-opinionstage"),Object(i.__)("quiz","social-polls-by-opinionstage"),Object(i.__)("outcome","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p}),Object(o.registerBlockType)("opinion-stage/block-os-form",{title:"Classic Form",icon:"editor-justify",description:Object(i.__)("Embed an Opinion Stage Form","social-polls-by-opinionstage"),category:s,keywords:[Object(i.__)("form","social-polls-by-opinionstage"),Object(i.__)("contact form","social-polls-by-opinionstage")],supports:c,attributes:a,edit:l,save:p})}]);
assets/gutenberg/src/edit.js CHANGED
@@ -168,7 +168,7 @@ function widgetTitleFromType (widgetType) {
168
  return __('Personality Quiz')
169
  break
170
  case WIDGET_FORM:
171
- return __('Form')
172
  break
173
  }
174
  }
168
  return __('Personality Quiz')
169
  break
170
  case WIDGET_FORM:
171
+ return __('Classic Form')
172
  break
173
  }
174
  }
assets/gutenberg/src/index.js CHANGED
@@ -74,7 +74,7 @@ registerBlockType('opinion-stage/block-os-personality', {
74
  })
75
 
76
  registerBlockType('opinion-stage/block-os-form', {
77
- title: 'Form',
78
  icon: 'editor-justify',
79
  description: __('Embed an Opinion Stage Form', 'social-polls-by-opinionstage'),
80
  category,
74
  })
75
 
76
  registerBlockType('opinion-stage/block-os-form', {
77
+ title: 'Classic Form',
78
  icon: 'editor-justify',
79
  description: __('Embed an Opinion Stage Form', 'social-polls-by-opinionstage'),
80
  category,
includes/class-opinionstagefeedback.php ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit; // Exit if accessed directly.
4
+ }
5
+
6
+ /**
7
+ * Opinionstage feedback.
8
+ *
9
+ * Opinionstage feedback handler class is responsible for feedback modal on
10
+ * disabling plugin.
11
+ *
12
+ * @since 19.7.4
13
+ */
14
+ class OpinionstageFeedback {
15
+
16
+ /**
17
+ * Project token.
18
+ *
19
+ * @since 19.7.4
20
+ * @var string
21
+ */
22
+ private $project_token = '1aef78541d1dc41570207ecaf9ec235a';
23
+
24
+ /**
25
+ * OpinionstageFeedback constructor.
26
+ *
27
+ * @since 19.7.4
28
+ */
29
+ public function __construct() {
30
+ add_action(
31
+ 'current_screen',
32
+ function () {
33
+ if ( ! $this->is_plugins_screen() ) {
34
+ return;
35
+ }
36
+ if ( class_exists( 'Mixpanel' )
37
+ && ! method_exists( 'Mixpanel', 'getInstance' )
38
+ && ! method_exists( 'Mixpanel', 'track' )
39
+ ) {
40
+ return;
41
+ }
42
+
43
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_feedback_dialog_scripts' ) );
44
+ }
45
+ );
46
+
47
+ add_action( 'wp_ajax_opinionstage_deactivate_feedback', array( $this, 'ajax_opinionstage_deactivate_feedback' ) );
48
+ }
49
+
50
+ /**
51
+ * Enqueue feedback dialog scripts.
52
+ *
53
+ * @since 19.7.4
54
+ */
55
+ public function enqueue_feedback_dialog_scripts() {
56
+ add_action( 'admin_footer', array( $this, 'print_deactivate_feedback_dialog' ) );
57
+
58
+ wp_register_script(
59
+ 'opinionstage-admin-feedback',
60
+ plugin_dir_url( OPINIONSTAGE_PLUGIN_FILE ) . 'admin/js/admin-feedback.js',
61
+ array( 'jquery' ),
62
+ OPINIONSTAGE_WIDGET_VERSION,
63
+ true
64
+ );
65
+
66
+ wp_enqueue_script( 'opinionstage-admin-feedback' );
67
+
68
+ wp_register_style(
69
+ 'opinionstage-admin-feedback',
70
+ plugin_dir_url( OPINIONSTAGE_PLUGIN_FILE ) . 'admin/css/admin-feedback.css',
71
+ array(),
72
+ OPINIONSTAGE_WIDGET_VERSION
73
+ );
74
+ wp_enqueue_style( 'opinionstage-admin-feedback' );
75
+ }
76
+
77
+ /**
78
+ * Return answers for deactivate feedback poll.
79
+ *
80
+ * @since 19.7.4
81
+ * @return array[]
82
+ */
83
+ private function get_deactivate_feedback_reasons() {
84
+ return array(
85
+ 'no_longer_needed' => array(
86
+ 'title' => esc_html__( 'I no longer need the plugin', 'social-polls-by-opinionstage' ),
87
+ 'input_placeholder' => '',
88
+ ),
89
+ 'found_a_better_plugin' => array(
90
+ 'title' => esc_html__( 'I found a better plugin', 'social-polls-by-opinionstage' ),
91
+ 'input_placeholder' => esc_html__( 'Please share which plugin', 'social-polls-by-opinionstage' ),
92
+ ),
93
+ 'couldnt_get_the_plugin_to_work' => array(
94
+ 'title' => esc_html__( 'I couldn\'t get the plugin to work', 'social-polls-by-opinionstage' ),
95
+ 'input_placeholder' => esc_html__( 'What was the problem', 'social-polls-by-opinionstage' ),
96
+ ),
97
+ 'temporary_deactivation' => array(
98
+ 'title' => esc_html__( 'It\'s a temporary deactivation', 'social-polls-by-opinionstage' ),
99
+ 'input_placeholder' => '',
100
+ ),
101
+ 'other' => array(
102
+ 'title' => esc_html__( 'Other', 'social-polls-by-opinionstage' ),
103
+ 'input_placeholder' => esc_html__( 'Please share the reason', 'social-polls-by-opinionstage' ),
104
+ ),
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Print deactivate feedback modal.
110
+ *
111
+ * @since 19.7.4
112
+ */
113
+ public function print_deactivate_feedback_dialog() {
114
+ $deactivate_reasons = $this->get_deactivate_feedback_reasons();
115
+ ?>
116
+ <div class="opinionstage-dialog-box-wrapper" id="opinionistage-deactivate-feedback-modal" >
117
+ <div class="opinionstage-dialog-box-content">
118
+ <div class="opinionstage-deactivate-feedback-dialog-header">
119
+ <img src="<?php echo esc_url( plugins_url( 'admin/images/os-icon.png', plugin_dir_path( __FILE__ ) ) ); ?>" class="opinionstage-modal-logo" >
120
+ <span class="opinionstage-modal-header"><?php esc_html_e( 'Quick Feedback', 'social-polls-by-opinionstage' ); ?></span>
121
+ <span id="opinionstage-dialog-close" class="opinionstage-close"></span>
122
+ </div>
123
+ <div class="opinionstage-dialog-message">
124
+ <form id="opinionstage-deactivate-feedback-dialog-form" method="post">
125
+ <?php
126
+ wp_nonce_field( '_opinionstage_deactivate_feedback_nonce' );
127
+ ?>
128
+ <input type="hidden" name="action" value="opinionstage_deactivate_feedback" />
129
+
130
+ <div class="opinionstage-deactivate-feedback-dialog-form-caption"><?php esc_html_e( 'Please share why you are disabling Opinion Stage:', 'social-polls-by-opinionstage' ); ?></div>
131
+ <div class="opinionstage-choices-wrapper">
132
+ <?php foreach ( $deactivate_reasons as $reason_key => $reason ) : ?>
133
+ <div class="opinionstage-deactivate-feedback-dialog-input-wrapper">
134
+ <input id="opinionstage-deactivate-feedback-<?php echo esc_attr( $reason_key ); ?>" class="opinionstage-deactivate-feedback-dialog-input" type="radio" name="reason_key" value="<?php echo esc_attr( $reason_key ); ?>" />
135
+ <label for="opinionstage-deactivate-feedback-<?php echo esc_attr( $reason_key ); ?>" ><?php echo esc_html( $reason['title'] ); ?></label>
136
+ <?php if ( ! empty( $reason['input_placeholder'] ) ) : ?>
137
+ <input class="opinionstage-feedback-text" type="text" name="reason_<?php echo esc_attr( $reason_key ); ?>" placeholder="<?php echo esc_attr( $reason['input_placeholder'] ); ?>" />
138
+ <?php endif; ?>
139
+ <?php if ( ! empty( $reason['alert'] ) ) : ?>
140
+ <div><?php echo esc_html( $reason['alert'] ); ?></div>
141
+ <?php endif; ?>
142
+ </div>
143
+ <?php endforeach; ?>
144
+ </div>
145
+ </form>
146
+ </div>
147
+ <div class="opinionstage-dialog-buttons">
148
+ <button id="opinionstage-dialog-submit" class="opinionstage-dialog-submit"><div class="opinionstage-loading-ring"></div><?php esc_html_e( 'Submit & Deactivate', 'social-polls-by-opinionstage' ); ?></button>
149
+ <button id="opinionstage-dialog-skip" class="opinionstage-dialog-skip"><?php esc_html_e( 'Skip & Deactivate', 'social-polls-by-opinionstage' ); ?></button>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ <?php
154
+ }
155
+
156
+ /**
157
+ * Ajax opinionstage deactivate feedback.
158
+ *
159
+ * @since 19.7.4
160
+ */
161
+ public function ajax_opinionstage_deactivate_feedback() {
162
+ if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), '_opinionstage_deactivate_feedback_nonce' ) ) {
163
+ wp_send_json_error();
164
+ }
165
+
166
+ $reason = '';
167
+
168
+ if ( ! empty( $_POST['reason_key'] ) ) {
169
+ $reason = sanitize_text_field( wp_unslash( $_POST['reason_key'] ) );
170
+ }
171
+
172
+ $possible_reasons = $this->get_deactivate_feedback_reasons();
173
+
174
+ if ( key_exists( $reason, $possible_reasons ) ) {
175
+ $reason_text_key = '';
176
+ $reason_text = '';
177
+ if ( isset( $_POST[ 'reason_' . $reason ] ) && trim( sanitize_text_field( wp_unslash( $_POST[ 'reason_' . $reason ] ) ) ) !== '' && ! empty( $possible_reasons[ $reason ]['input_placeholder'] ) ) {
178
+ $reason_text_key = 'reason_' . $reason;
179
+ $reason_text = sanitize_text_field( wp_unslash( $_POST[ 'reason_' . $reason ] ) );
180
+ }
181
+
182
+ $data = array(
183
+ 'reason' => $reason,
184
+ 'plugin_version' => OPINIONSTAGE_WIDGET_VERSION,
185
+ 'wp_version' => get_bloginfo( 'version' ),
186
+ 'site_lang' => get_bloginfo( 'language' ),
187
+ );
188
+
189
+ if ( '' !== $reason_text ) {
190
+ $data[ $reason_text_key ] = $reason_text;
191
+ }
192
+
193
+ if ( ! class_exists( 'Mixpanel' ) ) {
194
+ require_once plugin_dir_path( __FILE__ ) . 'mixpanel-php/lib/Mixpanel.php';
195
+ } else if ( ! method_exists( 'Mixpanel', 'getInstance' ) || ! method_exists( 'Mixpanel', 'track' ) ) {
196
+ wp_send_json_error();
197
+ }
198
+ try {
199
+ $mp = Mixpanel::getInstance( $this->project_token );
200
+ $mp->track( 'plugin_disabled', $data );
201
+ } catch ( Exception $e ) {
202
+ wp_send_json_error();
203
+ }
204
+
205
+ wp_send_json_success();
206
+ }
207
+ wp_send_json_error();
208
+ }
209
+
210
+ /**
211
+ * Determine if current page is plugins page
212
+ *
213
+ * @since 19.7.4
214
+ * @return bool
215
+ */
216
+ private function is_plugins_screen() {
217
+ return in_array( get_current_screen()->id, array( 'plugins', 'plugins-network' ), true );
218
+ }
219
+ }
220
+
221
+ $opinionstage_feedback = new OpinionstageFeedback();
includes/mixpanel-php/lib/Base/MixpanelBase.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This a Base class which all Mixpanel classes extend from to provide some very basic
5
+ * debugging and logging functionality. It also serves to persist $_options across the library.
6
+ *
7
+ */
8
+ class Base_MixpanelBase {
9
+
10
+
11
+ /**
12
+ * Default options that can be overridden via the $options constructor arg
13
+ * @var array
14
+ */
15
+ private $_defaults = array(
16
+ "max_batch_size" => 50, // the max batch size Mixpanel will accept is 50,
17
+ "max_queue_size" => 1000, // the max num of items to hold in memory before flushing
18
+ "debug" => false, // enable/disable debug mode
19
+ "consumer" => "curl", // which consumer to use
20
+ "host" => "api.mixpanel.com", // the host name for api calls
21
+ "events_endpoint" => "/track", // host relative endpoint for events
22
+ "people_endpoint" => "/engage", // host relative endpoint for people updates
23
+ "use_ssl" => true, // use ssl when available
24
+ "error_callback" => null // callback to use on consumption failures
25
+ );
26
+
27
+
28
+ /**
29
+ * An array of options to be used by the Mixpanel library.
30
+ * @var array
31
+ */
32
+ protected $_options = array();
33
+
34
+
35
+ /**
36
+ * Construct a new MixpanelBase object and merge custom options with defaults
37
+ * @param array $options
38
+ */
39
+ public function __construct($options = array()) {
40
+ $options = array_merge($this->_defaults, $options);
41
+ $this->_options = $options;
42
+ }
43
+
44
+
45
+ /**
46
+ * Log a message to PHP's error log
47
+ * @param $msg
48
+ */
49
+ protected function _log($msg) {
50
+ $arr = debug_backtrace();
51
+ $class = $arr[0]['class'];
52
+ $line = $arr[0]['line'];
53
+ error_log ( "[ $class - line $line ] : " . $msg );
54
+ }
55
+
56
+
57
+ /**
58
+ * Returns true if in debug mode, false if in production mode
59
+ * @return bool
60
+ */
61
+ protected function _debug() {
62
+ return array_key_exists("debug", $this->_options) && $this->_options["debug"] == true;
63
+ }
64
+
65
+ }
includes/mixpanel-php/lib/ConsumerStrategies/AbstractConsumer.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
3
+
4
+ /**
5
+ * Provides some base methods for use by a Consumer implementation
6
+ */
7
+ abstract class ConsumerStrategies_AbstractConsumer extends Base_MixpanelBase {
8
+
9
+ /**
10
+ * Creates a new AbstractConsumer
11
+ * @param array $options
12
+ */
13
+ function __construct($options = array()) {
14
+
15
+ parent::__construct($options);
16
+
17
+ if ($this->_debug()) {
18
+ $this->_log("Instantiated new Consumer");
19
+ }
20
+
21
+ }
22
+
23
+ /**
24
+ * Encode an array to be persisted
25
+ * @param array $params
26
+ * @return string
27
+ */
28
+ protected function _encode($params) {
29
+ return base64_encode(json_encode($params));
30
+ }
31
+
32
+ /**
33
+ * Handles errors that occur in a consumer
34
+ * @param $code
35
+ * @param $msg
36
+ */
37
+ protected function _handleError($code, $msg) {
38
+ if (isset($this->_options['error_callback'])) {
39
+ $handler = $this->_options['error_callback'];
40
+ call_user_func($handler, $code, $msg);
41
+ }
42
+
43
+ if ($this->_debug()) {
44
+ $arr = debug_backtrace();
45
+ $class = get_class($arr[0]['object']);
46
+ $line = $arr[0]['line'];
47
+ error_log ( "[ $class - line $line ] : " . print_r($msg, true) );
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Number of requests/batches that will be processed in parallel.
53
+ * @return int
54
+ */
55
+ public function getNumThreads() {
56
+ return 1;
57
+ }
58
+
59
+ /**
60
+ * Persist a batch of messages in whatever way the implementer sees fit
61
+ * @param array $batch an array of messages to consume
62
+ * @return boolean success or fail
63
+ */
64
+ abstract function persist($batch);
65
+ }
includes/mixpanel-php/lib/ConsumerStrategies/CurlConsumer.php ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/AbstractConsumer.php");
3
+
4
+ /**
5
+ * Consumes messages and sends them to a host/endpoint using cURL
6
+ */
7
+ class ConsumerStrategies_CurlConsumer extends ConsumerStrategies_AbstractConsumer {
8
+
9
+ /**
10
+ * @var string the host to connect to (e.g. api.mixpanel.com)
11
+ */
12
+ protected $_host;
13
+
14
+
15
+ /**
16
+ * @var string the host-relative endpoint to write to (e.g. /engage)
17
+ */
18
+ protected $_endpoint;
19
+
20
+
21
+ /**
22
+ * @var int connect_timeout The number of seconds to wait while trying to connect. Default is 5 seconds.
23
+ */
24
+ protected $_connect_timeout;
25
+
26
+
27
+ /**
28
+ * @var int timeout The maximum number of seconds to allow cURL call to execute. Default is 30 seconds.
29
+ */
30
+ protected $_timeout;
31
+
32
+
33
+ /**
34
+ * @var string the protocol to use for the cURL connection
35
+ */
36
+ protected $_protocol;
37
+
38
+
39
+ /**
40
+ * @var bool|null true to fork the cURL process (using exec) or false to use PHP's cURL extension. false by default
41
+ */
42
+ protected $_fork = null;
43
+
44
+
45
+ /**
46
+ * @var int number of cURL requests to run in parallel. 1 by default
47
+ */
48
+ protected $_num_threads;
49
+
50
+
51
+ /**
52
+ * Creates a new CurlConsumer and assigns properties from the $options array
53
+ * @param array $options
54
+ * @throws Exception
55
+ */
56
+ function __construct($options) {
57
+ parent::__construct($options);
58
+
59
+ $this->_host = $options['host'];
60
+ $this->_endpoint = $options['endpoint'];
61
+ $this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
62
+ $this->_timeout = array_key_exists('timeout', $options) ? $options['timeout'] : 30;
63
+ $this->_protocol = array_key_exists('use_ssl', $options) && $options['use_ssl'] == true ? "https" : "http";
64
+ $this->_fork = array_key_exists('fork', $options) ? ($options['fork'] == true) : false;
65
+ $this->_num_threads = array_key_exists('num_threads', $options) ? max(1, intval($options['num_threads'])) : 1;
66
+
67
+ // ensure the environment is workable for the given settings
68
+ if ($this->_fork == true) {
69
+ $exists = function_exists('exec');
70
+ if (!$exists) {
71
+ throw new Exception('The "exec" function must exist to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
72
+ }
73
+ $disabled = explode(', ', ini_get('disable_functions'));
74
+ $enabled = !in_array('exec', $disabled);
75
+ if (!$enabled) {
76
+ throw new Exception('The "exec" function must be enabled to use the cURL consumer in "fork" mode. Try setting fork = false or use another consumer.');
77
+ }
78
+ } else {
79
+ if (!function_exists('curl_init')) {
80
+ throw new Exception('The cURL PHP extension is required to use the cURL consumer with fork = false. Try setting fork = true or use another consumer.');
81
+ }
82
+ }
83
+ }
84
+
85
+
86
+ /**
87
+ * Write to the given host/endpoint using either a forked cURL process or using PHP's cURL extension
88
+ * @param array $batch
89
+ * @return bool
90
+ */
91
+ public function persist($batch) {
92
+ if (count($batch) > 0) {
93
+ $url = $this->_protocol . "://" . $this->_host . $this->_endpoint;
94
+ if ($this->_fork) {
95
+ $data = "data=" . $this->_encode($batch);
96
+ return $this->_execute_forked($url, $data);
97
+ } else {
98
+ return $this->_execute($url, $batch);
99
+ }
100
+ } else {
101
+ return true;
102
+ }
103
+ }
104
+
105
+
106
+ /**
107
+ * Write using the cURL php extension
108
+ * @param $url
109
+ * @param $batch
110
+ * @return bool
111
+ */
112
+ protected function _execute($url, $batch) {
113
+ if ($this->_debug()) {
114
+ $this->_log("Making blocking cURL call to $url");
115
+ }
116
+
117
+ $mh = curl_multi_init();
118
+ $chs = array();
119
+
120
+ $batch_size = ceil(count($batch) / $this->_num_threads);
121
+ for ($i=0; $i<$this->_num_threads && !empty($batch); $i++) {
122
+ $ch = curl_init();
123
+ $chs[] = $ch;
124
+ $data = "data=" . $this->_encode(array_splice($batch, 0, $batch_size));
125
+ curl_setopt($ch, CURLOPT_URL, $url);
126
+ curl_setopt($ch, CURLOPT_HEADER, 0);
127
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->_connect_timeout);
128
+ curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
129
+ curl_setopt($ch, CURLOPT_POST, 1);
130
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
131
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
132
+ curl_multi_add_handle($mh,$ch);
133
+ }
134
+
135
+ do {
136
+ curl_multi_exec($mh, $running);
137
+ curl_multi_select($mh);
138
+ } while ($running > 0);
139
+
140
+ $info = curl_multi_info_read($mh);
141
+
142
+ $error = false;
143
+ foreach ($chs as $ch) {
144
+ $response = curl_multi_getcontent($ch);
145
+ if (false === $response) {
146
+ $this->_handleError(curl_errno($ch), curl_error($ch));
147
+ $error = true;
148
+ }
149
+ elseif ("1" != trim($response)) {
150
+ $this->_handleError(0, $response);
151
+ $error = true;
152
+ }
153
+ curl_multi_remove_handle($mh, $ch);
154
+ }
155
+
156
+ if (CURLE_OK != $info['result']) {
157
+ $this->_handleError($info['result'], "cURL error with code=".$info['result']);
158
+ $error = true;
159
+ }
160
+
161
+ curl_multi_close($mh);
162
+ return !$error;
163
+ }
164
+
165
+
166
+ /**
167
+ * Write using a forked cURL process
168
+ * @param $url
169
+ * @param $data
170
+ * @return bool
171
+ */
172
+ protected function _execute_forked($url, $data) {
173
+
174
+ if ($this->_debug()) {
175
+ $this->_log("Making forked cURL call to $url");
176
+ }
177
+
178
+ $exec = 'curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d ' . $data . ' "' . $url . '"';
179
+
180
+ if(!$this->_debug()) {
181
+ $exec .= " >/dev/null 2>&1 &";
182
+ }
183
+
184
+ exec($exec, $output, $return_var);
185
+
186
+ if ($return_var != 0) {
187
+ $this->_handleError($return_var, $output);
188
+ }
189
+
190
+ return $return_var == 0;
191
+ }
192
+
193
+ /**
194
+ * @return int
195
+ */
196
+ public function getConnectTimeout()
197
+ {
198
+ return $this->_connect_timeout;
199
+ }
200
+
201
+ /**
202
+ * @return string
203
+ */
204
+ public function getEndpoint()
205
+ {
206
+ return $this->_endpoint;
207
+ }
208
+
209
+ /**
210
+ * @return bool|null
211
+ */
212
+ public function getFork()
213
+ {
214
+ return $this->_fork;
215
+ }
216
+
217
+ /**
218
+ * @return string
219
+ */
220
+ public function getHost()
221
+ {
222
+ return $this->_host;
223
+ }
224
+
225
+ /**
226
+ * @return array
227
+ */
228
+ public function getOptions()
229
+ {
230
+ return $this->_options;
231
+ }
232
+
233
+ /**
234
+ * @return string
235
+ */
236
+ public function getProtocol()
237
+ {
238
+ return $this->_protocol;
239
+ }
240
+
241
+ /**
242
+ * @return int
243
+ */
244
+ public function getTimeout()
245
+ {
246
+ return $this->_timeout;
247
+ }
248
+
249
+
250
+ /**
251
+ * Number of requests/batches that will be processed in parallel using curl_multi_exec.
252
+ * @return int
253
+ */
254
+ public function getNumThreads() {
255
+ return $this->_num_threads;
256
+ }
257
+ }
includes/mixpanel-php/lib/ConsumerStrategies/FileConsumer.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/AbstractConsumer.php");
3
+ /**
4
+ * Consumes messages and writes them to a file
5
+ */
6
+ class ConsumerStrategies_FileConsumer extends ConsumerStrategies_AbstractConsumer {
7
+
8
+ /**
9
+ * @var string path to a file that we want to write the messages to
10
+ */
11
+ private $_file;
12
+
13
+
14
+ /**
15
+ * Creates a new FileConsumer and assigns properties from the $options array
16
+ * @param array $options
17
+ */
18
+ function __construct($options) {
19
+ parent::__construct($options);
20
+
21
+ // what file to write to?
22
+ $this->_file = array_key_exists("file", $options) ? $options['file'] : dirname(__FILE__)."/../../messages.txt";
23
+ }
24
+
25
+
26
+ /**
27
+ * Append $batch to a file
28
+ * @param array $batch
29
+ * @return bool
30
+ */
31
+ public function persist($batch) {
32
+ if (count($batch) > 0) {
33
+ return file_put_contents($this->_file, json_encode($batch)."\n", FILE_APPEND | LOCK_EX) !== false;
34
+ } else {
35
+ return true;
36
+ }
37
+ }
38
+ }
includes/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Portions of this class were borrowed from
4
+ * https://github.com/segmentio/analytics-php/blob/master/lib/Analytics/Consumer/Socket.php.
5
+ * Thanks for the work!
6
+ *
7
+ * WWWWWW||WWWWWW
8
+ * W W W||W W W
9
+ * ||
10
+ * ( OO )__________
11
+ * / | \
12
+ * /o o| MIT \
13
+ * \___/||_||__||_|| *
14
+ * || || || ||
15
+ * _||_|| _||_||
16
+ * (__|__|(__|__|
17
+ * (The MIT License)
18
+ *
19
+ * Copyright (c) 2013 Segment.io Inc. friends@segment.io
20
+ *
21
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
22
+ * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the
23
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
24
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
25
+ *
26
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
27
+ * Software.
28
+ *
29
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
30
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
31
+ * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
32
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
+ */
34
+ require_once(dirname(__FILE__) . "/AbstractConsumer.php");
35
+
36
+ /**
37
+ * Consumes messages and writes them to host/endpoint using a persistent socket
38
+ */
39
+ class ConsumerStrategies_SocketConsumer extends ConsumerStrategies_AbstractConsumer {
40
+
41
+ /**
42
+ * @var string the host to connect to (e.g. api.mixpanel.com)
43
+ */
44
+ private $_host;
45
+
46
+
47
+ /**
48
+ * @var string the host-relative endpoint to write to (e.g. /engage)
49
+ */
50
+ private $_endpoint;
51
+
52
+
53
+ /**
54
+ * @var int connect_timeout the socket connection timeout in seconds
55
+ */
56
+ private $_connect_timeout;
57
+
58
+
59
+ /**
60
+ * @var string the protocol to use for the socket connection
61
+ */
62
+ private $_protocol;
63
+
64
+
65
+ /**
66
+ * @var resource holds the socket resource
67
+ */
68
+ private $_socket;
69
+
70
+ /**
71
+ * @var bool whether or not to wait for a response
72
+ */
73
+ private $_async;
74
+
75
+
76
+ /**
77
+ * Creates a new SocketConsumer and assigns properties from the $options array
78
+ * @param array $options
79
+ */
80
+ public function __construct($options = array()) {
81
+ parent::__construct($options);
82
+
83
+
84
+ $this->_host = $options['host'];
85
+ $this->_endpoint = $options['endpoint'];
86
+ $this->_connect_timeout = array_key_exists('connect_timeout', $options) ? $options['connect_timeout'] : 5;
87
+ $this->_async = array_key_exists('async', $options) && $options['async'] === false ? false : true;
88
+
89
+ if (array_key_exists('use_ssl', $options) && $options['use_ssl'] == true) {
90
+ $this->_protocol = "ssl";
91
+ $this->_port = 443;
92
+ } else {
93
+ $this->_protocol = "tcp";
94
+ $this->_port = 80;
95
+ }
96
+ }
97
+
98
+
99
+ /**
100
+ * Write using a persistent socket connection.
101
+ * @param array $batch
102
+ * @return bool
103
+ */
104
+ public function persist($batch) {
105
+
106
+ $socket = $this->_getSocket();
107
+ if (!is_resource($socket)) {
108
+ return false;
109
+ }
110
+
111
+ $data = "data=".$this->_encode($batch);
112
+
113
+ $body = "";
114
+ $body.= "POST ".$this->_endpoint." HTTP/1.1\r\n";
115
+ $body.= "Host: " . $this->_host . "\r\n";
116
+ $body.= "Content-Type: application/x-www-form-urlencoded\r\n";
117
+ $body.= "Accept: application/json\r\n";
118
+ $body.= "Content-length: " . strlen($data) . "\r\n";
119
+ $body.= "\r\n";
120
+ $body.= $data;
121
+
122
+ return $this->_write($socket, $body);
123
+ }
124
+
125
+
126
+ /**
127
+ * Return cached socket if open or create a new persistent socket
128
+ * @return bool|resource
129
+ */
130
+ private function _getSocket() {
131
+ if(is_resource($this->_socket)) {
132
+
133
+ if ($this->_debug()) {
134
+ $this->_log("Using existing socket");
135
+ }
136
+
137
+ return $this->_socket;
138
+ } else {
139
+
140
+ if ($this->_debug()) {
141
+ $this->_log("Creating new socket at ".time());
142
+ }
143
+
144
+ return $this->_createSocket();
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Attempt to open a new socket connection, cache it, and return the resource
150
+ * @param bool $retry
151
+ * @return bool|resource
152
+ */
153
+ private function _createSocket($retry = true) {
154
+ try {
155
+ $socket = pfsockopen($this->_protocol . "://" . $this->_host, $this->_port, $err_no, $err_msg, $this->_connect_timeout);
156
+
157
+ if ($this->_debug()) {
158
+ $this->_log("Opening socket connection to " . $this->_protocol . "://" . $this->_host . ":" . $this->_port);
159
+ }
160
+
161
+ if ($err_no != 0) {
162
+ $this->_handleError($err_no, $err_msg);
163
+ return $retry == true ? $this->_createSocket(false) : false;
164
+ } else {
165
+ // cache the socket
166
+ $this->_socket = $socket;
167
+ return $socket;
168
+ }
169
+
170
+ } catch (Exception $e) {
171
+ $this->_handleError($e->getCode(), $e->getMessage());
172
+ return $retry == true ? $this->_createSocket(false) : false;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Attempt to close and dereference a socket resource
178
+ */
179
+ private function _destroySocket() {
180
+ $socket = $this->_socket;
181
+ $this->_socket = null;
182
+ fclose($socket);
183
+ }
184
+
185
+
186
+ /**
187
+ * Write $data through the given $socket
188
+ * @param $socket
189
+ * @param $data
190
+ * @param bool $retry
191
+ * @return bool
192
+ */
193
+ private function _write($socket, $data, $retry = true) {
194
+
195
+ $bytes_sent = 0;
196
+ $bytes_total = strlen($data);
197
+ $socket_closed = false;
198
+ $success = true;
199
+ $max_bytes_per_write = 8192;
200
+
201
+ // if we have no data to write just return true
202
+ if ($bytes_total == 0) {
203
+ return true;
204
+ }
205
+
206
+ // try to write the data
207
+ while (!$socket_closed && $bytes_sent < $bytes_total) {
208
+
209
+ try {
210
+ $bytes = fwrite($socket, $data, $max_bytes_per_write);
211
+
212
+ if ($this->_debug()) {
213
+ $this->_log("Socket wrote ".$bytes." bytes");
214
+ }
215
+
216
+ // if we actually wrote data, then remove the written portion from $data left to write
217
+ if ($bytes > 0) {
218
+ $data = substr($data, $max_bytes_per_write);
219
+ }
220
+
221
+ } catch (Exception $e) {
222
+ $this->_handleError($e->getCode(), $e->getMessage());
223
+ $socket_closed = true;
224
+ }
225
+
226
+ if (isset($bytes) && $bytes) {
227
+ $bytes_sent += $bytes;
228
+ } else {
229
+ $socket_closed = true;
230
+ }
231
+ }
232
+
233
+ // create a new socket if the current one is closed and retry the message
234
+ if ($socket_closed) {
235
+
236
+ $this->_destroySocket();
237
+
238
+ if ($retry) {
239
+ if ($this->_debug()) {
240
+ $this->_log("Retrying socket write...");
241
+ }
242
+ $socket = $this->_getSocket();
243
+ if ($socket) return $this->_write($socket, $data, false);
244
+ }
245
+
246
+ return false;
247
+ }
248
+
249
+
250
+ // only wait for the response in debug mode or if we explicitly want to be synchronous
251
+ if ($this->_debug() || !$this->_async) {
252
+ $res = $this->handleResponse(fread($socket, 2048));
253
+ if ($res["status"] != "200") {
254
+ $this->_handleError($res["status"], $res["body"]);
255
+ $success = false;
256
+ }
257
+ }
258
+
259
+ return $success;
260
+ }
261
+
262
+
263
+ /**
264
+ * Parse the response from a socket write (only used for debugging)
265
+ * @param $response
266
+ * @return array
267
+ */
268
+ private function handleResponse($response) {
269
+
270
+ $lines = explode("\n", $response);
271
+
272
+ // extract headers
273
+ $headers = array();
274
+ foreach($lines as $line) {
275
+ $kvsplit = explode(":", $line);
276
+ if (count($kvsplit) == 2) {
277
+ $header = $kvsplit[0];
278
+ $value = $kvsplit[1];
279
+ $headers[$header] = trim($value);
280
+ }
281
+
282
+ }
283
+
284
+ // extract status
285
+ $line_one_exploded = explode(" ", $lines[0]);
286
+ $status = $line_one_exploded[1];
287
+
288
+ // extract body
289
+ $body = $lines[count($lines) - 1];
290
+
291
+ // if the connection has been closed lets kill the socket
292
+ if (array_key_exists("Connection", $headers) and $headers['Connection'] == "close") {
293
+ $this->_destroySocket();
294
+ if ($this->_debug()) {
295
+ $this->_log("Server told us connection closed so lets destroy the socket so it'll reconnect on next call");
296
+ }
297
+ }
298
+
299
+ $ret = array(
300
+ "status" => $status,
301
+ "body" => $body,
302
+ );
303
+
304
+ return $ret;
305
+ }
306
+
307
+
308
+ }
includes/mixpanel-php/lib/Mixpanel.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once(dirname(__FILE__) . "/Base/MixpanelBase.php");
4
+ require_once(dirname(__FILE__) . "/Producers/MixpanelPeople.php");
5
+ require_once(dirname(__FILE__) . "/Producers/MixpanelEvents.php");
6
+
7
+ /**
8
+ * This is the main class for the Mixpanel PHP Library which provides all of the methods you need to track events and
9
+ * create/update profiles.
10
+ *
11
+ * Architecture
12
+ * -------------
13
+ *
14
+ * This library is built such that all messages are buffered in an in-memory "queue"
15
+ * The queue will be automatically flushed at the end of every request. Alternatively, you can call "flush()" manually
16
+ * at any time. Flushed messages will be passed to a Consumer's "persist" method. The library comes with a handful of
17
+ * Consumers. The "CurlConsumer" is used by default which will send the messages to Mixpanel using forked cURL processes.
18
+ * You can implement your own custom Consumer to customize how a message is sent to Mixpanel. This can be useful when
19
+ * you want to put messages onto a distributed queue (such as ActiveMQ or Kestrel) instead of writing to Mixpanel in
20
+ * the user thread.
21
+ *
22
+ * Options
23
+ * -------------
24
+ *
25
+ * <table width="100%" cellpadding="5">
26
+ * <tr>
27
+ * <th>Option</th>
28
+ * <th>Description</th>
29
+ * <th>Default</th>
30
+ * </tr>
31
+ * <tr>
32
+ * <td>max_queue_size</td>
33
+ * <td>The maximum number of items to buffer in memory before flushing</td>
34
+ * <td>1000</td>
35
+ * </tr>
36
+ * <tr>
37
+ * <td>debug</td>
38
+ * <td>Enable/disable debug mode</td>
39
+ * <td>false</td>
40
+ * </tr>
41
+ * <tr>
42
+ * <td>consumer</td>
43
+ * <td>The consumer to use for writing messages</td>
44
+ * <td>curl</td>
45
+ * </tr>
46
+ * <tr>
47
+ * <td>consumers</td>
48
+ * <td>An array of custom consumers in the format array(consumer_key => class_name)</td>
49
+ * <td>null</td>
50
+ * </tr>
51
+ * <tr>
52
+ * <td>host</td>
53
+ * <td>The host name for api calls (used by some consumers)</td>
54
+ * <td>api.mixpanel.com</td>
55
+ * </tr>
56
+ * <tr>
57
+ * <td>events_endpoint</td>
58
+ * <td>The endpoint for tracking events (relative to the host)</td>
59
+ * <td>/events</td>
60
+ * </tr>
61
+ * <tr>
62
+ * <td>people_endpoint</td>
63
+ * <td>The endpoint for making people updates (relative to the host)</td>
64
+ * <td>/engage</td>
65
+ * </tr>
66
+ * <tr>
67
+ * <td>use_ssl</td>
68
+ * <td>Tell the consumer whether or not to use ssl (when available)</td>
69
+ * <td>true</td>
70
+ * </tr>
71
+ * <tr>
72
+ * <td>error_callback</td>
73
+ * <td>The name of a function to be called on consumption failures</td>
74
+ * <td>null</td>
75
+ * </tr>
76
+ * <tr>
77
+ * <td>connect_timeout</td>
78
+ * <td>In both the SocketConsumer and CurlConsumer, this is used for the connection timeout (i.e. How long it has take to actually make a connection).
79
+ * <td>5</td>
80
+ * </tr>
81
+ * <tr>
82
+ * <td>timeout</td>
83
+ * <td>In the CurlConsumer (non-forked), it is used to determine how long the cURL call has to execute.
84
+ * <td>30</td>
85
+ * </tr>
86
+ * </table>
87
+ *
88
+ * Example: Tracking an Event
89
+ * -------------
90
+ *
91
+ * $mp = Mixpanel::getInstance("MY_TOKEN");
92
+ *
93
+ * $mp->track("My Event");
94
+ *
95
+ * Example: Setting Profile Properties
96
+ * -------------
97
+ *
98
+ * $mp = Mixpanel::getInstance("MY_TOKEN", array("use_ssl" => false));
99
+ *
100
+ * $mp->people->set(12345, array(
101
+ * '$first_name' => "John",
102
+ * '$last_name' => "Doe",
103
+ * '$email' => "john.doe@example.com",
104
+ * '$phone' => "5555555555",
105
+ * 'Favorite Color' => "red"
106
+ * ));
107
+ *
108
+ */
109
+ class Mixpanel extends Base_MixpanelBase {
110
+
111
+
112
+ /**
113
+ * An instance of the MixpanelPeople class (used to create/update profiles)
114
+ * @var Producers_MixpanelPeople
115
+ */
116
+ public $people;
117
+
118
+
119
+ /**
120
+ * An instance of the MixpanelEvents class
121
+ * @var Producers_MixpanelEvents
122
+ */
123
+ private $_events;
124
+
125
+
126
+ /**
127
+ * Instances' list of the Mixpanel class (for singleton use, splitted by token)
128
+ * @var Mixpanel[]
129
+ */
130
+ private static $_instances = array();
131
+
132
+
133
+ /**
134
+ * Instantiates a new Mixpanel instance.
135
+ * @param $token
136
+ * @param array $options
137
+ */
138
+ public function __construct($token, $options = array()) {
139
+ parent::__construct($options);
140
+ $this->people = new Producers_MixpanelPeople($token, $options);
141
+ $this->_events = new Producers_MixpanelEvents($token, $options);
142
+ }
143
+
144
+
145
+ /**
146
+ * Returns a singleton instance of Mixpanel
147
+ * @param $token
148
+ * @param array $options
149
+ * @return Mixpanel
150
+ */
151
+ public static function getInstance($token, $options = array()) {
152
+ if(!isset(self::$_instances[$token])) {
153
+ self::$_instances[$token] = new Mixpanel($token, $options);
154
+ }
155
+ return self::$_instances[$token];
156
+ }
157
+
158
+
159
+ /**
160
+ * Add an array representing a message to be sent to Mixpanel to the in-memory queue.
161
+ * @param array $message
162
+ */
163
+ public function enqueue($message = array()) {
164
+ $this->_events->enqueue($message);
165
+ }
166
+
167
+
168
+ /**
169
+ * Add an array representing a list of messages to be sent to Mixpanel to a queue.
170
+ * @param array $messages
171
+ */
172
+ public function enqueueAll($messages = array()) {
173
+ $this->_events->enqueueAll($messages);
174
+ }
175
+
176
+
177
+ /**
178
+ * Flush the events queue
179
+ * @param int $desired_batch_size
180
+ */
181
+ public function flush($desired_batch_size = 50) {
182
+ $this->_events->flush($desired_batch_size);
183
+ }
184
+
185
+
186
+ /**
187
+ * Empty the events queue
188
+ */
189
+ public function reset() {
190
+ $this->_events->reset();
191
+ }
192
+
193
+
194
+ /**
195
+ * Identify the user you want to associate to tracked events. The $anon_id must be UUID v4 format and not already merged to an $identified_id.
196
+ * All identify calls with a new and valid $anon_id will trigger a track $identify event, and merge to the $identified_id.
197
+ * @param string|int $user_id
198
+ * @param string|int $anon_id [optional]
199
+ */
200
+ public function identify($user_id, $anon_id = null) {
201
+ $this->_events->identify($user_id, $anon_id);
202
+ }
203
+
204
+ /**
205
+ * Track an event defined by $event associated with metadata defined by $properties
206
+ * @param string $event
207
+ * @param array $properties
208
+ */
209
+ public function track($event, $properties = array()) {
210
+ $this->_events->track($event, $properties);
211
+ }
212
+
213
+
214
+ /**
215
+ * Register a property to be sent with every event.
216
+ *
217
+ * If the property has already been registered, it will be
218
+ * overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
219
+ * @param string $property
220
+ * @param mixed $value
221
+ */
222
+ public function register($property, $value) {
223
+ $this->_events->register($property, $value);
224
+ }
225
+
226
+
227
+ /**
228
+ * Register multiple properties to be sent with every event.
229
+ *
230
+ * If any of the properties have already been registered,
231
+ * they will be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
232
+ * instance.
233
+ * @param array $props_and_vals
234
+ */
235
+ public function registerAll($props_and_vals = array()) {
236
+ $this->_events->registerAll($props_and_vals);
237
+ }
238
+
239
+
240
+ /**
241
+ * Register a property to be sent with every event.
242
+ *
243
+ * If the property has already been registered, it will NOT be
244
+ * overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class instance.
245
+ * @param $property
246
+ * @param $value
247
+ */
248
+ public function registerOnce($property, $value) {
249
+ $this->_events->registerOnce($property, $value);
250
+ }
251
+
252
+
253
+ /**
254
+ * Register multiple properties to be sent with every event.
255
+ *
256
+ * If any of the properties have already been registered,
257
+ * they will NOT be overwritten. NOTE: Registered properties are only persisted for the life of the Mixpanel class
258
+ * instance.
259
+ * @param array $props_and_vals
260
+ */
261
+ public function registerAllOnce($props_and_vals = array()) {
262
+ $this->_events->registerAllOnce($props_and_vals);
263
+ }
264
+
265
+
266
+ /**
267
+ * Un-register an property to be sent with every event.
268
+ * @param string $property
269
+ */
270
+ public function unregister($property) {
271
+ $this->_events->unregister($property);
272
+ }
273
+
274
+
275
+ /**
276
+ * Un-register a list of properties to be sent with every event.
277
+ * @param array $properties
278
+ */
279
+ public function unregisterAll($properties) {
280
+ $this->_events->unregisterAll($properties);
281
+ }
282
+
283
+
284
+ /**
285
+ * Get a property that is set to be sent with every event
286
+ * @param string $property
287
+ * @return mixed
288
+ */
289
+ public function getProperty($property)
290
+ {
291
+ return $this->_events->getProperty($property);
292
+ }
293
+
294
+
295
+ /**
296
+ * An alias to be merged with the distinct_id. Each alias can only map to one distinct_id.
297
+ * This is helpful when you want to associate a generated id (such as a session id) to a user id or username.
298
+ * @param string|int $distinct_id
299
+ * @param string|int $alias
300
+ */
301
+ public function createAlias($distinct_id, $alias) {
302
+ $this->_events->createAlias($distinct_id, $alias);
303
+ }
304
+ }
includes/mixpanel-php/lib/Producers/MixpanelBaseProducer.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/../Base/MixpanelBase.php");
3
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/FileConsumer.php");
4
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
5
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/SocketConsumer.php");
6
+
7
+ if (!function_exists('json_encode')) {
8
+ throw new Exception('The JSON PHP extension is required.');
9
+ }
10
+
11
+ /**
12
+ * Provides some base methods for use by a message Producer
13
+ */
14
+ abstract class Producers_MixpanelBaseProducer extends Base_MixpanelBase {
15
+
16
+
17
+ /**
18
+ * @var string a token associated to a Mixpanel project
19
+ */
20
+ protected $_token;
21
+
22
+
23
+ /**
24
+ * @var array a queue to hold messages in memory before flushing in batches
25
+ */
26
+ private $_queue = array();
27
+
28
+
29
+ /**
30
+ * @var ConsumerStrategies_AbstractConsumer the consumer to use when flushing messages
31
+ */
32
+ private $_consumer = null;
33
+
34
+
35
+ /**
36
+ * @var array The list of available consumers
37
+ */
38
+ private $_consumers = array(
39
+ "file" => "ConsumerStrategies_FileConsumer",
40
+ "curl" => "ConsumerStrategies_CurlConsumer",
41
+ "socket" => "ConsumerStrategies_SocketConsumer"
42
+ );
43
+
44
+
45
+ /**
46
+ * If the queue reaches this size we'll auto-flush to prevent out of memory errors
47
+ * @var int
48
+ */
49
+ protected $_max_queue_size = 1000;
50
+
51
+
52
+ /**
53
+ * Creates a new MixpanelBaseProducer, assings Mixpanel project token, registers custom Consumers, and instantiates
54
+ * the desired consumer
55
+ * @param $token
56
+ * @param array $options
57
+ */
58
+ public function __construct($token, $options = array()) {
59
+
60
+ parent::__construct($options);
61
+
62
+ // register any customer consumers
63
+ if (array_key_exists("consumers", $options)) {
64
+ $this->_consumers = array_merge($this->_consumers, $options['consumers']);
65
+ }
66
+
67
+ // set max queue size
68
+ if (array_key_exists("max_queue_size", $options)) {
69
+ $this->_max_queue_size = $options['max_queue_size'];
70
+ }
71
+
72
+ // associate token
73
+ $this->_token = $token;
74
+
75
+ if ($this->_debug()) {
76
+ $this->_log("Using token: ".$this->_token);
77
+ }
78
+
79
+ // instantiate the chosen consumer
80
+ $this->_consumer = $this->_getConsumer();
81
+
82
+ }
83
+
84
+
85
+ /**
86
+ * Flush the queue when we destruct the client with retries
87
+ */
88
+ public function __destruct() {
89
+ $attempts = 0;
90
+ $max_attempts = 10;
91
+ $success = false;
92
+ while (!$success && $attempts < $max_attempts) {
93
+ if ($this->_debug()) {
94
+ $this->_log("destruct flush attempt #".($attempts+1));
95
+ }
96
+ $success = $this->flush();
97
+ $attempts++;
98
+ }
99
+ }
100
+
101
+
102
+ /**
103
+ * Iterate the queue and write in batches using the instantiated Consumer Strategy
104
+ * @param int $desired_batch_size
105
+ * @return bool whether or not the flush was successful
106
+ */
107
+ public function flush($desired_batch_size = 50) {
108
+ $queue_size = count($this->_queue);
109
+ $succeeded = true;
110
+ $num_threads = $this->_consumer->getNumThreads();
111
+
112
+ if ($this->_debug()) {
113
+ $this->_log("Flush called - queue size: ".$queue_size);
114
+ }
115
+
116
+ while($queue_size > 0 && $succeeded) {
117
+ $batch_size = min(array($queue_size, $desired_batch_size*$num_threads, $this->_options['max_batch_size']*$num_threads));
118
+ $batch = array_splice($this->_queue, 0, $batch_size);
119
+ $succeeded = $this->_persist($batch);
120
+
121
+ if (!$succeeded) {
122
+ if ($this->_debug()) {
123
+ $this->_log("Batch consumption failed!");
124
+ }
125
+ $this->_queue = array_merge($batch, $this->_queue);
126
+
127
+ if ($this->_debug()) {
128
+ $this->_log("added batch back to queue, queue size is now $queue_size");
129
+ }
130
+ }
131
+
132
+ $queue_size = count($this->_queue);
133
+
134
+ if ($this->_debug()) {
135
+ $this->_log("Batch of $batch_size consumed, queue size is now $queue_size");
136
+ }
137
+ }
138
+ return $succeeded;
139
+ }
140
+
141
+
142
+ /**
143
+ * Empties the queue without persisting any of the messages
144
+ */
145
+ public function reset() {
146
+ $this->_queue = array();
147
+ }
148
+
149
+
150
+ /**
151
+ * Returns the in-memory queue
152
+ * @return array
153
+ */
154
+ public function getQueue() {
155
+ return $this->_queue;
156
+ }
157
+
158
+ /**
159
+ * Returns the current Mixpanel project token
160
+ * @return string
161
+ */
162
+ public function getToken() {
163
+ return $this->_token;
164
+ }
165
+
166
+
167
+ /**
168
+ * Given a strategy type, return a new PersistenceStrategy object
169
+ * @return ConsumerStrategies_AbstractConsumer
170
+ */
171
+ protected function _getConsumer() {
172
+ $key = $this->_options['consumer'];
173
+ $Strategy = $this->_consumers[$key];
174
+ if ($this->_debug()) {
175
+ $this->_log("Using consumer: " . $key . " -> " . $Strategy);
176
+ }
177
+ $this->_options['endpoint'] = $this->_getEndpoint();
178
+
179
+ return new $Strategy($this->_options);
180
+ }
181
+
182
+
183
+ /**
184
+ * Add an array representing a message to be sent to Mixpanel to a queue.
185
+ * @param array $message
186
+ */
187
+ public function enqueue($message = array()) {
188
+ array_push($this->_queue, $message);
189
+
190
+ // force a flush if we've reached our threshold
191
+ if (count($this->_queue) > $this->_max_queue_size) {
192
+ $this->flush();
193
+ }
194
+
195
+ if ($this->_debug()) {
196
+ $this->_log("Queued message: ".json_encode($message));
197
+ }
198
+ }
199
+
200
+
201
+ /**
202
+ * Add an array representing a list of messages to be sent to Mixpanel to a queue.
203
+ * @param array $messages
204
+ */
205
+ public function enqueueAll($messages = array()) {
206
+ foreach($messages as $message) {
207
+ $this->enqueue($message);
208
+ }
209
+
210
+ }
211
+
212
+
213
+ /**
214
+ * Given an array of messages, persist it with the instantiated Persistence Strategy
215
+ * @param $message
216
+ * @return mixed
217
+ */
218
+ protected function _persist($message) {
219
+ return $this->_consumer->persist($message);
220
+ }
221
+
222
+
223
+
224
+
225
+ /**
226
+ * Return the endpoint that should be used by a consumer that consumes messages produced by this producer.
227
+ * @return string
228
+ */
229
+ abstract function _getEndpoint();
230
+
231
+ }
includes/mixpanel-php/lib/Producers/MixpanelEvents.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
3
+ require_once(dirname(__FILE__) . "/MixpanelPeople.php");
4
+ require_once(dirname(__FILE__) . "/../ConsumerStrategies/CurlConsumer.php");
5
+
6
+ /**
7
+ * Provides an API to track events on Mixpanel
8
+ */
9
+ class Producers_MixpanelEvents extends Producers_MixpanelBaseProducer {
10
+
11
+ /**
12
+ * An array of properties to attach to every tracked event
13
+ * @var array
14
+ */
15
+ private $_super_properties = array("mp_lib" => "php");
16
+
17
+
18
+ /**
19
+ * Track an event defined by $event associated with metadata defined by $properties
20
+ * @param string $event
21
+ * @param array $properties
22
+ */
23
+ public function track($event, $properties = array()) {
24
+
25
+ // if no token is passed in, use current token
26
+ if (!array_key_exists("token", $properties)) $properties['token'] = $this->_token;
27
+
28
+ // if no time is passed in, use the current time
29
+ if (!array_key_exists('time', $properties)) $properties['time'] = time();
30
+
31
+ $params['event'] = $event;
32
+ $params['properties'] = array_merge($this->_super_properties, $properties);
33
+
34
+ $this->enqueue($params);
35
+ }
36
+
37
+
38
+ /**
39
+ * Register a property to be sent with every event. If the property has already been registered, it will be
40
+ * overwritten.
41
+ * @param string $property
42
+ * @param mixed $value
43
+ */
44
+ public function register($property, $value) {
45
+ $this->_super_properties[$property] = $value;
46
+ }
47
+
48
+
49
+ /**
50
+ * Register multiple properties to be sent with every event. If any of the properties have already been registered,
51
+ * they will be overwritten.
52
+ * @param array $props_and_vals
53
+ */
54
+ public function registerAll($props_and_vals = array()) {
55
+ foreach($props_and_vals as $property => $value) {
56
+ $this->register($property, $value);
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Register a property to be sent with every event. If the property has already been registered, it will NOT be
63
+ * overwritten.
64
+ * @param $property
65
+ * @param $value
66
+ */
67
+ public function registerOnce($property, $value) {
68
+ if (!isset($this->_super_properties[$property])) {
69
+ $this->register($property, $value);
70
+ }
71
+ }
72
+
73
+
74
+ /**
75
+ * Register multiple properties to be sent with every event. If any of the properties have already been registered,
76
+ * they will NOT be overwritten.
77
+ * @param array $props_and_vals
78
+ */
79
+ public function registerAllOnce($props_and_vals = array()) {
80
+ foreach($props_and_vals as $property => $value) {
81
+ if (!isset($this->_super_properties[$property])) {
82
+ $this->register($property, $value);
83
+ }
84
+ }
85
+ }
86
+
87
+
88
+ /**
89
+ * Un-register an property to be sent with every event.
90
+ * @param string $property
91
+ */
92
+ public function unregister($property) {
93
+ unset($this->_super_properties[$property]);
94
+ }
95
+
96
+
97
+ /**
98
+ * Un-register a list of properties to be sent with every event.
99
+ * @param array $properties
100
+ */
101
+ public function unregisterAll($properties) {
102
+ foreach($properties as $property) {
103
+ $this->unregister($property);
104
+ }
105
+ }
106
+
107
+
108
+ /**
109
+ * Get a property that is set to be sent with every event
110
+ * @param string $property
111
+ * @return mixed
112
+ */
113
+ public function getProperty($property) {
114
+ return $this->_super_properties[$property];
115
+ }
116
+
117
+
118
+ /**
119
+ * Identify the user you want to associate to tracked events. The $anon_id must be UUID v4 format and not already merged to an $identified_id.
120
+ * All identify calls with a new and valid $anon_id will trigger a track $identify event, and merge to the $identified_id.
121
+ * @param string|int $user_id
122
+ * @param string|int $anon_id [optional]
123
+ */
124
+ public function identify($user_id, $anon_id = null) {
125
+ $this->register("distinct_id", $user_id);
126
+
127
+ $UUIDv4 = '/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i';
128
+ if (!empty($anon_id)) {
129
+ if (preg_match($UUIDv4, $anon_id) !== 1) {
130
+ /* not a valid uuid */
131
+ error_log("Running Identify method (identified_id: $user_id, anon_id: $anon_id) failed, anon_id not in UUID v4 format");
132
+ } else {
133
+ $this->track('$identify', array(
134
+ '$identified_id' => $user_id,
135
+ '$anon_id' => $anon_id
136
+ ));
137
+ }
138
+ }
139
+ }
140
+
141
+
142
+ /**
143
+ * An alias to be merged with the distinct_id. Each alias can only map to one distinct_id.
144
+ * This is helpful when you want to associate a generated id (such as a session id) to a user id or username.
145
+ *
146
+ * Because aliasing can be extremely vulnerable to race conditions and ordering issues, we'll make a synchronous
147
+ * call directly to Mixpanel when this method is called. If it fails we'll throw an Exception as subsequent
148
+ * events are likely to be incorrectly tracked.
149
+ * @param string|int $distinct_id
150
+ * @param string|int $alias
151
+ * @return array $msg
152
+ * @throws Exception
153
+ */
154
+ public function createAlias($distinct_id, $alias) {
155
+ $msg = array(
156
+ "event" => '$create_alias',
157
+ "properties" => array("distinct_id" => $distinct_id, "alias" => $alias, "token" => $this->_token)
158
+ );
159
+
160
+ // Save the current fork/async options
161
+ $old_fork = isset($this->_options['fork']) ? $this->_options['fork'] : false;
162
+ $old_async = isset($this->_options['async']) ? $this->_options['async'] : false;
163
+
164
+ // Override fork/async to make the new consumer synchronous
165
+ $this->_options['fork'] = false;
166
+ $this->_options['async'] = false;
167
+
168
+ // The name is ambiguous, but this creates a new consumer with current $this->_options
169
+ $consumer = $this->_getConsumer();
170
+ $success = $consumer->persist(array($msg));
171
+
172
+ // Restore the original fork/async settings
173
+ $this->_options['fork'] = $old_fork;
174
+ $this->_options['async'] = $old_async;
175
+
176
+ if (!$success) {
177
+ error_log("Creating Mixpanel Alias (distinct id: $distinct_id, alias: $alias) failed");
178
+ throw new Exception("Tried to create an alias but the call was not successful");
179
+ } else {
180
+ return $msg;
181
+ }
182
+ }
183
+
184
+
185
+ /**
186
+ * Returns the "events" endpoint
187
+ * @return string
188
+ */
189
+ function _getEndpoint() {
190
+ return $this->_options['events_endpoint'];
191
+ }
192
+ }
includes/mixpanel-php/lib/Producers/MixpanelPeople.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once(dirname(__FILE__) . "/MixpanelBaseProducer.php");
3
+
4
+ /**
5
+ * Provides an API to create/update profiles on Mixpanel
6
+ */
7
+ class Producers_MixpanelPeople extends Producers_MixpanelBaseProducer {
8
+
9
+ /**
10
+ * Internal method to prepare a message given the message data
11
+ * @param $distinct_id
12
+ * @param $operation
13
+ * @param $value
14
+ * @param null $ip
15
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
16
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
17
+ * @return array
18
+ */
19
+ private function _constructPayload($distinct_id, $operation, $value, $ip = null, $ignore_time = false, $ignore_alias = false) {
20
+ $payload = array(
21
+ '$token' => $this->_token,
22
+ '$distinct_id' => $distinct_id,
23
+ $operation => $value
24
+ );
25
+ if ($ip !== null) $payload['$ip'] = $ip;
26
+ if ($ignore_time === true) $payload['$ignore_time'] = true;
27
+ if ($ignore_alias === true) $payload['$ignore_alias'] = true;
28
+ return $payload;
29
+ }
30
+
31
+ /**
32
+ * Set properties on a user record. If the profile does not exist, it creates it with these properties.
33
+ * If it does exist, it sets the properties to these values, overwriting existing values.
34
+ * @param string|int $distinct_id the distinct_id or alias of a user
35
+ * @param array $props associative array of properties to set on the profile
36
+ * @param string|null $ip the ip address of the client (used for geo-location)
37
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
38
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
39
+ */
40
+ public function set($distinct_id, $props, $ip = null, $ignore_time = false, $ignore_alias = false) {
41
+ $payload = $this->_constructPayload($distinct_id, '$set', $props, $ip, $ignore_time, $ignore_alias);
42
+ $this->enqueue($payload);
43
+ }
44
+
45
+ /**
46
+ * Set properties on a user record. If the profile does not exist, it creates it with these properties.
47
+ * If it does exist, it sets the properties to these values but WILL NOT overwrite existing values.
48
+ * @param string|int $distinct_id the distinct_id or alias of a user
49
+ * @param array $props associative array of properties to set on the profile
50
+ * @param string|null $ip the ip address of the client (used for geo-location)
51
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
52
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
53
+ */
54
+ public function setOnce($distinct_id, $props, $ip = null, $ignore_time = false, $ignore_alias = false) {
55
+ $payload = $this->_constructPayload($distinct_id, '$set_once', $props, $ip, $ignore_time, $ignore_alias);
56
+ $this->enqueue($payload);
57
+ }
58
+
59
+ /**
60
+ * Unset properties on a user record. If the profile does not exist, it creates it with no properties.
61
+ * If it does exist, it unsets these properties. NOTE: In other libraries we use 'unset' which is
62
+ * a reserved word in PHP.
63
+ * @param string|int $distinct_id the distinct_id or alias of a user
64
+ * @param array $props associative array of properties to unset on the profile
65
+ * @param string|null $ip the ip address of the client (used for geo-location)
66
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
67
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
68
+ */
69
+ public function remove($distinct_id, $props, $ip = null, $ignore_time = false, $ignore_alias = false) {
70
+ $payload = $this->_constructPayload($distinct_id, '$unset', $props, $ip, $ignore_time, $ignore_alias);
71
+ $this->enqueue($payload);
72
+ }
73
+
74
+ /**
75
+ * Increments the value of a property on a user record. If the profile does not exist, it creates it and sets the
76
+ * property to the increment value.
77
+ * @param string|int $distinct_id the distinct_id or alias of a user
78
+ * @param $prop string the property to increment
79
+ * @param int $val the amount to increment the property by
80
+ * @param string|null $ip the ip address of the client (used for geo-location)
81
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
82
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
83
+ */
84
+ public function increment($distinct_id, $prop, $val, $ip = null, $ignore_time = false, $ignore_alias = false) {
85
+ $payload = $this->_constructPayload($distinct_id, '$add', array("$prop" => $val), $ip, $ignore_time, $ignore_alias);
86
+ $this->enqueue($payload);
87
+ }
88
+
89
+ /**
90
+ * Adds $val to a list located at $prop. If the property does not exist, it will be created. If $val is a string
91
+ * and the list is empty or does not exist, a new list with one value will be created.
92
+ * @param string|int $distinct_id the distinct_id or alias of a user
93
+ * @param string $prop the property that holds the list
94
+ * @param string|array $val items to add to the list
95
+ * @param string|null $ip the ip address of the client (used for geo-location)
96
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
97
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
98
+ */
99
+ public function append($distinct_id, $prop, $val, $ip = null, $ignore_time = false, $ignore_alias = false) {
100
+ $operation = gettype($val) == "array" ? '$union' : '$append';
101
+ $payload = $this->_constructPayload($distinct_id, $operation, array("$prop" => $val), $ip, $ignore_time, $ignore_alias);
102
+ $this->enqueue($payload);
103
+ }
104
+
105
+ /**
106
+ * Adds a transaction to the user's profile for revenue tracking
107
+ * @param string|int $distinct_id the distinct_id or alias of a user
108
+ * @param string $amount the transaction amount e.g. "20.50"
109
+ * @param null $timestamp the timestamp of when the transaction occurred (default to current timestamp)
110
+ * @param string|null $ip the ip address of the client (used for geo-location)
111
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
112
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
113
+ */
114
+ public function trackCharge($distinct_id, $amount, $timestamp = null, $ip = null, $ignore_time = false, $ignore_alias = false) {
115
+ $timestamp = $timestamp == null ? time() : $timestamp;
116
+ $date_iso = date("c", $timestamp);
117
+ $transaction = array(
118
+ '$time' => $date_iso,
119
+ '$amount' => $amount
120
+ );
121
+ $val = array('$transactions' => $transaction);
122
+ $payload = $this->_constructPayload($distinct_id, '$append', $val, $ip, $ignore_time, $ignore_alias);
123
+ $this->enqueue($payload);
124
+ }
125
+
126
+ /**
127
+ * Clear all transactions stored on a user's profile
128
+ * @param string|int $distinct_id the distinct_id or alias of a user
129
+ * @param string|null $ip the ip address of the client (used for geo-location)
130
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
131
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
132
+ */
133
+ public function clearCharges($distinct_id, $ip = null, $ignore_time = false, $ignore_alias = false) {
134
+ $payload = $this->_constructPayload($distinct_id, '$set', array('$transactions' => array()), $ip, $ignore_time, $ignore_alias);
135
+ $this->enqueue($payload);
136
+ }
137
+
138
+ /**
139
+ * Delete this profile from Mixpanel
140
+ * @param string|int $distinct_id the distinct_id or alias of a user
141
+ * @param string|null $ip the ip address of the client (used for geo-location)
142
+ * @param boolean $ignore_time If the $ignore_time property is true, Mixpanel will not automatically update the "Last Seen" property of the profile. Otherwise, Mixpanel will add a "Last Seen" property associated with the current time
143
+ * @param boolean $ignore_alias If the $ignore_alias property is true, an alias look up will not be performed after ingestion. Otherwise, a lookup for the distinct ID will be performed, and replaced if a match is found
144
+ */
145
+ public function deleteUser($distinct_id, $ip = null, $ignore_time = false, $ignore_alias = false) {
146
+ $payload = $this->_constructPayload($distinct_id, '$delete', "", $ip, $ignore_time, $ignore_alias);
147
+ $this->enqueue($payload);
148
+ }
149
+
150
+ /**
151
+ * Returns the "engage" endpoint
152
+ * @return string
153
+ */
154
+ function _getEndpoint() {
155
+ return $this->_options['people_endpoint'];
156
+ }
157
+
158
+ }
opinionstage-polls.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Poll, Survey, Form & Quiz Maker by OpinionStage (Deprecated)
4
  Plugin URI: https://www.opinionstage.com
5
  Description: Add a highly engaging poll, survey, quiz or contact form builder to your site. You can add the poll, survey, quiz or form to any post/page or to the sidebar.
6
- Version: 19.7.3
7
  Author: OpinionStage.com
8
  Author URI: https://www.opinionstage.com
9
  Text Domain: social-polls-by-opinionstage
3
  Plugin Name: Poll, Survey, Form & Quiz Maker by OpinionStage (Deprecated)
4
  Plugin URI: https://www.opinionstage.com
5
  Description: Add a highly engaging poll, survey, quiz or contact form builder to your site. You can add the poll, survey, quiz or form to any post/page or to the sidebar.
6
+ Version: 19.7.4
7
  Author: OpinionStage.com
8
  Author URI: https://www.opinionstage.com
9
  Text Domain: social-polls-by-opinionstage
plugin.php CHANGED
@@ -1,14 +1,14 @@
1
  <?php
2
  /**
3
- * Poll, Survey, Form & Quiz Maker by OpinionStage
4
  *
5
  * @package OpinionStageWordPressPlugin
6
  *
7
  * @wordpress-plugin
8
- * Plugin Name: Poll, Survey, Form & Quiz Maker by OpinionStage
9
  * Plugin URI: https://www.opinionstage.com
10
  * Description: Add a highly engaging poll, survey, quiz or contact form builder to your site. You can add the poll, survey, quiz or form to any post/page or to the sidebar.
11
- * Version: 19.7.3
12
  * Author: OpinionStage.com
13
  * Author URI: https://www.opinionstage.com
14
  * Text Domain: social-polls-by-opinionstage
@@ -34,7 +34,7 @@ if ( defined( 'WP_DEBUG' ) && true === WP_DEBUG ) {
34
  }
35
  }
36
 
37
- define( 'OPINIONSTAGE_WIDGET_VERSION', '19.7.3' );
38
 
39
  define( 'OPINIONSTAGE_TEXT_DOMAIN', 'social-polls-by-opinionstage' );
40
 
@@ -78,9 +78,9 @@ if ( ! version_compare( PHP_VERSION, '5.2', '>=' ) ) {
78
  function opinionstage_plugin_activated( $plugin ) {
79
  // Check if active plugin file is plugin.php on plugin activate hook.
80
  if ( plugin_basename( __FILE__ ) === $plugin ) {
81
- // phpcs:disable WordPress.Security.EscapeOutput
82
- exit( wp_safe_redirect( 'admin.php?page=' . OPINIONSTAGE_GETTING_STARTED_SLUG ) );
83
- // phpcs:enable
84
  }
85
  }
86
  // phpcs:disable Squiz.Commenting.FunctionComment
@@ -103,6 +103,7 @@ if ( ! version_compare( PHP_VERSION, '5.2', '>=' ) ) {
103
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-utility-functions.php';
104
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-article-placement-functions.php';
105
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-sidebar-widget.php';
 
106
 
107
  if ( ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) || ( defined( 'DOING_AJAX' ) ) ) {
108
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-ajax-functions.php';
@@ -131,7 +132,7 @@ if ( ! version_compare( PHP_VERSION, '5.2', '>=' ) ) {
131
  */
132
  function opinionstage_fail_php_version() {
133
  /* translators: %s: PHP version */
134
- $message = sprintf( esc_html__( 'Poll, Survey, Form & Quiz Maker by OpinionStage requires PHP version %s+, plugin is currently NOT RUNNING.', 'opinionstage' ), '5.2' );
135
  $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) );
136
  echo wp_kses_post( $html_message );
137
  }
@@ -147,7 +148,7 @@ function opinionstage_fail_php_version() {
147
  */
148
  function opinionstage_fail_wp_version() {
149
  /* translators: %s: WordPress version */
150
- $message = sprintf( esc_html__( 'Poll, Survey, Form & Quiz Maker by OpinionStage requires WordPress version %s+. Because you are using an earlier version, the plugin is currently NOT RUNNING.', 'opinionstage' ), '4.7' );
151
  $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) );
152
  echo wp_kses_post( $html_message );
153
  }
1
  <?php
2
  /**
3
+ * Poll, Survey & Quiz by OpinionStage
4
  *
5
  * @package OpinionStageWordPressPlugin
6
  *
7
  * @wordpress-plugin
8
+ * Plugin Name: Poll, Survey & Quiz by OpinionStage
9
  * Plugin URI: https://www.opinionstage.com
10
  * Description: Add a highly engaging poll, survey, quiz or contact form builder to your site. You can add the poll, survey, quiz or form to any post/page or to the sidebar.
11
+ * Version: 19.7.4
12
  * Author: OpinionStage.com
13
  * Author URI: https://www.opinionstage.com
14
  * Text Domain: social-polls-by-opinionstage
34
  }
35
  }
36
 
37
+ define( 'OPINIONSTAGE_WIDGET_VERSION', '19.7.4' );
38
 
39
  define( 'OPINIONSTAGE_TEXT_DOMAIN', 'social-polls-by-opinionstage' );
40
 
78
  function opinionstage_plugin_activated( $plugin ) {
79
  // Check if active plugin file is plugin.php on plugin activate hook.
80
  if ( plugin_basename( __FILE__ ) === $plugin ) {
81
+ $redirect_to = opinionstage_user_logged_in() ? OPINIONSTAGE_VIEW_ITEM_SLUG : OPINIONSTAGE_GETTING_STARTED_SLUG;
82
+ wp_safe_redirect( 'admin.php?page=' . $redirect_to );
83
+ exit();
84
  }
85
  }
86
  // phpcs:disable Squiz.Commenting.FunctionComment
103
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-utility-functions.php';
104
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-article-placement-functions.php';
105
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-sidebar-widget.php';
106
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-opinionstagefeedback.php';
107
 
108
  if ( ( function_exists( 'wp_doing_ajax' ) && wp_doing_ajax() ) || ( defined( 'DOING_AJAX' ) ) ) {
109
  require_once plugin_dir_path( __FILE__ ) . 'includes/opinionstage-ajax-functions.php';
132
  */
133
  function opinionstage_fail_php_version() {
134
  /* translators: %s: PHP version */
135
+ $message = sprintf( esc_html__( 'Poll, Survey & Quiz by OpinionStage requires PHP version %s+, plugin is currently NOT RUNNING.', 'opinionstage' ), '5.2' );
136
  $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) );
137
  echo wp_kses_post( $html_message );
138
  }
148
  */
149
  function opinionstage_fail_wp_version() {
150
  /* translators: %s: WordPress version */
151
+ $message = sprintf( esc_html__( 'Poll, Survey & Quiz by OpinionStage requires WordPress version %s+. Because you are using an earlier version, the plugin is currently NOT RUNNING.', 'opinionstage' ), '4.7' );
152
  $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) );
153
  echo wp_kses_post( $html_message );
154
  }
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
- === Poll, Survey, Form & Quiz Maker by OpinionStage ===
2
  Contributors: opinionstage, yoffegil, kucaahbe
3
  Donate link: https://www.opinionstage.com
4
  Tags: poll, quiz, survey, poll plugin, quiz plugin, survey plugin
5
  Requires at least: 2.8
6
- Tested up to: 5.5
7
- Stable tag: 19.7.3
8
  Requires PHP: 5.2
9
 
10
  Add a Poll, Survey, or Quiz to your Wordpress site. Create a poll, quiz, or survey from scratch or based on templates.
@@ -138,6 +138,11 @@ Opinion Stage makes it easy for you to comply with the GDPR regulation. For more
138
  N/A
139
 
140
  == Changelog ==
 
 
 
 
 
141
  = 19.7.3 =
142
  * updated signup functional
143
  * internal code improvements
1
+ === Poll, Survey & Quiz by OpinionStage ===
2
  Contributors: opinionstage, yoffegil, kucaahbe
3
  Donate link: https://www.opinionstage.com
4
  Tags: poll, quiz, survey, poll plugin, quiz plugin, survey plugin
5
  Requires at least: 2.8
6
+ Tested up to: 5.6
7
+ Stable tag: 19.7.4
8
  Requires PHP: 5.2
9
 
10
  Add a Poll, Survey, or Quiz to your Wordpress site. Create a poll, quiz, or survey from scratch or based on templates.
138
  N/A
139
 
140
  == Changelog ==
141
+ = 19.7.4 =
142
+ * updated plugin name
143
+ * added poll on disabling plugin
144
+ * renamed Form block to Classic Form
145
+ * internal code improvements
146
  = 19.7.3 =
147
  * updated signup functional
148
  * internal code improvements