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 | 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 +33 -33
- admin/content-popup.php +16 -8
- admin/css/admin-feedback.css +175 -0
- admin/js/admin-feedback.js +56 -0
- admin/views/settings.php +48 -46
- admin/views/view_my_items.php +98 -100
- assets/gutenberg/build/index.asset.php +1 -1
- assets/gutenberg/build/index.js +1 -1
- assets/gutenberg/src/edit.js +1 -1
- assets/gutenberg/src/index.js +1 -1
- includes/class-opinionstagefeedback.php +221 -0
- includes/mixpanel-php/lib/Base/MixpanelBase.php +65 -0
- includes/mixpanel-php/lib/ConsumerStrategies/AbstractConsumer.php +65 -0
- includes/mixpanel-php/lib/ConsumerStrategies/CurlConsumer.php +257 -0
- includes/mixpanel-php/lib/ConsumerStrategies/FileConsumer.php +38 -0
- includes/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php +308 -0
- includes/mixpanel-php/lib/Mixpanel.php +304 -0
- includes/mixpanel-php/lib/Producers/MixpanelBaseProducer.php +231 -0
- includes/mixpanel-php/lib/Producers/MixpanelEvents.php +192 -0
- includes/mixpanel-php/lib/Producers/MixpanelPeople.php +158 -0
- opinionstage-polls.php +1 -1
- plugin.php +10 -9
- readme.txt +8 -3
admin/content-popup-template.html.php
CHANGED
@@ -1,27 +1,27 @@
|
|
1 |
<?php
|
2 |
// block direct access to plugin PHP files:
|
3 |
-
defined( 'ABSPATH' )
|
4 |
|
5 |
-
require_once
|
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
|
10 |
?>
|
11 |
<style type="text/css">
|
12 |
.content__image {
|
13 |
-
|
14 |
-
|
15 |
-
|
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"
|
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 |
-
|
65 |
<div class='filter__itm'
|
66 |
@click="selectWidgetType('poll')"
|
67 |
:class="{ active: selectedWidgetType === 'poll' }"
|
68 |
-
|
69 |
<div class='filter__itm'
|
70 |
@click="selectWidgetType('survey')"
|
71 |
:class="{ active: selectedWidgetType === 'survey' }"
|
72 |
-
|
73 |
<div class='filter__itm'
|
74 |
@click="selectWidgetType('trivia')"
|
75 |
:class="{ active: selectedWidgetType === 'trivia' }"
|
76 |
-
|
77 |
<div class='filter__itm'
|
78 |
@click="selectWidgetType('outcome')"
|
79 |
:class="{ active: selectedWidgetType === 'outcome' }"
|
80 |
-
|
81 |
<div class='filter__itm'
|
82 |
@click="selectWidgetType('form')"
|
83 |
:class="{ active: selectedWidgetType === 'form' }"
|
84 |
-
|
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"
|
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)"
|
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'
|
117 |
-
<a class='content__links-itm' target="_blank" :href='widget.editUrl' v-show="!widget.template"
|
118 |
-
<a class='content__links-itm' target="_blank" :href='widget.statsUrl' v-show="!widget.template"
|
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 |
-
|
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
|
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"
|
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"
|
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 |
-
|
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
|
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 |
-
|
3 |
-
|
|
|
|
|
4 |
?>
|
5 |
<div id="opinionstage-content">
|
6 |
<div class="opinionstage-header-wrapper">
|
7 |
-
<?php if (
|
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;"
|
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
|
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[
|
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"
|
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"
|
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"
|
48 |
-
<div class="example"
|
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"
|
61 |
-
<div class="example"
|
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"
|
74 |
-
<div class="example"
|
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"
|
87 |
-
<div class="example"
|
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"
|
100 |
-
<div class="example"
|
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 |
-
|
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 |
-
|
8 |
-
|
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[
|
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"
|
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"
|
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"
|
32 |
-
<div style="padding:
|
33 |
<select id="itemList">
|
34 |
-
<option value="all"
|
35 |
-
<option value="poll"
|
36 |
-
<option value="survey"
|
37 |
-
<option value="trivia"
|
38 |
-
<option value="personality"
|
39 |
-
<option value="form"
|
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 |
-
|
|
|
|
|
|
|
49 |
</div>
|
50 |
-
<p class="result_progress" style="display: block; font-size: 16px; text-align: center;"
|
51 |
<table id="check"></table>
|
52 |
-
<p class="no_item" style="display: none; font-size: 15px; text-align: center;"
|
53 |
-
<div id="loadMore" class="btn btn_aqua btn_full-width" style="display: none;"
|
54 |
-
<div id="showLess" style="display: none;"
|
55 |
</div>
|
56 |
</div>
|
57 |
</div>
|
58 |
<script type="text/javascript">
|
59 |
-
jQuery(document).ready(function($){
|
60 |
-
|
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 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
previewBlockOsDate = previewBlockOsDate.toDateString();
|
84 |
var resDateOs = previewBlockOsDate.split(" ");
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
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 |
-
|
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 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
|
117 |
jQuery('.no_item').css('display', 'none');
|
118 |
-
|
119 |
-
|
120 |
-
if(selectedValue != 'all' && selectedValue != jQuery(
|
121 |
-
|
122 |
-
|
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 |
-
|
133 |
-
|
134 |
-
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
});
|
140 |
|
141 |
$("#searchItem").on("keyup",function search(e) {
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
}
|
159 |
}
|
160 |
else {
|
@@ -165,27 +163,27 @@ defined( 'ABSPATH' ) or die(1); ?>
|
|
165 |
outerContainer.css('display', 'none');
|
166 |
}
|
167 |
else {
|
168 |
-
|
169 |
}
|
170 |
}
|
171 |
}
|
172 |
});
|
173 |
}
|
174 |
-
|
175 |
-
|
176 |
-
});
|
177 |
},
|
178 |
error: function(){
|
179 |
-
|
180 |
}
|
181 |
});
|
182 |
|
183 |
|
184 |
function loadMore(size, dataLength, item) {
|
185 |
if(dataLength == size && dataLength > 10){
|
186 |
-
|
187 |
-
|
188 |
-
|
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 |
-
|
198 |
|
199 |
-
|
200 |
-
|
201 |
}
|
202 |
else {
|
203 |
$('table#check tbody#countItem:lt('+x+')').show(500);
|
204 |
}
|
205 |
|
206 |
-
|
207 |
$("#loadMore").hide(500);
|
208 |
}
|
209 |
});
|
210 |
$('#showLess').on('click', null, function () {
|
211 |
-
|
212 |
-
|
213 |
-
|
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' => '
|
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.
|
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
|
4 |
*
|
5 |
* @package OpinionStageWordPressPlugin
|
6 |
*
|
7 |
* @wordpress-plugin
|
8 |
-
* Plugin Name: Poll, Survey
|
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.
|
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.
|
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 |
-
|
82 |
-
|
83 |
-
|
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
|
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
|
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
|
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.
|
7 |
-
Stable tag: 19.7.
|
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
|