Version Description
= * Adding SMS support to Premium * More intuitive scheduler in Premium * Better timezone checks * Other small fixes and improvements
Download this release
Release Info
Developer | jasperroel |
Plugin | Call Now Button |
Version | 1.0.6 |
Comparing to | |
See all releases |
Code changes from version 1.0.5 to 1.0.6
- call-now-button.php +2 -2
- readme.txt +13 -4
- resources/js/action-edit-scheduler.js +126 -0
- resources/js/action-type-to-icon-text.js +13 -3
- resources/js/call-now-button.js +24 -13
- resources/js/dismiss.js +4 -4
- resources/js/preview.js +11 -0
- resources/js/settings.js +58 -8
- resources/style/call-now-button.css +164 -16
- src/admin/action-edit.php +59 -37
- src/admin/action-overview.php +89 -3
- src/admin/admin-ajax.php +18 -0
- src/admin/api/CnbAdminCloud.php +41 -6
- src/admin/api/CnbAppRemote.php +10 -0
- src/admin/button-edit.php +1 -0
- src/admin/button-overview.php +3 -1
- src/admin/domain-edit.php +3 -1
- src/admin/legacy-edit.php +7 -7
- src/admin/legacy-upgrade.php +16 -18
- src/admin/models/CnbButton.class.php +70 -1
- src/admin/models/CnbUser.class.php +62 -0
- src/admin/partials/admin-footer.php +4 -2
- src/admin/partials/admin-functions.php +10 -0
- src/admin/partials/domain-upgrade/overview.php +12 -12
- src/admin/settings-profile.php +39 -36
- src/admin/settings.php +57 -35
- src/autoload.php +1 -0
- src/call-now-button.php +13 -2
- src/cli/CNB_CLI.class.php +32 -0
- src/cli/CNB_CLI_Api.class.php +190 -0
- src/cli/CNB_CLI_Button.class.php +180 -0
- src/cli/CNB_CLI_User.class.php +61 -0
- src/cli/mocks/WP_CLI.class.php +35 -0
- src/cli/mocks/WP_CLI_Utils.class.php +11 -0
- src/utils/notices.php +59 -32
- src/utils/utils.php +17 -4
call-now-button.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Call Now Button
|
4 |
Plugin URI: https://callnowbutton.com
|
5 |
Description: Mobile visitors will see a <strong>Call Now Button</strong> on your website. Easy to use but flexible to meet more demanding requirements. Change placement and color, hide on specific pages, track how many people click them or conversions of your Google Ads campaigns. It's all optional but possible.
|
6 |
-
Version: 1.0.
|
7 |
Author: Jerry Rietveld
|
8 |
Author URI: https://www.callnowbutton.com
|
9 |
GitHub Plugin URI: https://github.com/callnowbutton/wp-plugin
|
@@ -26,7 +26,7 @@ License: GPL2
|
|
26 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
27 |
*/
|
28 |
|
29 |
-
define('CNB_VERSION', '1.0.
|
30 |
define('CNB_NAME', 'Call Now Button');
|
31 |
define('CNB_BASENAME', plugin_basename(__FILE__));
|
32 |
define('CNB_BASEFOLDER', plugin_basename(dirname(__FILE__)));
|
3 |
Plugin Name: Call Now Button
|
4 |
Plugin URI: https://callnowbutton.com
|
5 |
Description: Mobile visitors will see a <strong>Call Now Button</strong> on your website. Easy to use but flexible to meet more demanding requirements. Change placement and color, hide on specific pages, track how many people click them or conversions of your Google Ads campaigns. It's all optional but possible.
|
6 |
+
Version: 1.0.6
|
7 |
Author: Jerry Rietveld
|
8 |
Author URI: https://www.callnowbutton.com
|
9 |
GitHub Plugin URI: https://github.com/callnowbutton/wp-plugin
|
26 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
27 |
*/
|
28 |
|
29 |
+
define('CNB_VERSION', '1.0.6');
|
30 |
define('CNB_NAME', 'Call Now Button');
|
31 |
define('CNB_BASENAME', plugin_basename(__FILE__));
|
32 |
define('CNB_BASEFOLDER', plugin_basename(dirname(__FILE__)));
|
readme.txt
CHANGED
@@ -5,11 +5,11 @@ Tags: call button, click to call, convert, call now button, contact button
|
|
5 |
Requires at least: 3.9
|
6 |
Requires PHP: 5.4
|
7 |
Tested up to: 5.9
|
8 |
-
Stable tag: 1.0.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
12 |
-
|
13 |
|
14 |
== Description ==
|
15 |
|
@@ -29,7 +29,7 @@ Under the **Presentation tab** you can change the color of the button, move it t
|
|
29 |
Under the **Settings menu** you'll find a bunch of features that allow you to enable click tracking in Google Analytics, fire a conversion tag so a call is registered as a conversion in Google Ads, adjust the size of the button or move the button further backwards in case you want something else to sit on top of it (e.g. your privacy notice).
|
30 |
|
31 |
###Need even more control?
|
32 |
-
Easily upgrade the plugin to Premium to add additional features such as multiple buttons, additional actions such as
|
33 |
|
34 |
|
35 |
|
@@ -111,12 +111,17 @@ Yes, you can upgrade to Premium to enable tons of extra features. Checkout [call
|
|
111 |
|
112 |
|
113 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
= 1.0.5 =
|
115 |
* Preview improvements
|
116 |
* Back link when editing actions
|
117 |
* Some bug, style and copy fixes
|
118 |
|
119 |
-
|
120 |
= 1.0.4 =
|
121 |
* Live button preview in Premium
|
122 |
* Easy activation of Premium via email
|
@@ -235,3 +240,7 @@ Yes, you can upgrade to Premium to enable tons of extra features. Checkout [call
|
|
235 |
|
236 |
= 0.0.1 =
|
237 |
* First time launch
|
|
|
|
|
|
|
|
5 |
Requires at least: 3.9
|
6 |
Requires PHP: 5.4
|
7 |
Tested up to: 5.9
|
8 |
+
Stable tag: 1.0.6
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
12 |
+
The web's #1 click to call button for your website! A very simple but powerful plugin that adds a Call Now Button to your website for your mobile visitors (only for responsive websites).
|
13 |
|
14 |
== Description ==
|
15 |
|
29 |
Under the **Settings menu** you'll find a bunch of features that allow you to enable click tracking in Google Analytics, fire a conversion tag so a call is registered as a conversion in Google Ads, adjust the size of the button or move the button further backwards in case you want something else to sit on top of it (e.g. your privacy notice).
|
30 |
|
31 |
###Need even more control?
|
32 |
+
Easily upgrade the plugin to Premium to add additional features such as multiple buttons, additional actions such as SMS/Text, Email, WhatsApp, Maps and links, a button scheduler, more advanced page selection options, Buttonbars and Multibuttons, a live preview window and much much more!
|
33 |
|
34 |
|
35 |
|
111 |
|
112 |
|
113 |
== Changelog ==
|
114 |
+
= 1.0.6 =
|
115 |
+
* Adding SMS support to Premium
|
116 |
+
* More intuitive scheduler in Premium
|
117 |
+
* Better timezone checks
|
118 |
+
* Other small fixes and improvements
|
119 |
+
|
120 |
= 1.0.5 =
|
121 |
* Preview improvements
|
122 |
* Back link when editing actions
|
123 |
* Some bug, style and copy fixes
|
124 |
|
|
|
125 |
= 1.0.4 =
|
126 |
* Live button preview in Premium
|
127 |
* Easy activation of Premium via email
|
240 |
|
241 |
= 0.0.1 =
|
242 |
* First time launch
|
243 |
+
|
244 |
+
== Upgrade Notice ==
|
245 |
+
= 1.0.6 =
|
246 |
+
* Upgrade now to keep your Call Now Button up to date. The update contains some small UI improvements and we've added SMS/Text support to the Premium version. Maybe give Premium Free a go!
|
resources/js/action-edit-scheduler.js
ADDED
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
*
|
3 |
+
* Range of minutes is 0 - 1439:
|
4 |
+
* - 0 == midnight
|
5 |
+
* - 24*60-1 (1439) = minute before end of day
|
6 |
+
*
|
7 |
+
* This is the inverse of fromFormattedToMinutes
|
8 |
+
*
|
9 |
+
* @param {number} time amount of minutes from midnight
|
10 |
+
* @returns {string} hh:mm in 24h time notation, padded with 0 were needed
|
11 |
+
*/
|
12 |
+
function getFormattedTime(time) {
|
13 |
+
let hour = Math.floor(time / 60);
|
14 |
+
let minutes = time - (hour * 60);
|
15 |
+
|
16 |
+
if (hour < 10) hour = "0" + hour
|
17 |
+
if (hour === 0) hour = "00"
|
18 |
+
|
19 |
+
if (minutes< 10) minutes = "0" + minutes
|
20 |
+
if (minutes === 0) minutes = "00"
|
21 |
+
return hour + ':' + minutes
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The inverse of getFormattedTime
|
26 |
+
*
|
27 |
+
* @param {string} time Formatted time string ("16:39")
|
28 |
+
* @returns {number} number between 0 (inclusive) and 1440 (exclusive)
|
29 |
+
*/
|
30 |
+
function fromFormattedToMinutes(time) {
|
31 |
+
const splitTime = time.split(":")
|
32 |
+
return (splitTime[0] * 60) + (splitTime[1] * 1)
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* This sets the actual <input> elements that are submitted as part of the scheduler
|
37 |
+
*
|
38 |
+
* Note that "stop" should be later than "start".
|
39 |
+
*
|
40 |
+
* @param {string} start Formatted 24h time ("13:00")
|
41 |
+
* @param {string} stop Formatted 24h time ("14:50")
|
42 |
+
*/
|
43 |
+
function cnbUpdateTime(start, stop) {
|
44 |
+
jQuery('#actions-schedule-start').val(start)
|
45 |
+
jQuery('#actions-schedule-stop').val(stop)
|
46 |
+
}
|
47 |
+
|
48 |
+
function cnbUpdateColors() {
|
49 |
+
const reverse = jQuery('#actions_schedule_outside_hours').prop('checked')
|
50 |
+
const headerColor = reverse ? '#b3afaf' : '#3582c4';
|
51 |
+
const widgetColor = headerColor === '#b3afaf' ? '#3582c4' : '#b3afaf';
|
52 |
+
jQuery('#cnb-schedule-range .ui-widget-header').css({"background-color": headerColor});
|
53 |
+
jQuery('#cnb-schedule-range.ui-widget-content').css({"background": widgetColor});
|
54 |
+
}
|
55 |
+
|
56 |
+
function cnbAjaxTimeFormat(start, stop) {
|
57 |
+
const data = {
|
58 |
+
'action': 'cnb_time_format',
|
59 |
+
'start': start,
|
60 |
+
'stop': stop
|
61 |
+
};
|
62 |
+
|
63 |
+
jQuery.post(ajaxurl, data, function(response) {
|
64 |
+
cnbUpdateTimeText(response.start, response.stop)
|
65 |
+
});
|
66 |
+
}
|
67 |
+
|
68 |
+
function cnbUpdateTimeText(start, stop) {
|
69 |
+
const reverse1 = jQuery('#actions_schedule_outside_hours').prop('checked') ? 'Before': 'From';
|
70 |
+
const reverse2 = jQuery('#actions_schedule_outside_hours').prop('checked') ? 'and after': 'till';
|
71 |
+
|
72 |
+
jQuery( "#cnb-schedule-range-text" ).html( reverse1+" <strong>" + start + "</strong> "+reverse2+" <strong>" + stop + "</strong>")
|
73 |
+
}
|
74 |
+
|
75 |
+
function cnbRangeInverter() {
|
76 |
+
jQuery('#actions_schedule_outside_hours').on('change', () => {
|
77 |
+
cnbUpdateColors();
|
78 |
+
|
79 |
+
const start = jQuery('#actions-schedule-start').val()
|
80 |
+
const stop = jQuery('#actions-schedule-stop').val()
|
81 |
+
cnbAjaxTimeFormat(start, stop)
|
82 |
+
});
|
83 |
+
}
|
84 |
+
|
85 |
+
function cnbSetupScheduleStartStopSlider(start, stop) {
|
86 |
+
jQuery( "#cnb-schedule-range" ).slider({
|
87 |
+
range: true,
|
88 |
+
min: 0,
|
89 |
+
max: 24 * 60, // Do not include midnight, since "min" is inclusive
|
90 |
+
values: [ start, stop ],
|
91 |
+
step: 15,
|
92 |
+
slide: function( event, ui ) {
|
93 |
+
const start = getFormattedTime(ui.values[ 0 ])
|
94 |
+
let stop = getFormattedTime(ui.values[ 1 ])
|
95 |
+
stop = stop !== "24:00" ? stop : "23:59"
|
96 |
+
|
97 |
+
cnbAjaxTimeFormat(start, stop)
|
98 |
+
cnbUpdateTime(start, stop)
|
99 |
+
cnbUpdateColors()
|
100 |
+
}
|
101 |
+
});
|
102 |
+
}
|
103 |
+
|
104 |
+
function cnbSetupActionEditScheduler(start, stop) {
|
105 |
+
// Set time
|
106 |
+
cnbAjaxTimeFormat(getFormattedTime(start), getFormattedTime(stop))
|
107 |
+
cnbUpdateTime(getFormattedTime(start), getFormattedTime(stop))
|
108 |
+
cnbSetupScheduleStartStopSlider(start, stop)
|
109 |
+
|
110 |
+
// First time setup
|
111 |
+
cnbRangeInverter();
|
112 |
+
cnbUpdateColors();
|
113 |
+
}
|
114 |
+
|
115 |
+
jQuery( () => {
|
116 |
+
// Get the current value
|
117 |
+
const startVal = jQuery('#actions-schedule-start').val()
|
118 |
+
let stopVal = jQuery('#actions-schedule-stop').val()
|
119 |
+
stopVal = stopVal !== "24:00" ? stopVal : "23:59"
|
120 |
+
|
121 |
+
// Set it or use the default
|
122 |
+
const start = fromFormattedToMinutes(startVal ? startVal : '08:00');
|
123 |
+
const stop = fromFormattedToMinutes(stopVal ? stopVal : '17:00');
|
124 |
+
|
125 |
+
cnbSetupActionEditScheduler(start, stop)
|
126 |
+
});
|
resources/js/action-type-to-icon-text.js
CHANGED
@@ -1,12 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
function cnbActiontypeToIcontext(actionType) {
|
2 |
switch (actionType) {
|
3 |
case 'ANCHOR': return 'anchor';
|
4 |
-
case 'WHATSAPP': return 'whatsapp';
|
5 |
case 'EMAIL': return 'email';
|
|
|
6 |
case 'LINK': return 'link';
|
7 |
case 'MAP': return 'directions';
|
8 |
-
case '
|
9 |
-
case '
|
|
|
10 |
default:
|
11 |
return 'call';
|
12 |
}
|
1 |
+
/**
|
2 |
+
* Get the default glyph for a particular action type.
|
3 |
+
*
|
4 |
+
* This should have the same content as the PHP function cnb_actiontype_to_icontext
|
5 |
+
*
|
6 |
+
* @param {string} actionType
|
7 |
+
*
|
8 |
+
* @returns {string}
|
9 |
+
*/
|
10 |
function cnbActiontypeToIcontext(actionType) {
|
11 |
switch (actionType) {
|
12 |
case 'ANCHOR': return 'anchor';
|
|
|
13 |
case 'EMAIL': return 'email';
|
14 |
+
case 'HOURS': return 'access_time';
|
15 |
case 'LINK': return 'link';
|
16 |
case 'MAP': return 'directions';
|
17 |
+
case 'PHONE': return 'call';
|
18 |
+
case 'SMS': return 'chat';
|
19 |
+
case 'WHATSAPP': return 'whatsapp';
|
20 |
default:
|
21 |
return 'call';
|
22 |
}
|
resources/js/call-now-button.js
CHANGED
@@ -329,6 +329,8 @@ function cnb_action_update_appearance(value) {
|
|
329 |
const emailExtraEle = jQuery('.cnb-action-properties-email-extra');
|
330 |
const whatsappEle = jQuery('.cnb-action-properties-whatsapp');
|
331 |
const whatsappExtraEle = jQuery('.cnb-action-properties-whatsapp-extra');
|
|
|
|
|
332 |
|
333 |
const propertiesEle = jQuery('.cnb-action-properties-map');
|
334 |
const valueEle = jQuery('.cnb-action-value');
|
@@ -339,9 +341,10 @@ function cnb_action_update_appearance(value) {
|
|
339 |
emailExtraEle.hide();
|
340 |
whatsappEle.hide();
|
341 |
whatsappExtraEle.hide();
|
|
|
|
|
342 |
propertiesEle.hide();
|
343 |
|
344 |
-
|
345 |
valueEle.show();
|
346 |
valueTextEle.prop( 'disabled', false );
|
347 |
whatsappValueEle.prop( 'disabled', true );
|
@@ -350,22 +353,35 @@ function cnb_action_update_appearance(value) {
|
|
350 |
whatsappValueEle.removeAttr("required")
|
351 |
|
352 |
switch (value) {
|
353 |
-
case 'PHONE':
|
354 |
-
valuelabelEle.text('Phone number');
|
355 |
-
valueTextEle.attr("required", "required");
|
356 |
-
break
|
357 |
case 'ANCHOR':
|
358 |
valuelabelEle.text('On-page anchor');
|
359 |
valueTextEle.attr("required", "required");
|
360 |
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
case 'LINK':
|
362 |
valuelabelEle.text('Full URL');
|
363 |
valueTextEle.attr("required", "required");
|
364 |
break
|
365 |
-
case '
|
366 |
-
valuelabelEle.text('
|
367 |
valueTextEle.attr("required", "required");
|
368 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
break
|
370 |
case 'WHATSAPP':
|
371 |
valuelabelEle.text('Whatsapp number');
|
@@ -375,11 +391,6 @@ function cnb_action_update_appearance(value) {
|
|
375 |
whatsappEle.show();
|
376 |
whatsappValueEle.attr("required", "required");
|
377 |
break
|
378 |
-
case 'MAP':
|
379 |
-
valuelabelEle.text('Address');
|
380 |
-
valueTextEle.attr("required", "required");
|
381 |
-
propertiesEle.show();
|
382 |
-
break
|
383 |
default:
|
384 |
valuelabelEle.text('Action value');
|
385 |
valueTextEle.attr("required", "required");
|
329 |
const emailExtraEle = jQuery('.cnb-action-properties-email-extra');
|
330 |
const whatsappEle = jQuery('.cnb-action-properties-whatsapp');
|
331 |
const whatsappExtraEle = jQuery('.cnb-action-properties-whatsapp-extra');
|
332 |
+
const smsEle = jQuery('.cnb-action-properties-sms');
|
333 |
+
const smsExtraEle = jQuery('.cnb-action-properties-sms-extra');
|
334 |
|
335 |
const propertiesEle = jQuery('.cnb-action-properties-map');
|
336 |
const valueEle = jQuery('.cnb-action-value');
|
341 |
emailExtraEle.hide();
|
342 |
whatsappEle.hide();
|
343 |
whatsappExtraEle.hide();
|
344 |
+
smsEle.hide();
|
345 |
+
smsExtraEle.hide();
|
346 |
propertiesEle.hide();
|
347 |
|
|
|
348 |
valueEle.show();
|
349 |
valueTextEle.prop( 'disabled', false );
|
350 |
whatsappValueEle.prop( 'disabled', true );
|
353 |
whatsappValueEle.removeAttr("required")
|
354 |
|
355 |
switch (value) {
|
|
|
|
|
|
|
|
|
356 |
case 'ANCHOR':
|
357 |
valuelabelEle.text('On-page anchor');
|
358 |
valueTextEle.attr("required", "required");
|
359 |
break
|
360 |
+
case 'EMAIL':
|
361 |
+
valuelabelEle.text('E-mail address');
|
362 |
+
valueTextEle.attr("required", "required");
|
363 |
+
emailEle.show()
|
364 |
+
break
|
365 |
+
case 'HOURS':
|
366 |
+
// Not implemented yet
|
367 |
+
break;
|
368 |
case 'LINK':
|
369 |
valuelabelEle.text('Full URL');
|
370 |
valueTextEle.attr("required", "required");
|
371 |
break
|
372 |
+
case 'MAP':
|
373 |
+
valuelabelEle.text('Address');
|
374 |
valueTextEle.attr("required", "required");
|
375 |
+
propertiesEle.show();
|
376 |
+
break
|
377 |
+
case 'PHONE':
|
378 |
+
valuelabelEle.text('Phone number');
|
379 |
+
valueTextEle.attr("required", "required");
|
380 |
+
break
|
381 |
+
case 'SMS':
|
382 |
+
valuelabelEle.text('Phone number');
|
383 |
+
valueTextEle.attr("required", "required");
|
384 |
+
smsEle.show();
|
385 |
break
|
386 |
case 'WHATSAPP':
|
387 |
valuelabelEle.text('Whatsapp number');
|
391 |
whatsappEle.show();
|
392 |
whatsappValueEle.attr("required", "required");
|
393 |
break
|
|
|
|
|
|
|
|
|
|
|
394 |
default:
|
395 |
valuelabelEle.text('Action value');
|
396 |
valueTextEle.attr("required", "required");
|
resources/js/dismiss.js
CHANGED
@@ -39,10 +39,10 @@ function cnb_upgrade_notice_dismiss_listener() {
|
|
39 |
})
|
40 |
}
|
41 |
|
42 |
-
function
|
43 |
-
jQuery('#welcome-
|
44 |
cnb_decrease_sidenav_counter();
|
45 |
-
jQuery('#welcome-
|
46 |
})
|
47 |
}
|
48 |
|
@@ -62,5 +62,5 @@ jQuery(() => {
|
|
62 |
cnb_add_jquery_textnodes();
|
63 |
cnb_dismissables_listener();
|
64 |
cnb_upgrade_notice_dismiss_listener();
|
65 |
-
|
66 |
})
|
39 |
})
|
40 |
}
|
41 |
|
42 |
+
function cnb_welcome_banner_dismiss_listener() {
|
43 |
+
jQuery('#welcome-banner').on('click', '.notice-dismiss', () => {
|
44 |
cnb_decrease_sidenav_counter();
|
45 |
+
jQuery('#welcome-banner').remove();
|
46 |
})
|
47 |
}
|
48 |
|
62 |
cnb_add_jquery_textnodes();
|
63 |
cnb_dismissables_listener();
|
64 |
cnb_upgrade_notice_dismiss_listener();
|
65 |
+
cnb_welcome_banner_dismiss_listener();
|
66 |
})
|
resources/js/preview.js
CHANGED
@@ -66,6 +66,14 @@ function livePreview() {
|
|
66 |
// Ensure it is always visible
|
67 |
parsedData.cnb.options.displayMode = 'ALWAYS';
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
// Ensure a Multi button / Buttonbar gets its actions
|
70 |
if (typeof cnb_actions !== 'undefined') {
|
71 |
if (parsedData &&
|
@@ -79,6 +87,7 @@ function livePreview() {
|
|
79 |
}
|
80 |
}
|
81 |
|
|
|
82 |
// Fix iconenabled (should be true/false instead of 0/1)
|
83 |
if (parsedData.action_id && parsedData.actions &&
|
84 |
parsedData.actions[parsedData.action_id]) {
|
@@ -150,5 +159,7 @@ function initButtonEdit() {
|
|
150 |
|
151 |
|
152 |
jQuery(() => {
|
|
|
|
|
153 |
initButtonEdit()
|
154 |
})
|
66 |
// Ensure it is always visible
|
67 |
parsedData.cnb.options.displayMode = 'ALWAYS';
|
68 |
|
69 |
+
// Ensure all Actions are visible
|
70 |
+
if (typeof cnb_actions !== 'undefined' && cnb_ignore_schedule) {
|
71 |
+
cnb_actions = cnb_actions.map((item) => {
|
72 |
+
item.schedule.showAlways = true;
|
73 |
+
return item
|
74 |
+
});
|
75 |
+
}
|
76 |
+
|
77 |
// Ensure a Multi button / Buttonbar gets its actions
|
78 |
if (typeof cnb_actions !== 'undefined') {
|
79 |
if (parsedData &&
|
87 |
}
|
88 |
}
|
89 |
|
90 |
+
|
91 |
// Fix iconenabled (should be true/false instead of 0/1)
|
92 |
if (parsedData.action_id && parsedData.actions &&
|
93 |
parsedData.actions[parsedData.action_id]) {
|
159 |
|
160 |
|
161 |
jQuery(() => {
|
162 |
+
// Default, we show all actions
|
163 |
+
window.cnb_ignore_schedule = true;
|
164 |
initButtonEdit()
|
165 |
})
|
resources/js/settings.js
CHANGED
@@ -1,3 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
/**
|
2 |
* This calls the admin-ajax action called 'cnb_email_activation' (function cnb_admin_cnb_email_activation)
|
3 |
*/
|
@@ -8,22 +34,30 @@ function cnb_email_activation(admin_email) {
|
|
8 |
'admin_email': admin_email
|
9 |
};
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
// Send remove request
|
18 |
jQuery.post(ajaxurl, data)
|
19 |
.done((result) => {
|
20 |
if (result && result.email) {
|
21 |
-
|
|
|
22 |
jQuery('#cnb_email_activation_email').text(result.email)
|
23 |
}
|
24 |
|
25 |
if (result && result.errors) {
|
26 |
-
|
|
|
27 |
|
28 |
const keys = Object.keys(result.errors)
|
29 |
keys.forEach((key) => {
|
@@ -36,7 +70,8 @@ function cnb_email_activation(admin_email) {
|
|
36 |
}
|
37 |
})
|
38 |
.fail((result) => {
|
39 |
-
|
|
|
40 |
|
41 |
// Create Text Nodes to ensure escaping of the content
|
42 |
const codeMsg = document.createTextNode(result.status + ' ' + result.statusText)
|
@@ -53,6 +88,21 @@ function cnb_email_activation_alternate() {
|
|
53 |
return cnb_email_activation(alternate_admin_email);
|
54 |
}
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
function init_settings() {
|
57 |
jQuery("#cnb_email_activation_alternate_form").hide()
|
58 |
}
|
1 |
+
function cnb_email_activation_reenable_fields() {
|
2 |
+
const errorMessage = '<h3 class="title">Something went wrong!</h3>' +
|
3 |
+
'<p>Something has gone wrong and we do not know why...</p>' +
|
4 |
+
'<p>As unlikely as it is, our service might be experiencing issues (check <a href="https://status.callnowbutton.com">our status page</a>).</p>' +
|
5 |
+
'<p>If you think you\'ve found a bug, please report it at our <a href="https://callnowbutton.com/support/" target="_blank">Help Center</a>.';
|
6 |
+
const errorDetails = '<p>Technical details:</p><p style="color:red"><span id="cnb_email_activation_details"></span></p>';
|
7 |
+
|
8 |
+
jQuery('#cnb_email_activation_alternate_address').removeAttr("disabled")
|
9 |
+
jQuery('#cnb_email_activation_alternate').removeAttr("disabled")
|
10 |
+
jQuery('#cnb_email_activation_alternate').val("Activate Premium")
|
11 |
+
jQuery('#cnb_email_activation').html(errorMessage + errorDetails);
|
12 |
+
}
|
13 |
+
|
14 |
+
function cnb_email_activation_taking_too_long() {
|
15 |
+
const errorMessage = '<h3 class="title">Hmm, that\'s taking a while...</h3>' +
|
16 |
+
'<p>This call should not take this long. Please try again in a minute or so.</p>' +
|
17 |
+
'<p>As unlikely as it is, our service might be experiencing issues (check <a href="https://status.callnowbutton.com">our status page</a>).</p>' +
|
18 |
+
'<p>If you think you\'ve found a bug, please report it at our <a href="https://callnowbutton.com/support/" target="_blank">Help Center</a>.';
|
19 |
+
const errorDetails = '<p>Technical details:</p><p style="color:red"><span id="cnb_email_activation_details"></span></p>';
|
20 |
+
|
21 |
+
jQuery('#cnb_email_activation_alternate_address').removeAttr("disabled")
|
22 |
+
jQuery('#cnb_email_activation_alternate').removeAttr("disabled")
|
23 |
+
jQuery('#cnb_email_activation_alternate').val("Activate Premium")
|
24 |
+
jQuery('#cnb_email_activation').html(errorMessage + errorDetails);
|
25 |
+
}
|
26 |
+
|
27 |
/**
|
28 |
* This calls the admin-ajax action called 'cnb_email_activation' (function cnb_admin_cnb_email_activation)
|
29 |
*/
|
34 |
'admin_email': admin_email
|
35 |
};
|
36 |
|
37 |
+
// Disable the Email and Button fields (reactivate in case of errors)
|
38 |
+
jQuery('#cnb_email_activation_alternate_address').attr("disabled", "disabled")
|
39 |
+
jQuery('#cnb_email_activation_alternate').attr("disabled", "disabled")
|
40 |
+
jQuery('#cnb_email_activation_alternate').val("Check your e-mail")
|
41 |
+
|
42 |
+
// Clear the error fields
|
43 |
+
jQuery('#cnb_email_activation').empty()
|
44 |
+
jQuery('#cnb_email_activation_email').empty()
|
45 |
+
|
46 |
+
const statusTimeout = 5000
|
47 |
+
const takingTooLongTimer = setTimeout(cnb_email_activation_taking_too_long, statusTimeout)
|
48 |
|
49 |
// Send remove request
|
50 |
jQuery.post(ajaxurl, data)
|
51 |
.done((result) => {
|
52 |
if (result && result.email) {
|
53 |
+
clearTimeout(takingTooLongTimer)
|
54 |
+
jQuery('#cnb_email_activation').html('<span class="cnb_check_email_message">Check your inbox for an activation email sent to <strong><span id="cnb_email_activation_email"></span></strong>.</span>')
|
55 |
jQuery('#cnb_email_activation_email').text(result.email)
|
56 |
}
|
57 |
|
58 |
if (result && result.errors) {
|
59 |
+
clearTimeout(takingTooLongTimer)
|
60 |
+
cnb_email_activation_reenable_fields()
|
61 |
|
62 |
const keys = Object.keys(result.errors)
|
63 |
keys.forEach((key) => {
|
70 |
}
|
71 |
})
|
72 |
.fail((result) => {
|
73 |
+
clearTimeout(takingTooLongTimer)
|
74 |
+
cnb_email_activation_reenable_fields()
|
75 |
|
76 |
// Create Text Nodes to ensure escaping of the content
|
77 |
const codeMsg = document.createTextNode(result.status + ' ' + result.statusText)
|
88 |
return cnb_email_activation(alternate_admin_email);
|
89 |
}
|
90 |
|
91 |
+
// Note: IDE marks this as unused, but it is used by settings.php ("Delete API key")
|
92 |
+
function cnb_delete_apikey() {
|
93 |
+
const apiKeyField = jQuery(".call-now-button #cnb_api_key")
|
94 |
+
apiKeyField.prop("type", "hidden");
|
95 |
+
apiKeyField.prop("value", "delete_me");
|
96 |
+
apiKeyField.removeAttr("disabled");
|
97 |
+
|
98 |
+
// Ensure we use the exact verbiage of the Submit button
|
99 |
+
const saveVal = apiKeyField.parents('.cnb-container').find('#submit').val();
|
100 |
+
jQuery('.call-now-button #cnb_api_key_delete').replaceWith("<p>Click <strong>"+saveVal+"</strong> to disconnect your account.</p>")
|
101 |
+
|
102 |
+
// Present the default behavior of this submit button (since it needs to be actioned on by the *actual* submit button
|
103 |
+
return false;
|
104 |
+
}
|
105 |
+
|
106 |
function init_settings() {
|
107 |
jQuery("#cnb_email_activation_alternate_form").hide()
|
108 |
}
|
resources/style/call-now-button.css
CHANGED
@@ -48,6 +48,15 @@ Universal CNB admin styling options
|
|
48 |
text-decoration: underline;
|
49 |
}
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
.cnb_footer_beta {
|
52 |
border: 1px solid;
|
53 |
border-radius: 3px;
|
@@ -147,6 +156,18 @@ table.form-table.nav-tab-active,
|
|
147 |
font-size: 14px;
|
148 |
}
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
table.form-table.nav-tab-only {
|
151 |
display: table;
|
152 |
}
|
@@ -366,7 +387,7 @@ input[type='range'] {
|
|
366 |
border: 1px solid #c3c4c7;
|
367 |
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
368 |
background: #fff;
|
369 |
-
margin
|
370 |
max-width:1000px;
|
371 |
}
|
372 |
|
@@ -701,6 +722,17 @@ input[type=checkbox].cnb_day_selector:checked + label.cnb_day_selector {
|
|
701 |
/*
|
702 |
Preview phone and button placement
|
703 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
704 |
#phone-preview .phone-outside > div {
|
705 |
position: absolute;
|
706 |
}
|
@@ -745,7 +777,7 @@ Preview phone and button placement
|
|
745 |
margin-left: -30px;
|
746 |
}
|
747 |
#cnb-button-preview {
|
748 |
-
position: relative;
|
749 |
height: 100%;
|
750 |
overflow: hidden;
|
751 |
}
|
@@ -757,7 +789,7 @@ Enforce mobile viewport for previews via overwrites:
|
|
757 |
#cnb-button-preview .cnb-full,
|
758 |
#cnb-button-preview .cnb-multi,
|
759 |
#cnb-button-preview .cnb-single {
|
760 |
-
position: absolute;
|
761 |
z-index: 99998 !important;
|
762 |
}
|
763 |
#cnb-button-preview .cnb-full:before {
|
@@ -784,12 +816,69 @@ Enforce mobile viewport for previews via overwrites:
|
|
784 |
}
|
785 |
|
786 |
/*
|
787 |
-
Welcome
|
788 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
789 |
.welcome-column-box {
|
790 |
padding-right: 10px;
|
791 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
792 |
@media screen and (max-width: 870px) {
|
|
|
|
|
|
|
|
|
793 |
.cnb-mobile-inline {
|
794 |
display: inline-block;
|
795 |
margin-bottom:0;
|
@@ -797,19 +886,15 @@ Welcome panel styling
|
|
797 |
.only-in-columns {
|
798 |
display: none;
|
799 |
}
|
800 |
-
.call-now-button .welcome-
|
801 |
margin-top:22px !important;
|
802 |
}
|
803 |
}
|
804 |
@media screen and (max-width: 600px) {
|
805 |
-
.
|
806 |
-
|
807 |
-
|
808 |
}
|
809 |
-
.cnb-mobile-inline {
|
810 |
-
display: block;
|
811 |
-
margin-bottom:0;
|
812 |
-
}
|
813 |
|
814 |
}
|
815 |
|
@@ -832,9 +917,72 @@ a.cnb-nav-tab:hover {
|
|
832 |
background-color: #fff;
|
833 |
color: #3c434a;
|
834 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
835 |
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
840 |
}
|
48 |
text-decoration: underline;
|
49 |
}
|
50 |
|
51 |
+
.top-0 {
|
52 |
+
margin-top: 0;
|
53 |
+
padding-top: 0;
|
54 |
+
}
|
55 |
+
.bottom-0 {
|
56 |
+
margin-bottom: 0;
|
57 |
+
padding-bottom: 0;
|
58 |
+
}
|
59 |
+
|
60 |
.cnb_footer_beta {
|
61 |
border: 1px solid;
|
62 |
border-radius: 3px;
|
156 |
font-size: 14px;
|
157 |
}
|
158 |
|
159 |
+
#TB_window {
|
160 |
+
top:10px !important;
|
161 |
+
margin-top:0 !important;
|
162 |
+
}
|
163 |
+
.call-now-button0_page_call-now-button-domains #TB_window {
|
164 |
+
height: 97%;
|
165 |
+
}
|
166 |
+
.call-now-button0_page_call-now-button-domains #TB_ajaxContent {
|
167 |
+
height: calc(100% - 32px) !important;
|
168 |
+
padding: 0 15px !important;
|
169 |
+
}
|
170 |
+
|
171 |
table.form-table.nav-tab-only {
|
172 |
display: table;
|
173 |
}
|
387 |
border: 1px solid #c3c4c7;
|
388 |
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
389 |
background: #fff;
|
390 |
+
margin: 5px;
|
391 |
max-width:1000px;
|
392 |
}
|
393 |
|
722 |
/*
|
723 |
Preview phone and button placement
|
724 |
*/
|
725 |
+
#phone-preview {
|
726 |
+
margin-bottom: 50px;
|
727 |
+
}
|
728 |
+
#phone-preview .phone-outside:after {
|
729 |
+
content: '*The preview ignores the scheduler';
|
730 |
+
bottom: -25px;
|
731 |
+
position: absolute;
|
732 |
+
font-style: italic;
|
733 |
+
width: 100%;
|
734 |
+
text-align: center;
|
735 |
+
}
|
736 |
#phone-preview .phone-outside > div {
|
737 |
position: absolute;
|
738 |
}
|
777 |
margin-left: -30px;
|
778 |
}
|
779 |
#cnb-button-preview {
|
780 |
+
position: relative !important;
|
781 |
height: 100%;
|
782 |
overflow: hidden;
|
783 |
}
|
789 |
#cnb-button-preview .cnb-full,
|
790 |
#cnb-button-preview .cnb-multi,
|
791 |
#cnb-button-preview .cnb-single {
|
792 |
+
position: absolute !important;
|
793 |
z-index: 99998 !important;
|
794 |
}
|
795 |
#cnb-button-preview .cnb-full:before {
|
816 |
}
|
817 |
|
818 |
/*
|
819 |
+
Welcome banner styling
|
820 |
*/
|
821 |
+
.welcome-banner {
|
822 |
+
position: relative;
|
823 |
+
overflow: auto;
|
824 |
+
margin: 16px 0;
|
825 |
+
padding: 23px 10px 10px;
|
826 |
+
border: 1px solid #c3c4c7;
|
827 |
+
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
828 |
+
background: #fff;
|
829 |
+
font-size: 13px;
|
830 |
+
line-height: 1.7;
|
831 |
+
}
|
832 |
+
.welcome-banner h2 {
|
833 |
+
margin: 0;
|
834 |
+
font-size: 21px;
|
835 |
+
font-weight: 400;
|
836 |
+
line-height: 1.2;
|
837 |
+
}
|
838 |
+
.welcome-banner h3 {
|
839 |
+
margin-bottom:0.5em;
|
840 |
+
}
|
841 |
+
.welcome-banner .about-description {
|
842 |
+
font-size: 16px;
|
843 |
+
margin: 0;
|
844 |
+
}
|
845 |
+
.welcome-banner-content {
|
846 |
+
margin-left: 13px;
|
847 |
+
max-width: 1500px;
|
848 |
+
}
|
849 |
+
.welcome-banner p {
|
850 |
+
color: #646970;
|
851 |
+
margin:0.5em 0;
|
852 |
+
}
|
853 |
+
.welcome-banner .welcome-banner-column-container {
|
854 |
+
clear: both;
|
855 |
+
position: relative;
|
856 |
+
}
|
857 |
+
.welcome-banner .welcome-banner-column {
|
858 |
+
width: 32%;
|
859 |
+
min-width: 200px;
|
860 |
+
float: left;
|
861 |
+
}
|
862 |
+
.welcome-banner .welcome-banner-column:first-child {
|
863 |
+
width: 36%;
|
864 |
+
}
|
865 |
.welcome-column-box {
|
866 |
padding-right: 10px;
|
867 |
}
|
868 |
+
.welcome-banner .welcome-banner-close {
|
869 |
+
position: absolute;
|
870 |
+
top: 10px;
|
871 |
+
right: 10px;
|
872 |
+
padding: 10px 15px 10px 21px;
|
873 |
+
font-size: 13px;
|
874 |
+
line-height: 1.23076923;
|
875 |
+
text-decoration: none;
|
876 |
+
}
|
877 |
@media screen and (max-width: 870px) {
|
878 |
+
.welcome-banner .welcome-banner-column,
|
879 |
+
.welcome-banner .welcome-banner-column:first-child {
|
880 |
+
width: 100%;
|
881 |
+
}
|
882 |
.cnb-mobile-inline {
|
883 |
display: inline-block;
|
884 |
margin-bottom:0;
|
886 |
.only-in-columns {
|
887 |
display: none;
|
888 |
}
|
889 |
+
.call-now-button .welcome-banner-column .button {
|
890 |
margin-top:22px !important;
|
891 |
}
|
892 |
}
|
893 |
@media screen and (max-width: 600px) {
|
894 |
+
.cnb-mobile-inline {
|
895 |
+
display: block;
|
896 |
+
margin-bottom:0;
|
897 |
}
|
|
|
|
|
|
|
|
|
898 |
|
899 |
}
|
900 |
|
917 |
background-color: #fff;
|
918 |
color: #3c434a;
|
919 |
}
|
920 |
+
/* Message when email activation was initiated */
|
921 |
+
input.cnb_activation_input_field {
|
922 |
+
width:calc(100% - 158px);
|
923 |
+
max-width: 25em;
|
924 |
+
}
|
925 |
+
span.cnb_check_email_message {
|
926 |
+
background-color: #fff;
|
927 |
+
display: block;
|
928 |
+
padding: 5px;
|
929 |
+
text-align: center;
|
930 |
+
border: 1px solid #2271b1;
|
931 |
+
border-radius: 4px;
|
932 |
+
}
|
933 |
+
.notice-call-now-button span.cnb_check_email_message {
|
934 |
+
border-radius: 0;
|
935 |
+
border: 0;
|
936 |
+
border-top: 1px solid #2271b1;
|
937 |
+
border-bottom: 1px solid #2271b1;
|
938 |
+
background-color: #f7f7f7;
|
939 |
+
padding:15px 5px;
|
940 |
+
text-align: left;
|
941 |
+
}
|
942 |
+
@media screen and (max-width: 450px) {
|
943 |
+
input.cnb_activation_input_field {
|
944 |
+
width: 100%;
|
945 |
+
margin-bottom: 10px;
|
946 |
+
}
|
947 |
+
input.cnb_activation_input_field ~ input[type=submit] {
|
948 |
+
width: 100%;
|
949 |
+
}
|
950 |
+
.notice-call-now-button span.cnb_check_email_message {
|
951 |
+
text-align: center;
|
952 |
+
}
|
953 |
+
}
|
954 |
+
/* There's currently no native class for a delete button. Adding our own */
|
955 |
+
.wp-core-ui .button.delete {
|
956 |
+
color: #c00;
|
957 |
+
border-color: #c00;
|
958 |
+
}
|
959 |
+
.wp-core-ui .button.delete:focus,
|
960 |
+
.wp-core-ui .button.delete:focus-visible {
|
961 |
+
outline-color: #C00;
|
962 |
+
}
|
963 |
|
964 |
+
|
965 |
+
.cnb-scheduler-slider .ui-slider-horizontal {
|
966 |
+
border:0 !important;
|
967 |
+
}
|
968 |
+
.cnb-scheduler-slider .ui-state-active,
|
969 |
+
.cnb-scheduler-slider .ui-widget-content .ui-state-active,
|
970 |
+
.cnb-scheduler-slider .ui-widget-header .ui-state-active,
|
971 |
+
.cnb-scheduler-slider a.ui-button:active,
|
972 |
+
.cnb-scheduler-slider .ui-button:active,
|
973 |
+
.cnb-scheduler-slider .ui-button.ui-state-active:hover {
|
974 |
+
border: 1px solid #2371b1;
|
975 |
+
background: #fff;
|
976 |
+
font-weight: normal;
|
977 |
+
color: #fff
|
978 |
+
}
|
979 |
+
.cnb-scheduler-slider p:first-child {
|
980 |
+
margin-bottom:1em;
|
981 |
+
}
|
982 |
+
.cnb-promobox-action-left #cnb_email_activation_alternate_formd:before {
|
983 |
+
content: '*The Premium Free plan is for websites with up to 20k pageviews per month. More popular websites can try it out but are required to upgrade to a PRO plan once the limit gets hit.';
|
984 |
+
display: block;
|
985 |
+
padding-left: 12px;
|
986 |
+
padding-bottom: 16px;
|
987 |
+
color: #646970;
|
988 |
}
|
src/admin/action-edit.php
CHANGED
@@ -278,6 +278,17 @@ function cnb_wp_locale_day_to_daysofweek_array_index($wp_locale_day) {
|
|
278 |
return $wp_locale_day - 1;
|
279 |
}
|
280 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
/**
|
282 |
* @param $action CnbAction
|
283 |
* @param $button CnbButton
|
@@ -285,21 +296,15 @@ function cnb_wp_locale_day_to_daysofweek_array_index($wp_locale_day) {
|
|
285 |
* @param $show_table boolean
|
286 |
*/
|
287 |
function cnb_render_form_action($action, $button=null, $domain=null, $show_table=true) {
|
288 |
-
// In case a domain is not passed, we take it from the button
|
289 |
-
$domain = isset($domain) ? $domain : (isset($button) ? $button->domain : null);
|
290 |
/**
|
291 |
* @global WP_Locale $wp_locale WordPress date and time locale object.
|
292 |
*/
|
293 |
global $wp_locale;
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
* This array only signifies the order to DISPLAY the days in the UI according to WP_Locale
|
300 |
-
* So, in this case, we make the UI render the week starting on Monday (1) and end on Sunday (0).
|
301 |
-
*/
|
302 |
-
$cnb_days_of_week_order = array(1,2,3,4,5,6,0);
|
303 |
|
304 |
if (empty($action->actionType)) {
|
305 |
$action->actionType = 'PHONE';
|
@@ -313,11 +318,13 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
313 |
wp_enqueue_script('jquery');
|
314 |
wp_enqueue_script('jquery-ui-core');
|
315 |
wp_enqueue_script('jquery-ui-slider');
|
|
|
316 |
|
317 |
// Uses domain timezone if no timezone can be found
|
318 |
$timezone = (isset($action->schedule) && !empty($action->schedule->timezone)) ? $action->schedule->timezone : (isset($domain) ? $domain->timezone : null);
|
319 |
$action_tz_different_from_domain = isset($domain) && !empty($domain->timezone) && $domain->timezone !== $timezone;
|
320 |
cnb_domain_timezone_check( $domain );
|
|
|
321 |
?>
|
322 |
<input type="hidden" name="actions[<?php esc_attr_e($action->id) ?>][id]" value="<?php if ($action->id !== null && $action->id !== 'new') { esc_attr_e($action->id); } ?>" />
|
323 |
<input type="hidden" name="actions[<?php esc_attr_e($action->id) ?>][delete]" id="cnb_action_<?php esc_attr_e($action->id) ?>_delete" value="" />
|
@@ -401,20 +408,25 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
401 |
<th colspan="2"><hr /></th>
|
402 |
</tr>
|
403 |
|
|
|
|
|
|
|
|
|
|
|
404 |
<tr class="cnb-action-properties-whatsapp">
|
405 |
<th></th>
|
406 |
<td><a class="cnb_cursor_pointer" onclick="jQuery('.cnb-action-properties-whatsapp-extra').show();jQuery(this).parent().parent().hide()">Extra Whatsapp settings...</a></td>
|
407 |
</tr>
|
408 |
-
<tr class="cnb-action-properties-whatsapp-extra">
|
409 |
<th colspan="2"><hr /></th>
|
410 |
</tr>
|
411 |
-
<tr class="cnb-action-properties-whatsapp-extra">
|
412 |
<th scope="row"><label for="action-properties-message">Default message</label></th>
|
413 |
<td>
|
414 |
<textarea id="action-properties-message" name="actions[<?php esc_attr_e($action->id) ?>][properties][message]" class="large-text code" rows="3"><?php if (isset($action->properties) && isset($action->properties->message)) { echo esc_textarea($action->properties->message); } ?></textarea>
|
415 |
</td>
|
416 |
</tr>
|
417 |
-
<tr class="cnb-action-properties-whatsapp-extra">
|
418 |
<th colspan="2"><hr /></th>
|
419 |
</tr>
|
420 |
|
@@ -464,14 +476,21 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
464 |
<?php } ?>
|
465 |
|
466 |
<tr class="cnb_hide_on_modal">
|
467 |
-
<th scope="row">
|
468 |
<td>
|
|
|
469 |
<input name="actions[<?php esc_attr_e($action->id) ?>][schedule][showAlways]" type="hidden" value="false" />
|
470 |
<input id="actions_schedule_show_always" class="cnb_toggle_checkbox" onchange="return cnb_hide_on_show_always();" name="actions[<?php esc_attr_e($action->id) ?>][schedule][showAlways]" type="checkbox"
|
471 |
-
value="true" <?php checked(true, $
|
|
|
472 |
<label for="actions_schedule_show_always" class="cnb_toggle_label">Toggle</label>
|
473 |
-
<span data-cnb_toggle_state_label="actions_schedule_show_always" class="cnb_toggle_state
|
474 |
-
|
|
|
|
|
|
|
|
|
|
|
475 |
</td>
|
476 |
</tr>
|
477 |
<tr>
|
@@ -480,7 +499,7 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
480 |
</td>
|
481 |
</tr>
|
482 |
<tr class="cnb_hide_on_show_always">
|
483 |
-
<th>
|
484 |
<td>
|
485 |
<?php
|
486 |
foreach ($cnb_days_of_week_order as $cnb_day_of_week) {
|
@@ -499,12 +518,27 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
499 |
</td>
|
500 |
</tr>
|
501 |
<tr class="cnb_hide_on_show_always">
|
502 |
-
<th><label for="
|
503 |
-
<td
|
|
|
|
|
|
|
|
|
504 |
</tr>
|
505 |
<tr class="cnb_hide_on_show_always">
|
506 |
-
<th
|
507 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
508 |
</tr>
|
509 |
<tr class="cnb_hide_on_show_always<?php if (!$action_tz_different_from_domain) { ?> cnb_advanced_view<?php } ?>">
|
510 |
<th><label for="actions[<?php esc_attr_e($action->id) ?>][schedule][timezone]">Timezone</label></th>
|
@@ -528,17 +562,6 @@ function cnb_render_form_action($action, $button=null, $domain=null, $show_table
|
|
528 |
<?php } ?>
|
529 |
</td>
|
530 |
</tr>
|
531 |
-
<tr class="cnb_hide_on_show_always">
|
532 |
-
<th><label for="actions_schedule_outside_hours">After hours</label></th>
|
533 |
-
<td>
|
534 |
-
<input id="actions_schedule_outside_hours" class="cnb_toggle_checkbox" name="actions[<?php esc_attr_e($action->id) ?>][schedule][outsideHours]" type="checkbox"
|
535 |
-
value="true" <?php checked(true, isset($action->schedule) && $action->schedule->outsideHours); ?> />
|
536 |
-
<label for="actions_schedule_outside_hours" class="cnb_toggle_label">Toggle</label>
|
537 |
-
<span data-cnb_toggle_state_label="actions_schedule_outside_hours" class="cnb_toggle_state cnb_toggle_false">Button shows between set hours</span>
|
538 |
-
<span data-cnb_toggle_state_label="actions_schedule_outside_hours" class="cnb_toggle_state cnb_toggle_true">Button shows outside set hours</span>
|
539 |
-
|
540 |
-
</td>
|
541 |
-
</tr>
|
542 |
<?php if ($show_table) { ?>
|
543 |
</table>
|
544 |
<?php } ?>
|
@@ -567,8 +590,7 @@ function cnb_admin_page_action_edit_render_main($action, $button, $domain=null,
|
|
567 |
? boolval($action->iconEnabled)
|
568 |
: true;
|
569 |
?>
|
570 |
-
|
571 |
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/css/intlTelInput.min.css" integrity="sha512-yye/u0ehQsrVrfSd6biT17t39Rg9kNc+vENcCXZuMz2a+LWFGvXUnYuWUW6pbfYj1jcBb/C39UZw2ciQvwDDvg==" crossorigin="anonymous" />
|
572 |
<input type="hidden" name="bid" value="<?php echo $bid ?>" />
|
573 |
<input type="hidden" name="action_id" value="<?php echo $action->id ?>" />
|
574 |
<input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('cnb-action-edit')?>" />
|
@@ -628,6 +650,7 @@ function cnb_admin_page_action_edit_render() {
|
|
628 |
wp_enqueue_script(CNB_SLUG . '-client');
|
629 |
|
630 |
do_action('cnb_header');
|
|
|
631 |
?>
|
632 |
<div class="cnb-two-column-section-preview">
|
633 |
<div class="cnb-body-column">
|
@@ -645,7 +668,6 @@ function cnb_admin_page_action_edit_render() {
|
|
645 |
let cnb_button = <?php echo json_encode($button); ?>;
|
646 |
let cnb_actions = <?php echo json_encode($button->actions); ?>;
|
647 |
let cnb_domain = <?php echo json_encode($button->domain) ?>;
|
648 |
-
|
649 |
</script>
|
650 |
|
651 |
<form class="cnb-container" action="<?php echo $redirect_link; ?>" method="post">
|
278 |
return $wp_locale_day - 1;
|
279 |
}
|
280 |
|
281 |
+
/**
|
282 |
+
* CNB week starts on Monday (0), WP_Local starts on Sunday (0)
|
283 |
+
* See cnb_wp_locale_day_to_daysofweek_array_index()
|
284 |
+
*
|
285 |
+
* This array only signifies the order to DISPLAY the days in the UI according to WP_Locale
|
286 |
+
* So, in this case, we make the UI render the week starting on Monday (1) and end on Sunday (0).
|
287 |
+
*/
|
288 |
+
function cnb_wp_get_order_of_days() {
|
289 |
+
return array(1,2,3,4,5,6,0);
|
290 |
+
}
|
291 |
+
|
292 |
/**
|
293 |
* @param $action CnbAction
|
294 |
* @param $button CnbButton
|
296 |
* @param $show_table boolean
|
297 |
*/
|
298 |
function cnb_render_form_action($action, $button=null, $domain=null, $show_table=true) {
|
|
|
|
|
299 |
/**
|
300 |
* @global WP_Locale $wp_locale WordPress date and time locale object.
|
301 |
*/
|
302 |
global $wp_locale;
|
303 |
+
|
304 |
+
// In case a domain is not passed, we take it from the button
|
305 |
+
$domain = isset($domain) ? $domain : (isset($button) ? $button->domain : null);
|
306 |
+
|
307 |
+
$cnb_days_of_week_order = cnb_wp_get_order_of_days();
|
|
|
|
|
|
|
|
|
308 |
|
309 |
if (empty($action->actionType)) {
|
310 |
$action->actionType = 'PHONE';
|
318 |
wp_enqueue_script('jquery');
|
319 |
wp_enqueue_script('jquery-ui-core');
|
320 |
wp_enqueue_script('jquery-ui-slider');
|
321 |
+
wp_enqueue_script(CNB_SLUG . '-action-edit-scheduler');
|
322 |
|
323 |
// Uses domain timezone if no timezone can be found
|
324 |
$timezone = (isset($action->schedule) && !empty($action->schedule->timezone)) ? $action->schedule->timezone : (isset($domain) ? $domain->timezone : null);
|
325 |
$action_tz_different_from_domain = isset($domain) && !empty($domain->timezone) && $domain->timezone !== $timezone;
|
326 |
cnb_domain_timezone_check( $domain );
|
327 |
+
$timezone_set_correctly = cnb_warn_about_timezone($domain);
|
328 |
?>
|
329 |
<input type="hidden" name="actions[<?php esc_attr_e($action->id) ?>][id]" value="<?php if ($action->id !== null && $action->id !== 'new') { esc_attr_e($action->id); } ?>" />
|
330 |
<input type="hidden" name="actions[<?php esc_attr_e($action->id) ?>][delete]" id="cnb_action_<?php esc_attr_e($action->id) ?>_delete" value="" />
|
408 |
<th colspan="2"><hr /></th>
|
409 |
</tr>
|
410 |
|
411 |
+
<tr class="cnb-action-properties-sms">
|
412 |
+
<th></th>
|
413 |
+
<td><a class="cnb_cursor_pointer" onclick="jQuery('.cnb-action-properties-sms-extra').show();jQuery(this).parent().parent().hide()">Extra SMS settings...</a></td>
|
414 |
+
</tr>
|
415 |
+
|
416 |
<tr class="cnb-action-properties-whatsapp">
|
417 |
<th></th>
|
418 |
<td><a class="cnb_cursor_pointer" onclick="jQuery('.cnb-action-properties-whatsapp-extra').show();jQuery(this).parent().parent().hide()">Extra Whatsapp settings...</a></td>
|
419 |
</tr>
|
420 |
+
<tr class="cnb-action-properties-whatsapp-extra cnb-action-properties-sms-extra">
|
421 |
<th colspan="2"><hr /></th>
|
422 |
</tr>
|
423 |
+
<tr class="cnb-action-properties-whatsapp-extra cnb-action-properties-sms-extra">
|
424 |
<th scope="row"><label for="action-properties-message">Default message</label></th>
|
425 |
<td>
|
426 |
<textarea id="action-properties-message" name="actions[<?php esc_attr_e($action->id) ?>][properties][message]" class="large-text code" rows="3"><?php if (isset($action->properties) && isset($action->properties->message)) { echo esc_textarea($action->properties->message); } ?></textarea>
|
427 |
</td>
|
428 |
</tr>
|
429 |
+
<tr class="cnb-action-properties-whatsapp-extra cnb-action-properties-sms-extra">
|
430 |
<th colspan="2"><hr /></th>
|
431 |
</tr>
|
432 |
|
476 |
<?php } ?>
|
477 |
|
478 |
<tr class="cnb_hide_on_modal">
|
479 |
+
<th scope="row">Show at all times</th>
|
480 |
<td>
|
481 |
+
<?php $showAlwaysValue = $action->id === 'new' || $action->schedule->showAlways; ?>
|
482 |
<input name="actions[<?php esc_attr_e($action->id) ?>][schedule][showAlways]" type="hidden" value="false" />
|
483 |
<input id="actions_schedule_show_always" class="cnb_toggle_checkbox" onchange="return cnb_hide_on_show_always();" name="actions[<?php esc_attr_e($action->id) ?>][schedule][showAlways]" type="checkbox"
|
484 |
+
value="true" <?php checked(true, $showAlwaysValue); ?>
|
485 |
+
<?php if (!$timezone_set_correctly) { ?>disabled="disabled" <?php } ?>/>
|
486 |
<label for="actions_schedule_show_always" class="cnb_toggle_label">Toggle</label>
|
487 |
+
<span data-cnb_toggle_state_label="actions_schedule_show_always" class="cnb_toggle_state cnb_toggle_true">Yes <?php if (!$timezone_set_correctly) { ?>(disabled)<?php } ?></span>
|
488 |
+
<?php if (!$timezone_set_correctly && $showAlwaysValue){ ?>
|
489 |
+
<p class="description"><span class="dashicons dashicons-warning"></span>The scheduler is disabled because your timezone is not set correctly yet.</p>
|
490 |
+
<?php } ?>
|
491 |
+
<?php if (!$timezone_set_correctly && !$showAlwaysValue){ ?>
|
492 |
+
<p class="description"><span class="dashicons dashicons-warning"></span>Please set your timezone before making any more changes. See the notice at the top of the page for more information.</p>
|
493 |
+
<?php } ?>
|
494 |
</td>
|
495 |
</tr>
|
496 |
<tr>
|
499 |
</td>
|
500 |
</tr>
|
501 |
<tr class="cnb_hide_on_show_always">
|
502 |
+
<th>Set days</th>
|
503 |
<td>
|
504 |
<?php
|
505 |
foreach ($cnb_days_of_week_order as $cnb_day_of_week) {
|
518 |
</td>
|
519 |
</tr>
|
520 |
<tr class="cnb_hide_on_show_always">
|
521 |
+
<th><label for="actions_schedule_outside_hours">After hours</label></th>
|
522 |
+
<td>
|
523 |
+
<input id="actions_schedule_outside_hours" class="cnb_toggle_checkbox" name="actions[<?php esc_attr_e($action->id) ?>][schedule][outsideHours]" type="checkbox"
|
524 |
+
value="true" <?php checked(true, isset($action->schedule) && $action->schedule->outsideHours); ?> />
|
525 |
+
<label for="actions_schedule_outside_hours" class="cnb_toggle_label">Toggle</label>
|
526 |
+
</td>
|
527 |
</tr>
|
528 |
<tr class="cnb_hide_on_show_always">
|
529 |
+
<th>Set times</th>
|
530 |
+
<td class="cnb-scheduler-slider">
|
531 |
+
<p id="cnb-schedule-range-text"></p>
|
532 |
+
<div id="cnb-schedule-range" style="max-width: 300px"></div>
|
533 |
+
</td>
|
534 |
+
</tr>
|
535 |
+
<tr class="cnb_hide_on_show_always cnb_advanced_view">
|
536 |
+
<th><label for="actions-schedule-start">Start time</label></th>
|
537 |
+
<td><input type="time" name="actions[<?php esc_attr_e($action->id) ?>][schedule][start]" id="actions-schedule-start" value="<?php if (isset($action->schedule)) { esc_attr_e($action->schedule->start); } ?>"></td>
|
538 |
+
</tr>
|
539 |
+
<tr class="cnb_hide_on_show_always cnb_advanced_view">
|
540 |
+
<th><label for="actions-schedule-stop">End time</label></th>
|
541 |
+
<td><input type="time" name="actions[<?php esc_attr_e($action->id) ?>][schedule][stop]" id="actions-schedule-stop" value="<?php if (isset($action->schedule)) { esc_attr_e($action->schedule->stop); } ?>"></td>
|
542 |
</tr>
|
543 |
<tr class="cnb_hide_on_show_always<?php if (!$action_tz_different_from_domain) { ?> cnb_advanced_view<?php } ?>">
|
544 |
<th><label for="actions[<?php esc_attr_e($action->id) ?>][schedule][timezone]">Timezone</label></th>
|
562 |
<?php } ?>
|
563 |
</td>
|
564 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
565 |
<?php if ($show_table) { ?>
|
566 |
</table>
|
567 |
<?php } ?>
|
590 |
? boolval($action->iconEnabled)
|
591 |
: true;
|
592 |
?>
|
593 |
+
|
|
|
594 |
<input type="hidden" name="bid" value="<?php echo $bid ?>" />
|
595 |
<input type="hidden" name="action_id" value="<?php echo $action->id ?>" />
|
596 |
<input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('cnb-action-edit')?>" />
|
650 |
wp_enqueue_script(CNB_SLUG . '-client');
|
651 |
|
652 |
do_action('cnb_header');
|
653 |
+
|
654 |
?>
|
655 |
<div class="cnb-two-column-section-preview">
|
656 |
<div class="cnb-body-column">
|
668 |
let cnb_button = <?php echo json_encode($button); ?>;
|
669 |
let cnb_actions = <?php echo json_encode($button->actions); ?>;
|
670 |
let cnb_domain = <?php echo json_encode($button->domain) ?>;
|
|
|
671 |
</script>
|
672 |
|
673 |
<form class="cnb-container" action="<?php echo $redirect_link; ?>" method="post">
|
src/admin/action-overview.php
CHANGED
@@ -75,7 +75,8 @@ class Cnb_Action_List_Table extends WP_List_Table {
|
|
75 |
'id' => __('ID'),
|
76 |
'actionType' => __('Type'),
|
77 |
'actionValue' => __('Value'),
|
78 |
-
'labelText' => __('Label')
|
|
|
79 |
);
|
80 |
if ($this->button) { unset($columns['cb']); }
|
81 |
|
@@ -156,7 +157,8 @@ class Cnb_Action_List_Table extends WP_List_Table {
|
|
156 |
case 'actionValue':
|
157 |
case 'labelText':
|
158 |
return !empty($item[$column_name]) ? esc_html($item[$column_name]) : '<em>No value</em>';
|
159 |
-
// Handled by column_actionType
|
|
|
160 |
case 'actionType':
|
161 |
return null;
|
162 |
case 'actionButton':
|
@@ -218,7 +220,8 @@ class Cnb_Action_List_Table extends WP_List_Table {
|
|
218 |
'actionButton' => $button,
|
219 |
'actionType' => $action->actionType,
|
220 |
'actionValue' => $action->actionValue,
|
221 |
-
'labelText' => $action->labelText
|
|
|
222 |
);
|
223 |
}
|
224 |
return $data;
|
@@ -258,6 +261,89 @@ class Cnb_Action_List_Table extends WP_List_Table {
|
|
258 |
);
|
259 |
}
|
260 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
function column_actionType($item) {
|
262 |
$column_name = 'actionType';
|
263 |
$bid = $this->button !== null ? $this->button->id : null;
|
75 |
'id' => __('ID'),
|
76 |
'actionType' => __('Type'),
|
77 |
'actionValue' => __('Value'),
|
78 |
+
'labelText' => __('Label'),
|
79 |
+
'schedule' => __('Schedule'),
|
80 |
);
|
81 |
if ($this->button) { unset($columns['cb']); }
|
82 |
|
157 |
case 'actionValue':
|
158 |
case 'labelText':
|
159 |
return !empty($item[$column_name]) ? esc_html($item[$column_name]) : '<em>No value</em>';
|
160 |
+
// Handled by column_actionType & column_schedule
|
161 |
+
case 'schedule':
|
162 |
case 'actionType':
|
163 |
return null;
|
164 |
case 'actionButton':
|
220 |
'actionButton' => $button,
|
221 |
'actionType' => $action->actionType,
|
222 |
'actionValue' => $action->actionValue,
|
223 |
+
'labelText' => $action->labelText,
|
224 |
+
'schedule' => $action->schedule,
|
225 |
);
|
226 |
}
|
227 |
return $data;
|
261 |
);
|
262 |
}
|
263 |
|
264 |
+
function column_schedule($item) {
|
265 |
+
/**
|
266 |
+
* @global WP_Locale $wp_locale WordPress date and time locale object.
|
267 |
+
*/
|
268 |
+
global $wp_locale;
|
269 |
+
|
270 |
+
if (!$item || !$item['schedule'] || $item['schedule']->showAlways) {
|
271 |
+
return __('Always visible');
|
272 |
+
}
|
273 |
+
|
274 |
+
$cnb_days_of_week_order = cnb_wp_get_order_of_days();
|
275 |
+
|
276 |
+
$schedule = $item['schedule'];
|
277 |
+
|
278 |
+
$days = '';
|
279 |
+
$daysOfWeek = array_unique($schedule->daysOfWeek);
|
280 |
+
if (count($daysOfWeek) === 1) {
|
281 |
+
// All disabled or enabled
|
282 |
+
if ($daysOfWeek[0] === true) {
|
283 |
+
$days = __( 'All days');
|
284 |
+
} else {
|
285 |
+
// Alligator alert: normally this is no possible, but adding for completeness
|
286 |
+
$days = __('No days');
|
287 |
+
}
|
288 |
+
} else {
|
289 |
+
// Special case: weekdays (and weekends?)
|
290 |
+
// First 5 are true, last 2 are false == weekdays
|
291 |
+
// Get first 5, filter for false/null, count
|
292 |
+
$weekdays = (count(array_filter(array_slice($schedule->daysOfWeek, 0, 5))) === 5 &&
|
293 |
+
count(array_filter(array_slice($schedule->daysOfWeek, 5, 2))) === 0);
|
294 |
+
$weekend = (count(array_filter(array_slice($schedule->daysOfWeek, 0, 5))) === 0 &&
|
295 |
+
count(array_filter(array_slice($schedule->daysOfWeek, 5, 2))) === 2);
|
296 |
+
if ($weekdays) {
|
297 |
+
$days = __('Week days only');
|
298 |
+
} else if ($weekend) {
|
299 |
+
$days = __('Weekend only');
|
300 |
+
} else {
|
301 |
+
// Print days it's enabled
|
302 |
+
$split = '';
|
303 |
+
foreach ( $cnb_days_of_week_order as $cnb_day_of_week ) {
|
304 |
+
$api_server_index = cnb_wp_locale_day_to_daysofweek_array_index( $cnb_day_of_week );
|
305 |
+
$day = $wp_locale->get_weekday( $cnb_day_of_week );
|
306 |
+
if ( $schedule->daysOfWeek[ $api_server_index ] ) {
|
307 |
+
$days .= $split . $day;
|
308 |
+
$split = ', ';
|
309 |
+
}
|
310 |
+
}
|
311 |
+
}
|
312 |
+
}
|
313 |
+
$wp_time_format = get_option('time_format');
|
314 |
+
|
315 |
+
$start = $schedule->start;
|
316 |
+
$stop = $schedule->stop;
|
317 |
+
|
318 |
+
$date = new DateTime();
|
319 |
+
$hour = explode(':', $start)[0];
|
320 |
+
$min = explode(':', $start)[1];
|
321 |
+
$date->setTime($hour, $min);
|
322 |
+
$wp_start = $date->format($wp_time_format);
|
323 |
+
|
324 |
+
$hour = explode(':', $stop)[0];
|
325 |
+
$min = explode(':', $stop)[1];
|
326 |
+
$date->setTime($hour, $min);
|
327 |
+
$wp_stop = $date->format($wp_time_format);
|
328 |
+
|
329 |
+
// print time
|
330 |
+
$time = '';
|
331 |
+
if ($start == "00:00" && $stop === "23:59") {
|
332 |
+
$time = '<em>'.__('All day').'</em>';
|
333 |
+
} else {
|
334 |
+
$time = esc_html($wp_start) . ' - ' . esc_html($wp_stop);
|
335 |
+
}
|
336 |
+
|
337 |
+
if ($schedule->outsideHours) {
|
338 |
+
$time = 'Before ' . esc_html($wp_start) . ', after ' . esc_html($wp_stop);
|
339 |
+
}
|
340 |
+
return sprintf(
|
341 |
+
'%1$s %2$s',
|
342 |
+
'<div class="cnb-scheduler-days">'.$days.'</div>',
|
343 |
+
'<div class="time">'.$time.'</div>'
|
344 |
+
);
|
345 |
+
}
|
346 |
+
|
347 |
function column_actionType($item) {
|
348 |
$column_name = 'actionType';
|
349 |
$bid = $this->button !== null ? $this->button->id : null;
|
src/admin/admin-ajax.php
CHANGED
@@ -93,3 +93,21 @@ function cnb_admin_cnb_email_activation() {
|
|
93 |
}
|
94 |
|
95 |
add_action('wp_ajax_cnb_email_activation', 'cnb_admin_cnb_email_activation');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
|
95 |
add_action('wp_ajax_cnb_email_activation', 'cnb_admin_cnb_email_activation');
|
96 |
+
|
97 |
+
function cnb_time_format_($time) {
|
98 |
+
$time_format = get_option('time_format');
|
99 |
+
$time_formatted = strtotime($time);
|
100 |
+
return date_i18n( $time_format, $time_formatted );
|
101 |
+
}
|
102 |
+
|
103 |
+
function cnb_time_format() {
|
104 |
+
$start = trim(filter_input( INPUT_POST, 'start', FILTER_SANITIZE_STRING ));
|
105 |
+
$stop = trim(filter_input( INPUT_POST, 'stop', FILTER_SANITIZE_STRING ));
|
106 |
+
wp_send_json(array(
|
107 |
+
'start' => cnb_time_format_($start),
|
108 |
+
'stop' => cnb_time_format_($stop),
|
109 |
+
)
|
110 |
+
);
|
111 |
+
}
|
112 |
+
|
113 |
+
add_action('wp_ajax_cnb_time_format', 'cnb_time_format');
|
src/admin/api/CnbAdminCloud.php
CHANGED
@@ -4,6 +4,19 @@ require_once dirname( __FILE__ ) . '/../../utils/CnbAdminNotices.class.php';
|
|
4 |
|
5 |
class CnbAdminCloud {
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
/**
|
8 |
* Called when Cloud Hosting is enabled via settings
|
9 |
*
|
@@ -13,14 +26,15 @@ class CnbAdminCloud {
|
|
13 |
*
|
14 |
* @return string The ID to use for the Cloud Button
|
15 |
*/
|
16 |
-
public static function cnb_set_default_option_for_cloud(
|
17 |
global $cnb_options;
|
18 |
|
19 |
// Check if an ID has already been set. If so, use if and continue
|
20 |
if ( isset( $options['cloud_use_id'] ) && ! empty( $options['cloud_use_id'] ) ) {
|
21 |
return null;
|
22 |
}
|
23 |
-
|
|
|
24 |
if ( empty( $options['api_key'] ) ) {
|
25 |
return null;
|
26 |
}
|
@@ -30,12 +44,33 @@ class CnbAdminCloud {
|
|
30 |
$cnb_options['api_key'] = $options['api_key'];
|
31 |
// Check if we can talk to the API via a key. If so, use the current user to be safe
|
32 |
$user_info = CnbAppRemote::cnb_remote_get_user_info();
|
|
|
33 |
// Reset key
|
34 |
$cnb_options['api_key'] = $original_key;
|
35 |
if ( !is_wp_error($user_info)) {
|
36 |
return $user_info->id;
|
37 |
}
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
return null;
|
40 |
}
|
41 |
|
@@ -451,8 +486,8 @@ class CnbAdminCloud {
|
|
451 |
$button_overview_url = esc_url( $button_overview_link );
|
452 |
|
453 |
$notice = new CnbNotice('success', '<p><span class="dashicons dashicons-cloud-saved"></span>
|
454 |
-
Congratulations
|
455 |
-
Click <a href="' . $button_overview_url . '">here</a> to
|
456 |
array_push( $cnb_cloud_notifications, $notice);
|
457 |
|
458 |
return $cnb_cloud_notifications;
|
@@ -500,8 +535,8 @@ class CnbAdminCloud {
|
|
500 |
$button_edit_url = esc_url( $button_edit_link );
|
501 |
|
502 |
$notice = new CnbNotice('success', '<p><span class="dashicons dashicons-cloud-saved"></span>
|
503 |
-
Congratulations! You are now using the Call Now Button
|
504 |
-
Click <a href="' . $button_edit_url . '">here</a> to
|
505 |
array_push( $cnb_cloud_notifications, $notice);
|
506 |
}
|
507 |
|
4 |
|
5 |
class CnbAdminCloud {
|
6 |
|
7 |
+
/**
|
8 |
+
* @param $api_key
|
9 |
+
*
|
10 |
+
* @return boolean true is the key is valid, false if not
|
11 |
+
*/
|
12 |
+
public function is_api_key_valid($api_key) {
|
13 |
+
global $cnb_options;
|
14 |
+
$old_value = $cnb_options['api_key'];
|
15 |
+
$cnb_options['api_key'] = $api_key;
|
16 |
+
$user_info = CnbAppRemote::cnb_remote_get_user_info();
|
17 |
+
$cnb_options['api_key'] = $old_value;
|
18 |
+
return !is_wp_error($user_info);
|
19 |
+
}
|
20 |
/**
|
21 |
* Called when Cloud Hosting is enabled via settings
|
22 |
*
|
26 |
*
|
27 |
* @return string The ID to use for the Cloud Button
|
28 |
*/
|
29 |
+
public static function cnb_set_default_option_for_cloud( &$options ) {
|
30 |
global $cnb_options;
|
31 |
|
32 |
// Check if an ID has already been set. If so, use if and continue
|
33 |
if ( isset( $options['cloud_use_id'] ) && ! empty( $options['cloud_use_id'] ) ) {
|
34 |
return null;
|
35 |
}
|
36 |
+
|
37 |
+
// If no API key is passed, there is nothing to do here
|
38 |
if ( empty( $options['api_key'] ) ) {
|
39 |
return null;
|
40 |
}
|
44 |
$cnb_options['api_key'] = $options['api_key'];
|
45 |
// Check if we can talk to the API via a key. If so, use the current user to be safe
|
46 |
$user_info = CnbAppRemote::cnb_remote_get_user_info();
|
47 |
+
|
48 |
// Reset key
|
49 |
$cnb_options['api_key'] = $original_key;
|
50 |
if ( !is_wp_error($user_info)) {
|
51 |
return $user_info->id;
|
52 |
}
|
53 |
|
54 |
+
// See if the passed in API key is REALLY an OTT
|
55 |
+
$api_key_from_ott = cnb_try_api_key_ott($options['api_key'], false);
|
56 |
+
|
57 |
+
if ($api_key_from_ott != null) {
|
58 |
+
$original_key = !empty($cnb_options['api_key']) ? $cnb_options['api_key'] : null;
|
59 |
+
$cnb_options['api_key'] = $api_key_from_ott;
|
60 |
+
|
61 |
+
// Check if we can talk to the API via a key. If so, use the current user to be safe
|
62 |
+
$user_info = CnbAppRemote::cnb_remote_get_user_info();
|
63 |
+
|
64 |
+
if ( !is_wp_error($user_info)) {
|
65 |
+
$options['api_key'] = $api_key_from_ott;
|
66 |
+
return $user_info->id;
|
67 |
+
}
|
68 |
+
|
69 |
+
// Reset key(s)
|
70 |
+
$options['api_key'] = $original_key;
|
71 |
+
$cnb_options['api_key'] = $original_key;
|
72 |
+
}
|
73 |
+
|
74 |
return null;
|
75 |
}
|
76 |
|
486 |
$button_overview_url = esc_url( $button_overview_link );
|
487 |
|
488 |
$notice = new CnbNotice('success', '<p><span class="dashicons dashicons-cloud-saved"></span>
|
489 |
+
Congratulations! You have successfully activated Call Now Button <strong>Premium</strong>!
|
490 |
+
Click <a href="' . $button_overview_url . '">here</a> to get stared.</p>');
|
491 |
array_push( $cnb_cloud_notifications, $notice);
|
492 |
|
493 |
return $cnb_cloud_notifications;
|
535 |
$button_edit_url = esc_url( $button_edit_link );
|
536 |
|
537 |
$notice = new CnbNotice('success', '<p><span class="dashicons dashicons-cloud-saved"></span>
|
538 |
+
Congratulations! You are now using the Premium version of the Call Now Button plugin!
|
539 |
+
Click <a href="' . $button_edit_url . '">here</a> to get started.</p>');
|
540 |
array_push( $cnb_cloud_notifications, $notice);
|
541 |
}
|
542 |
|
src/admin/api/CnbAppRemote.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
require_once dirname( __FILE__ ) . '/RemoteTrace.php';
|
4 |
|
5 |
/**
|
@@ -396,6 +398,9 @@ class CnbAppRemote {
|
|
396 |
return self::cnb_remote_handle_response( $response );
|
397 |
}
|
398 |
|
|
|
|
|
|
|
399 |
public static function cnb_remote_get_user_info() {
|
400 |
$rest_endpoint = '/v1/user';
|
401 |
|
@@ -443,6 +448,11 @@ class CnbAppRemote {
|
|
443 |
return self::cnb_remote_get( $rest_endpoint );
|
444 |
}
|
445 |
|
|
|
|
|
|
|
|
|
|
|
446 |
public static function cnb_remote_get_buttons() {
|
447 |
$rest_endpoint = '/v1/button';
|
448 |
|
1 |
<?php
|
2 |
|
3 |
+
use cnb\admin\models\Cnb_User;
|
4 |
+
|
5 |
require_once dirname( __FILE__ ) . '/RemoteTrace.php';
|
6 |
|
7 |
/**
|
398 |
return self::cnb_remote_handle_response( $response );
|
399 |
}
|
400 |
|
401 |
+
/**
|
402 |
+
* @return Cnb_User|WP_Error
|
403 |
+
*/
|
404 |
public static function cnb_remote_get_user_info() {
|
405 |
$rest_endpoint = '/v1/user';
|
406 |
|
448 |
return self::cnb_remote_get( $rest_endpoint );
|
449 |
}
|
450 |
|
451 |
+
/**
|
452 |
+
* This does not (yet) actually return CnbButton, but a stdclass that resembles it.
|
453 |
+
*
|
454 |
+
* @return CnbButton[]|WP_Error
|
455 |
+
*/
|
456 |
public static function cnb_remote_get_buttons() {
|
457 |
$rest_endpoint = '/v1/button';
|
458 |
|
src/admin/button-edit.php
CHANGED
@@ -574,6 +574,7 @@ function cnb_admin_page_edit_render() {
|
|
574 |
});
|
575 |
|
576 |
do_action('cnb_header');
|
|
|
577 |
?>
|
578 |
|
579 |
<div class="cnb-two-column-section-preview">
|
574 |
});
|
575 |
|
576 |
do_action('cnb_header');
|
577 |
+
cnb_warn_about_timezone($default_domain);
|
578 |
?>
|
579 |
|
580 |
<div class="cnb-two-column-section-preview">
|
src/admin/button-overview.php
CHANGED
@@ -24,7 +24,7 @@ function cnb_get_new_button_link() {
|
|
24 |
array(
|
25 |
'TB_inline' => 'true',
|
26 |
'inlineId' => 'cnb-add-new-modal',
|
27 |
-
'height' => '
|
28 |
'page' => 'call-now-button',
|
29 |
'action' => 'new',
|
30 |
'type' => 'single',
|
@@ -501,6 +501,8 @@ function cnb_admin_page_overview_render_list() {
|
|
501 |
$wp_list_table->setOption( 'filter_buttons_for_domain', $cnb_cloud_domain->id);
|
502 |
}
|
503 |
|
|
|
|
|
504 |
add_action('cnb_header_name', 'cnb_add_header_button_overview');
|
505 |
|
506 |
$upgrade_url = get_cnb_domain_upgrade($cnb_cloud_domain);
|
24 |
array(
|
25 |
'TB_inline' => 'true',
|
26 |
'inlineId' => 'cnb-add-new-modal',
|
27 |
+
'height' => '500', // 405 is ideal -> To hide the scrollbar
|
28 |
'page' => 'call-now-button',
|
29 |
'action' => 'new',
|
30 |
'type' => 'single',
|
501 |
$wp_list_table->setOption( 'filter_buttons_for_domain', $cnb_cloud_domain->id);
|
502 |
}
|
503 |
|
504 |
+
// If users come to this page before activating, we need the -settings JS for the activation notice
|
505 |
+
wp_enqueue_script(CNB_SLUG . '-settings');
|
506 |
add_action('cnb_header_name', 'cnb_add_header_button_overview');
|
507 |
|
508 |
$upgrade_url = get_cnb_domain_upgrade($cnb_cloud_domain);
|
src/admin/domain-edit.php
CHANGED
@@ -155,7 +155,7 @@ function cnb_admin_page_domain_edit_process() {
|
|
155 |
/**
|
156 |
* @param CnbDomain $domain
|
157 |
*
|
158 |
-
* @return
|
159 |
*/
|
160 |
function cnb_domain_timezone_check($domain) {
|
161 |
if ($domain && !is_wp_error($domain) && !empty($domain->timezone)) {
|
@@ -175,8 +175,10 @@ function cnb_domain_timezone_check($domain) {
|
|
175 |
$message = "<p id='cnb-notice-domain-timezone-unsupported'>Please set your timezone in the <a href=\"". $redirect_url . "\">Advanced settings</a> tab to avoid unpredictable behavior when using the scheduler.</p>";
|
176 |
$notice = new CnbNotice('warning', $message, false);
|
177 |
CnbAdminNotices::get_instance()->renderNotice($notice);
|
|
|
178 |
}
|
179 |
}
|
|
|
180 |
}
|
181 |
/**
|
182 |
* Main entrypoint, used by `domain-overview.php`.
|
155 |
/**
|
156 |
* @param CnbDomain $domain
|
157 |
*
|
158 |
+
* @return boolean true if everything is already
|
159 |
*/
|
160 |
function cnb_domain_timezone_check($domain) {
|
161 |
if ($domain && !is_wp_error($domain) && !empty($domain->timezone)) {
|
175 |
$message = "<p id='cnb-notice-domain-timezone-unsupported'>Please set your timezone in the <a href=\"". $redirect_url . "\">Advanced settings</a> tab to avoid unpredictable behavior when using the scheduler.</p>";
|
176 |
$notice = new CnbNotice('warning', $message, false);
|
177 |
CnbAdminNotices::get_instance()->renderNotice($notice);
|
178 |
+
return false;
|
179 |
}
|
180 |
}
|
181 |
+
return true;
|
182 |
}
|
183 |
/**
|
184 |
* Main entrypoint, used by `domain-overview.php`.
|
src/admin/legacy-edit.php
CHANGED
@@ -111,7 +111,7 @@ function cnb_admin_page_legacy_edit_render() {
|
|
111 |
|
112 |
do_action('cnb_header');
|
113 |
?>
|
114 |
-
<?php
|
115 |
<div class="cnb-two-column-section">
|
116 |
<div class="cnb-body-column">
|
117 |
<div class="cnb-body-content">
|
@@ -291,23 +291,23 @@ function cnb_admin_page_legacy_edit_render() {
|
|
291 |
'Unlock extra power',
|
292 |
'<p>Need more powerful features such as:</p>
|
293 |
<p>✓ More buttons<br>
|
294 |
-
✓ Email, WhatsApp, Maps<br>
|
295 |
✓ Scheduling<br>
|
296 |
-
✓
|
297 |
-
✓ Multibutton (expandable single button)<br>
|
298 |
✓ And more!</p>',
|
299 |
'unlock',
|
300 |
'',
|
301 |
-
'
|
302 |
cnb_legacy_upgrade_page()
|
303 |
);
|
304 |
?>
|
305 |
<?php
|
306 |
cnb_promobox(
|
307 |
'blue',
|
308 |
-
'
|
309 |
'<p>Looking for more than just a call button? You can now add the following actions:</p>
|
310 |
-
<p>✓
|
|
|
311 |
✓ WhatsApp<br>
|
312 |
✓ Directions<br>
|
313 |
✓ Links</p>',
|
111 |
|
112 |
do_action('cnb_header');
|
113 |
?>
|
114 |
+
<?php cnb_get_welcome_banner() ?>
|
115 |
<div class="cnb-two-column-section">
|
116 |
<div class="cnb-body-column">
|
117 |
<div class="cnb-body-content">
|
291 |
'Unlock extra power',
|
292 |
'<p>Need more powerful features such as:</p>
|
293 |
<p>✓ More buttons<br>
|
294 |
+
✓ Text/SMS, Email, WhatsApp, Maps<br>
|
295 |
✓ Scheduling<br>
|
296 |
+
✓ Multi action buttons<br>
|
|
|
297 |
✓ And more!</p>',
|
298 |
'unlock',
|
299 |
'',
|
300 |
+
'Try Premium',
|
301 |
cnb_legacy_upgrade_page()
|
302 |
);
|
303 |
?>
|
304 |
<?php
|
305 |
cnb_promobox(
|
306 |
'blue',
|
307 |
+
'Add more actions!',
|
308 |
'<p>Looking for more than just a call button? You can now add the following actions:</p>
|
309 |
+
<p>✓ SMS/Text<br>
|
310 |
+
✓ Email<br>
|
311 |
✓ WhatsApp<br>
|
312 |
✓ Directions<br>
|
313 |
✓ Links</p>',
|
src/admin/legacy-upgrade.php
CHANGED
@@ -15,9 +15,8 @@ function cnb_standard_plugin_promobox() { ?>
|
|
15 |
'Standard plugin',
|
16 |
'<p>✓ One button<br>
|
17 |
✓ Phone<br>
|
18 |
-
✓ Circular<br>
|
19 |
-
✓
|
20 |
-
<span class="cnb_description">(single action Buttonbar™)</span>
|
21 |
✓ Action label<br>
|
22 |
</p>
|
23 |
<hr>
|
@@ -25,6 +24,7 @@ function cnb_standard_plugin_promobox() { ?>
|
|
25 |
✓ Placement options<br>
|
26 |
✓ For mobile devices<br>
|
27 |
✓ Include or exclude pages<br>
|
|
|
28 |
</p>
|
29 |
<hr>
|
30 |
<p>
|
@@ -34,7 +34,8 @@ function cnb_standard_plugin_promobox() { ?>
|
|
34 |
<hr>
|
35 |
<p>
|
36 |
✓ Adjust the button size<br>
|
37 |
-
✓ Flexible z-index
|
|
|
38 |
</p>',
|
39 |
'admin-plugins',
|
40 |
'<strong>Free</strong>',
|
@@ -51,24 +52,19 @@ function cnb_premium_plugin_promobox() { ?>
|
|
51 |
cnb_promobox(
|
52 |
'blue',
|
53 |
'Premium',
|
54 |
-
'
|
55 |
-
<hr>
|
56 |
<p><strong>✓ Lots of buttons!</strong><br>
|
57 |
-
✓ Phone, Email, WhatsApp, Maps, URLs<br>
|
58 |
-
✓ Circular button<br>
|
59 |
-
✓ Buttonbar
|
60 |
-
<span class="cnb_description">(multi action full width button)</span>
|
61 |
-
✓ Multibutton™
|
62 |
-
<span class="cnb_description">(single button unfolding into multiple)</span>
|
63 |
✓ Actions labels<br>
|
64 |
</p>
|
65 |
<hr>
|
66 |
<p>
|
67 |
✓ Placement options<br>
|
68 |
✓ For mobile and desktop/laptop<br>
|
69 |
-
✓
|
70 |
-
✓
|
71 |
-
<span class="cnb_description">(for deciding where a button should appear. E.g. only show to Google Ads visitors)</span>
|
72 |
</p>
|
73 |
<hr>
|
74 |
<p>
|
@@ -79,9 +75,9 @@ function cnb_premium_plugin_promobox() { ?>
|
|
79 |
<p>
|
80 |
✓ Adjust the button size<br>
|
81 |
✓ Flexible z-index<br>
|
82 |
-
✓
|
83 |
<hr>
|
84 |
-
<p class="cnb_align_center">From <strong>€2.49/$2.99</strong> per month or <strong style="text-decoration:underline">FREE
|
85 |
'cloud',
|
86 |
cnb_settings_email_activation_input(),
|
87 |
'none'
|
@@ -94,7 +90,9 @@ function cnb_upgrade_faq() { ?>
|
|
94 |
<div style="max-width:600px;margin:0 auto">
|
95 |
<h1 class="cnb-center">FAQ</h1>
|
96 |
<h3>Can I really get Premium for Free?</h3>
|
97 |
-
<p>Yes. It's possible to access all premium features of the Call Now Button for free. No credit card is required. You only need an account for that. The difference with the paid Premium plans is that a small "Powered by Call Now Button" notice is added to your buttons.</p>
|
|
|
|
|
98 |
<h3>Does the Premium plan require an account?</h3>
|
99 |
<p>Yes. We want the Call Now Button to be accessible to all website owners. Even those that do not have a WordPress powered website. The Premium version of the Call Now Button can be used by everyone. You can continue to manage your buttons from your WordPress instance, but you could also do this via our web app. And should you ever move to a different CMS, your button(s) will just move with you.</p>
|
100 |
<h3>What is the "powered by" notice on the Free Premium plan?</h3>
|
15 |
'Standard plugin',
|
16 |
'<p>✓ One button<br>
|
17 |
✓ Phone<br>
|
18 |
+
✓ Circular (single action)<br>
|
19 |
+
✓ Buttonbar (single action)<br>
|
|
|
20 |
✓ Action label<br>
|
21 |
</p>
|
22 |
<hr>
|
24 |
✓ Placement options<br>
|
25 |
✓ For mobile devices<br>
|
26 |
✓ Include or exclude pages<br>
|
27 |
+
|
28 |
</p>
|
29 |
<hr>
|
30 |
<p>
|
34 |
<hr>
|
35 |
<p>
|
36 |
✓ Adjust the button size<br>
|
37 |
+
✓ Flexible z-index<br>
|
38 |
+
|
39 |
</p>',
|
40 |
'admin-plugins',
|
41 |
'<strong>Free</strong>',
|
52 |
cnb_promobox(
|
53 |
'blue',
|
54 |
'Premium',
|
55 |
+
'
|
|
|
56 |
<p><strong>✓ Lots of buttons!</strong><br>
|
57 |
+
✓ Phone, SMS/Text, Email, WhatsApp, Maps, URLs<br>
|
58 |
+
✓ Circular button (multi action)<br>
|
59 |
+
✓ Buttonbar (multi action)<br>
|
|
|
|
|
|
|
60 |
✓ Actions labels<br>
|
61 |
</p>
|
62 |
<hr>
|
63 |
<p>
|
64 |
✓ Placement options<br>
|
65 |
✓ For mobile and desktop/laptop<br>
|
66 |
+
✓ Advanced page targeting<br>
|
67 |
+
✓ Scheduling
|
|
|
68 |
</p>
|
69 |
<hr>
|
70 |
<p>
|
75 |
<p>
|
76 |
✓ Adjust the button size<br>
|
77 |
✓ Flexible z-index<br>
|
78 |
+
✓ Live button preview</p>
|
79 |
<hr>
|
80 |
+
<p class="cnb_align_center">From <strong>€2.49/$2.99</strong> per month or <strong style="text-decoration:underline">FREE*</strong> with subtle "<em>powered by</em>" branding.</p>',
|
81 |
'cloud',
|
82 |
cnb_settings_email_activation_input(),
|
83 |
'none'
|
90 |
<div style="max-width:600px;margin:0 auto">
|
91 |
<h1 class="cnb-center">FAQ</h1>
|
92 |
<h3>Can I really get Premium for Free?</h3>
|
93 |
+
<p>Yes. It's possible to access all premium features of the Call Now Button for free. No credit card is required. You only need an account for that. The difference with the paid Premium plans is that a small "Powered by Call Now Button" notice is added to your buttons and there's a monthly pageviews limit of 20k.</p>
|
94 |
+
<h3>My website has more than 20k monthly pageviews. Can I still use Premium for Free?</h3>
|
95 |
+
<p>The Free plan can be used by all websites. But once you hit the 20k pageview limit you will need to upgrade to PRO to keep using the plugin. PRO starts at €2.49/$2.99 per month.</p>
|
96 |
<h3>Does the Premium plan require an account?</h3>
|
97 |
<p>Yes. We want the Call Now Button to be accessible to all website owners. Even those that do not have a WordPress powered website. The Premium version of the Call Now Button can be used by everyone. You can continue to manage your buttons from your WordPress instance, but you could also do this via our web app. And should you ever move to a different CMS, your button(s) will just move with you.</p>
|
98 |
<h3>What is the "powered by" notice on the Free Premium plan?</h3>
|
src/admin/models/CnbButton.class.php
CHANGED
@@ -30,6 +30,11 @@ class CnbButton {
|
|
30 |
|
31 |
public $conditions;
|
32 |
|
|
|
|
|
|
|
|
|
|
|
33 |
public static function setSaneDefault($button) {
|
34 |
// Set some sane defaults
|
35 |
if (!isset($button->options)) $button->options = new CnbButtonOptions();
|
@@ -55,14 +60,78 @@ class CnbButton {
|
|
55 |
$button->type = 'SINGLE';
|
56 |
$button->domain = $domain;
|
57 |
$button->actions = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
return $button;
|
60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
|
63 |
class CnbButtonOptions {
|
64 |
public $iconBackgroundColor;
|
65 |
public $iconColor;
|
|
|
|
|
|
|
66 |
public $placement;
|
67 |
public $scale;
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
public $conditions;
|
32 |
|
33 |
+
/**
|
34 |
+
* @var CnbButtonOptions
|
35 |
+
*/
|
36 |
+
public $options;
|
37 |
+
|
38 |
public static function setSaneDefault($button) {
|
39 |
// Set some sane defaults
|
40 |
if (!isset($button->options)) $button->options = new CnbButtonOptions();
|
60 |
$button->type = 'SINGLE';
|
61 |
$button->domain = $domain;
|
62 |
$button->actions = array();
|
63 |
+
$button->conditions = array();
|
64 |
+
|
65 |
+
return $button;
|
66 |
+
}
|
67 |
+
|
68 |
+
public function toArray() {
|
69 |
+
return array(
|
70 |
+
'id' => $this->id,
|
71 |
+
'active' => $this->active,
|
72 |
+
'name' => $this->name,
|
73 |
+
'type' => $this->type,
|
74 |
+
'domain' => $this->domain,
|
75 |
+
'actions' => $this->actions,
|
76 |
+
'conditions' => $this->conditions,
|
77 |
+
'options' => isset($this->options) ? $this->options->toArray() : array()
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
public static function fromObject($object) {
|
82 |
+
$button = new CnbButton();
|
83 |
+
$button->id = $object->id;
|
84 |
+
$button->active = $object->active;
|
85 |
+
$button->name = $object->name;
|
86 |
+
$button->type = $object->type;
|
87 |
+
$button->domain = $object->domain;
|
88 |
+
$button->actions = $object->actions;
|
89 |
+
$button->conditions = $object->conditions;
|
90 |
+
$button->options = CnbButtonOptions::fromObject($object->options);
|
91 |
|
92 |
return $button;
|
93 |
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @param $buttons CnbButton[]
|
97 |
+
*
|
98 |
+
* @return array
|
99 |
+
*/
|
100 |
+
public static function convert($buttons) {
|
101 |
+
return array_map(
|
102 |
+
function($button) {
|
103 |
+
$button = $button instanceof CnbButton ? $button : self::fromObject($button);
|
104 |
+
return ($button instanceof CnbButton) ? $button->toArray() : array();
|
105 |
+
}, $buttons
|
106 |
+
);
|
107 |
+
}
|
108 |
}
|
109 |
|
110 |
class CnbButtonOptions {
|
111 |
public $iconBackgroundColor;
|
112 |
public $iconColor;
|
113 |
+
/**
|
114 |
+
* @var string
|
115 |
+
*/
|
116 |
public $placement;
|
117 |
public $scale;
|
118 |
+
|
119 |
+
public function toArray() {
|
120 |
+
return array(
|
121 |
+
'iconBackgroundColor' => $this->iconBackgroundColor,
|
122 |
+
'iconColor' => $this->iconColor,
|
123 |
+
'placement' => $this->placement,
|
124 |
+
'scale' => $this->scale
|
125 |
+
);
|
126 |
+
}
|
127 |
+
|
128 |
+
public static function fromObject( $object ) {
|
129 |
+
$options = new CnbButtonOptions();
|
130 |
+
$options->iconBackgroundColor = $object->iconBackgroundColor;
|
131 |
+
$options->iconColor = $object->iconColor;
|
132 |
+
$options->placement = $object->placement;
|
133 |
+
$options->scale = $object->scale;
|
134 |
+
|
135 |
+
return $options;
|
136 |
+
}
|
137 |
+
}
|
src/admin/models/CnbUser.class.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace cnb\admin\models;
|
4 |
+
|
5 |
+
class Cnb_User {
|
6 |
+
/**
|
7 |
+
* @var string UUID of the User
|
8 |
+
*/
|
9 |
+
public $id;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var string Name of the User
|
13 |
+
*/
|
14 |
+
public $name;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Usually the same as admin_email
|
18 |
+
*
|
19 |
+
* @var string email address of the User
|
20 |
+
*/
|
21 |
+
public $email;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $companyName;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var Cnb_User_Address
|
30 |
+
*/
|
31 |
+
public $address;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var array{Cnb_user_TaxId}
|
35 |
+
*/
|
36 |
+
public $taxIds;
|
37 |
+
}
|
38 |
+
|
39 |
+
class Cnb_user_TaxId {
|
40 |
+
public $value;
|
41 |
+
/**
|
42 |
+
* @var Cnb_user_TaxId_Verification
|
43 |
+
*/
|
44 |
+
public $verification;
|
45 |
+
}
|
46 |
+
|
47 |
+
class Cnb_user_TaxId_Verification {
|
48 |
+
/**
|
49 |
+
* @var string either "verified" or "pending"
|
50 |
+
*/
|
51 |
+
public $status;
|
52 |
+
}
|
53 |
+
|
54 |
+
class Cnb_User_Address {
|
55 |
+
public $line1;
|
56 |
+
public $line2;
|
57 |
+
public $postalCode;
|
58 |
+
public $city;
|
59 |
+
public $state;
|
60 |
+
public $country;
|
61 |
+
|
62 |
+
}
|
src/admin/partials/admin-footer.php
CHANGED
@@ -17,8 +17,10 @@ function cnb_show_feedback_collection() {
|
|
17 |
$upgrade_url = esc_url( $upgrade_link );?>
|
18 |
<div class="feedback-collection">
|
19 |
<div class="cnb-clear"></div>
|
20 |
-
<p class="cnb-url cnb-center"><a href="<?php echo CNB_WEBSITE; ?><?php cnb_utm_params("footer-links", "branding"); ?>" target="_blank">Call Now Button
|
21 |
-
|
|
|
|
|
22 |
<p class="cnb-center cnb-spacing">
|
23 |
<a href="<?php echo CNB_SUPPORT;
|
24 |
cnb_utm_params("footer-links", "support"); ?>" target="_blank" title="Support">Support</a> ·
|
17 |
$upgrade_url = esc_url( $upgrade_link );?>
|
18 |
<div class="feedback-collection">
|
19 |
<div class="cnb-clear"></div>
|
20 |
+
<p class="cnb-url cnb-center"><a href="<?php echo CNB_WEBSITE; ?><?php cnb_utm_params("footer-links", "branding"); ?>" target="_blank">Call Now Button<?php if ($cnb_cloud_hosting) {
|
21 |
+
echo '<span class="cnb_footer_beta">PREMIUM</span>';
|
22 |
+
} ?></a></p>
|
23 |
+
<p class="cnb-center">Version <?php echo CNB_VERSION; ?>
|
24 |
<p class="cnb-center cnb-spacing">
|
25 |
<a href="<?php echo CNB_SUPPORT;
|
26 |
cnb_utm_params("footer-links", "support"); ?>" target="_blank" title="Support">Support</a> ·
|
src/admin/partials/admin-functions.php
CHANGED
@@ -52,6 +52,10 @@ function has_changelog($cnb_options) {
|
|
52 |
|
53 |
function cnb_get_changelog() {
|
54 |
return array(
|
|
|
|
|
|
|
|
|
55 |
'1.0.4' => array(
|
56 |
'Live button preview for Premium',
|
57 |
'Easy premium activation via email',
|
@@ -98,6 +102,11 @@ function cnb_get_button_types() {
|
|
98 |
/**
|
99 |
* Return an array of all ActionTypes
|
100 |
*
|
|
|
|
|
|
|
|
|
|
|
101 |
* @return string[] array of ActionType to their nice names
|
102 |
*/
|
103 |
function cnb_get_action_types() {
|
@@ -108,6 +117,7 @@ function cnb_get_action_types() {
|
|
108 |
'LINK' => 'Link',
|
109 |
'MAP' => 'Google Maps',
|
110 |
'WHATSAPP' => 'Whatsapp',
|
|
|
111 |
);
|
112 |
}
|
113 |
|
52 |
|
53 |
function cnb_get_changelog() {
|
54 |
return array(
|
55 |
+
'1.0.6' => array(
|
56 |
+
'💬 SMS/Text support in Premium',
|
57 |
+
'⏱️ More intuitive button scheduler in Premium',
|
58 |
+
),
|
59 |
'1.0.4' => array(
|
60 |
'Live button preview for Premium',
|
61 |
'Easy premium activation via email',
|
102 |
/**
|
103 |
* Return an array of all ActionTypes
|
104 |
*
|
105 |
+
* Note(s):
|
106 |
+
* - This is NOT in alphabetical order, but rather in order of
|
107 |
+
* what feels more likely to be choosen
|
108 |
+
* - HOURS is missing, since that is not implemented yet
|
109 |
+
*
|
110 |
* @return string[] array of ActionType to their nice names
|
111 |
*/
|
112 |
function cnb_get_action_types() {
|
117 |
'LINK' => 'Link',
|
118 |
'MAP' => 'Google Maps',
|
119 |
'WHATSAPP' => 'Whatsapp',
|
120 |
+
'SMS' => 'SMS',
|
121 |
);
|
122 |
}
|
123 |
|
src/admin/partials/domain-upgrade/overview.php
CHANGED
@@ -8,14 +8,14 @@ function cnb_get_plan($plans, $name) {
|
|
8 |
return null;
|
9 |
}
|
10 |
|
11 |
-
function getProfileEditModal($additional_classes=null, $link_text='
|
12 |
if (!$modal_header) {$modal_header=$link_text;}
|
13 |
$url = admin_url('admin.php');
|
14 |
$full_url = add_query_arg(
|
15 |
array(
|
16 |
'TB_inline' => 'true',
|
17 |
'inlineId' => 'cnb_admin_page_domain_upgrade_profile',
|
18 |
-
'height' => '
|
19 |
$url );
|
20 |
printf(
|
21 |
'<a href="%1$s" title="%2$s" class="thickbox open-profile-details-modal %4$s" onclick="cnb_btn=\'%5$s\'">%3$s</a>',
|
@@ -77,7 +77,7 @@ function cnb_domain_upgrade_overview($domain, $user) {
|
|
77 |
<div class="currency-box currency-box-eur cnb-flexbox<?php if($active_currency !== 'usd') {?> currency-box-active<?php }?>">
|
78 |
<?php if($domain->type === 'FREE') { ?>
|
79 |
<div class="pricebox cnb-premium-free">
|
80 |
-
<h3 class="free">Premium
|
81 |
<div class="benefit">Shows "Powered by" branding<br>Up to 20k monthly pageviews</div>
|
82 |
<div class="plan-amount"><span class="currency"></span><span class="euros"> </span><span class="cents"></span><span class="timeframe"></span></div>
|
83 |
<div class="billingprice"> </div>
|
@@ -86,32 +86,32 @@ function cnb_domain_upgrade_overview($domain, $user) {
|
|
86 |
<?php } ?>
|
87 |
<?php $plan = cnb_get_plan($plans, 'powered-by-eur-yearly'); ?>
|
88 |
<div class="pricebox">
|
89 |
-
<h3 class="yearly"><span class="cnb-premium-label">
|
90 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
91 |
<div class="plan-amount"><span class="currency">€</span><span class="euros">2</span><span class="cents">.49</span><span class="timeframe">/month</span></div>
|
92 |
<div class="billingprice">
|
93 |
Billed at €29.88 annually
|
94 |
</div>
|
95 |
-
<?php getProfileEditModal('button button-primary', 'Upgrade', '
|
96 |
<a class="button button-primary button-upgrade powered-by-eur-yearly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
97 |
</div>
|
98 |
|
99 |
<?php $plan = cnb_get_plan($plans, 'powered-by-eur-monthly'); ?>
|
100 |
<div class="pricebox">
|
101 |
-
<h3 class="monthly"><span class="cnb-premium-label">
|
102 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
103 |
<div class="plan-amount"><span class="currency">€</span><span class="euros">4</span><span class="cents">.98</span><span class="timeframe">/month</span></div>
|
104 |
<div class="billingprice">
|
105 |
Billed monthly
|
106 |
</div>
|
107 |
-
<?php getProfileEditModal('button button-secondary', 'Upgrade', '
|
108 |
<a class="button button-secondary button-upgrade powered-by-eur-monthly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
109 |
</div>
|
110 |
</div>
|
111 |
<div class="currency-box currency-box-usd cnb-flexbox<?php if($active_currency === 'usd') {?> currency-box-active<?php }?>">
|
112 |
<?php if($domain->type === 'FREE') { ?>
|
113 |
<div class="pricebox cnb-premium-free">
|
114 |
-
<h3 class="free">Premium
|
115 |
<div class="benefit">Shows "Powered by" branding<br>Up to 20k monthly pageviews</div>
|
116 |
<div class="plan-amount"><span class="currency"></span><span class="euros"> </span><span class="cents"></span><span class="timeframe"></span></div>
|
117 |
<div class="billingprice"> </div>
|
@@ -120,24 +120,24 @@ function cnb_domain_upgrade_overview($domain, $user) {
|
|
120 |
<?php } ?>
|
121 |
<?php $plan = cnb_get_plan($plans, 'powered-by-usd-yearly'); ?>
|
122 |
<div class="pricebox">
|
123 |
-
<h3 class="yearly"><span class="cnb-premium-label">
|
124 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
125 |
<div class="plan-amount"><span class="currency">$</span><span class="euros">2</span><span class="cents">.99</span><span class="timeframe">/month</span></div>
|
126 |
<div class="billingprice">
|
127 |
Billed at $34.88 annually
|
128 |
</div>
|
129 |
-
<?php getProfileEditModal('button button-primary', 'Upgrade', '
|
130 |
<a class="button button-primary button-upgrade powered-by-usd-yearly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
131 |
</div>
|
132 |
<?php $plan = cnb_get_plan($plans, 'powered-by-usd-monthly'); ?>
|
133 |
<div class="pricebox">
|
134 |
-
<h3 class="monthly"><span class="cnb-premium-label">
|
135 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
136 |
<div class="plan-amount"><span class="currency">$</span><span class="euros">5</span><span class="cents">.98</span><span class="timeframe">/month</span></div>
|
137 |
<div class="billingprice">
|
138 |
Billed monthly
|
139 |
</div>
|
140 |
-
<?php getProfileEditModal('button button-secondary', 'Upgrade', '
|
141 |
<a class="button button-secondary button-upgrade powered-by-usd-monthly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
142 |
</div>
|
143 |
</div>
|
8 |
return null;
|
9 |
}
|
10 |
|
11 |
+
function getProfileEditModal($additional_classes=null, $link_text='Enter or verify your information', $modal_header=null, $data_title='') {
|
12 |
if (!$modal_header) {$modal_header=$link_text;}
|
13 |
$url = admin_url('admin.php');
|
14 |
$full_url = add_query_arg(
|
15 |
array(
|
16 |
'TB_inline' => 'true',
|
17 |
'inlineId' => 'cnb_admin_page_domain_upgrade_profile',
|
18 |
+
'height' => '525'),
|
19 |
$url );
|
20 |
printf(
|
21 |
'<a href="%1$s" title="%2$s" class="thickbox open-profile-details-modal %4$s" onclick="cnb_btn=\'%5$s\'">%3$s</a>',
|
77 |
<div class="currency-box currency-box-eur cnb-flexbox<?php if($active_currency !== 'usd') {?> currency-box-active<?php }?>">
|
78 |
<?php if($domain->type === 'FREE') { ?>
|
79 |
<div class="pricebox cnb-premium-free">
|
80 |
+
<h3 class="free">Premium (free)</h3>
|
81 |
<div class="benefit">Shows "Powered by" branding<br>Up to 20k monthly pageviews</div>
|
82 |
<div class="plan-amount"><span class="currency"></span><span class="euros"> </span><span class="cents"></span><span class="timeframe"></span></div>
|
83 |
<div class="billingprice"> </div>
|
86 |
<?php } ?>
|
87 |
<?php $plan = cnb_get_plan($plans, 'powered-by-eur-yearly'); ?>
|
88 |
<div class="pricebox">
|
89 |
+
<h3 class="yearly"><span class="cnb-premium-label">PRO </span>Yearly</h3>
|
90 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
91 |
<div class="plan-amount"><span class="currency">€</span><span class="euros">2</span><span class="cents">.49</span><span class="timeframe">/month</span></div>
|
92 |
<div class="billingprice">
|
93 |
Billed at €29.88 annually
|
94 |
</div>
|
95 |
+
<?php getProfileEditModal('button button-primary', 'Upgrade', 'Enter or verify your information', 'powered-by-eur-yearly'); ?>
|
96 |
<a class="button button-primary button-upgrade powered-by-eur-yearly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
97 |
</div>
|
98 |
|
99 |
<?php $plan = cnb_get_plan($plans, 'powered-by-eur-monthly'); ?>
|
100 |
<div class="pricebox">
|
101 |
+
<h3 class="monthly"><span class="cnb-premium-label">PRO </span>Monthly</h3>
|
102 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
103 |
<div class="plan-amount"><span class="currency">€</span><span class="euros">4</span><span class="cents">.98</span><span class="timeframe">/month</span></div>
|
104 |
<div class="billingprice">
|
105 |
Billed monthly
|
106 |
</div>
|
107 |
+
<?php getProfileEditModal('button button-secondary', 'Upgrade', 'Enter or verify your information', 'powered-by-eur-monthly'); ?>
|
108 |
<a class="button button-secondary button-upgrade powered-by-eur-monthly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
109 |
</div>
|
110 |
</div>
|
111 |
<div class="currency-box currency-box-usd cnb-flexbox<?php if($active_currency === 'usd') {?> currency-box-active<?php }?>">
|
112 |
<?php if($domain->type === 'FREE') { ?>
|
113 |
<div class="pricebox cnb-premium-free">
|
114 |
+
<h3 class="free">Premium (free)</h3>
|
115 |
<div class="benefit">Shows "Powered by" branding<br>Up to 20k monthly pageviews</div>
|
116 |
<div class="plan-amount"><span class="currency"></span><span class="euros"> </span><span class="cents"></span><span class="timeframe"></span></div>
|
117 |
<div class="billingprice"> </div>
|
120 |
<?php } ?>
|
121 |
<?php $plan = cnb_get_plan($plans, 'powered-by-usd-yearly'); ?>
|
122 |
<div class="pricebox">
|
123 |
+
<h3 class="yearly"><span class="cnb-premium-label">PRO </span>Yearly</h3>
|
124 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
125 |
<div class="plan-amount"><span class="currency">$</span><span class="euros">2</span><span class="cents">.99</span><span class="timeframe">/month</span></div>
|
126 |
<div class="billingprice">
|
127 |
Billed at $34.88 annually
|
128 |
</div>
|
129 |
+
<?php getProfileEditModal('button button-primary', 'Upgrade', 'Enter or verify your information', 'powered-by-usd-yearly'); ?>
|
130 |
<a class="button button-primary button-upgrade powered-by-usd-yearly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
131 |
</div>
|
132 |
<?php $plan = cnb_get_plan($plans, 'powered-by-usd-monthly'); ?>
|
133 |
<div class="pricebox">
|
134 |
+
<h3 class="monthly"><span class="cnb-premium-label">PRO </span>Monthly</h3>
|
135 |
<div class="benefit">No "Powered by" branding<br>Up to 50k monthly pageviews</div>
|
136 |
<div class="plan-amount"><span class="currency">$</span><span class="euros">5</span><span class="cents">.98</span><span class="timeframe">/month</span></div>
|
137 |
<div class="billingprice">
|
138 |
Billed monthly
|
139 |
</div>
|
140 |
+
<?php getProfileEditModal('button button-secondary', 'Upgrade', 'Enter or verify your information', 'powered-by-usd-monthly'); ?>
|
141 |
<a class="button button-secondary button-upgrade powered-by-usd-monthly" href="#" onclick="cnb_get_checkout('<?php _e($plan->id) ?>')">Upgrade</a>
|
142 |
</div>
|
143 |
</div>
|
src/admin/settings-profile.php
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
2 |
function cnb_add_header_profile_edit() {
|
3 |
echo 'Profile';
|
4 |
}
|
@@ -306,7 +309,7 @@ function cnb_admin_profile_edit_process() {
|
|
306 |
/**
|
307 |
* @param false $modal
|
308 |
*
|
309 |
-
* @return
|
310 |
*/
|
311 |
function cnb_admin_page_profile_edit_render_form($modal = false) {
|
312 |
$cnb_user = CnbAppRemote::cnb_remote_get_user_info();
|
@@ -362,6 +365,37 @@ function cnb_admin_page_profile_edit_render_form($modal = false) {
|
|
362 |
class="regular-text ltr cnb_vat_companies_required">
|
363 |
</td>
|
364 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
|
366 |
<tr class="cnb_vat_companies_show" style="display:none">
|
367 |
<th scope="row"><label for="user[address][line1]">Address<span class="cnb_required">*</span></label></th>
|
@@ -378,8 +412,8 @@ function cnb_admin_page_profile_edit_render_form($modal = false) {
|
|
378 |
</td>
|
379 |
</tr>
|
380 |
|
381 |
-
<tr
|
382 |
-
<th scope="row"><label for="user[address][postalCode]"><span class="cnb_ie_only" style="display:none">Eircode/</span>Zip/Postal code<span class="cnb_required
|
383 |
<td>
|
384 |
<input type="text" id="user[address][postalCode]" name="user[address][postalCode]"
|
385 |
value="<?php esc_html_e( isset($cnb_user->address) ? $cnb_user->address->postalCode : '' ) ?>"
|
@@ -403,40 +437,10 @@ function cnb_admin_page_profile_edit_render_form($modal = false) {
|
|
403 |
</td>
|
404 |
</tr>
|
405 |
|
406 |
-
<tr>
|
407 |
-
<th scope="row"><label for="cnb_profile_country">Country<span class="cnb_required">*</span></label></th>
|
408 |
-
<td>
|
409 |
-
<label>
|
410 |
-
<select id="cnb_profile_country" class="select-menu" name="user[address][country]"
|
411 |
-
required="required">
|
412 |
-
<option value=""></option>
|
413 |
-
<?php
|
414 |
-
foreach ( cnb_stripe_get_countries() as $country ) {
|
415 |
-
$selected = '';
|
416 |
-
if (isset($cnb_user->address)) {
|
417 |
-
$selected = $country['code'] === $cnb_user->address->country ? ' selected="selected"' : '';
|
418 |
-
}
|
419 |
-
echo '<option value="' . $country['code'] . '"' . $selected . '>' . $country['country'] . '</option>' . "\n";
|
420 |
-
}
|
421 |
-
?>
|
422 |
-
</select>
|
423 |
-
</label>
|
424 |
-
</td>
|
425 |
-
</tr>
|
426 |
|
427 |
-
<tr class="cnb_show_vat_toggle" style="display:none">
|
428 |
-
<th scope="row"><label for="cnb-euvatbusiness">VAT registered business?</label></th>
|
429 |
-
<td>
|
430 |
-
<input type="hidden" name="user[euvatbusiness]" value="0">
|
431 |
-
<input id="cnb-euvatbusiness" type="checkbox" name="user[euvatbusiness]" value="1"
|
432 |
-
<?php if(!empty($cnb_user->taxIds[0]->value)) { ?>checked="checked"<?php } ?>
|
433 |
-
class="regular-text ltr cnb_eu_values_only">
|
434 |
-
<label for="cnb-euvatbusiness">Yes</label>
|
435 |
-
</td>
|
436 |
-
</tr>
|
437 |
|
438 |
<tr class="cnb_vat_companies_show" style="display:none">
|
439 |
-
<th scope="row"><label for="cnb_profile_vat">VAT number<span class="cnb_required">*</span></label>
|
440 |
</th>
|
441 |
<td>
|
442 |
<input id="cnb_profile_vat" type="text" name="user[taxIds][0][value]"
|
@@ -444,8 +448,7 @@ function cnb_admin_page_profile_edit_render_form($modal = false) {
|
|
444 |
class="regular-text ltr cnb_vat_companies_required cnb_eu_values_only">
|
445 |
<input id="cnb_user_taxids_type" type="hidden" name="user[taxIds][0][type]" value="eu_vat"
|
446 |
class="regular-text ltr cnb_vat_companies_required cnb_eu_values_only">
|
447 |
-
|
448 |
-
VAT.</p>
|
449 |
<?php
|
450 |
if ($cnb_user_stripe_verified) {
|
451 |
echo '<p class="description"><span class="dashicons dashicons-saved"></span><em>Your VAT number is verified.</em></p>';
|
1 |
<?php
|
2 |
+
|
3 |
+
use cnb\admin\models\Cnb_User;
|
4 |
+
|
5 |
function cnb_add_header_profile_edit() {
|
6 |
echo 'Profile';
|
7 |
}
|
309 |
/**
|
310 |
* @param false $modal
|
311 |
*
|
312 |
+
* @return Cnb_User|WP_Error
|
313 |
*/
|
314 |
function cnb_admin_page_profile_edit_render_form($modal = false) {
|
315 |
$cnb_user = CnbAppRemote::cnb_remote_get_user_info();
|
365 |
class="regular-text ltr cnb_vat_companies_required">
|
366 |
</td>
|
367 |
</tr>
|
368 |
+
<tr>
|
369 |
+
<th scope="row"><label for="cnb_profile_country">Country<span class="cnb_required">*</span></label></th>
|
370 |
+
<td>
|
371 |
+
<label>
|
372 |
+
<select id="cnb_profile_country" class="select-menu" name="user[address][country]"
|
373 |
+
required="required">
|
374 |
+
<option value=""></option>
|
375 |
+
<?php
|
376 |
+
foreach ( cnb_stripe_get_countries() as $country ) {
|
377 |
+
$selected = '';
|
378 |
+
if (isset($cnb_user->address)) {
|
379 |
+
$selected = $country['code'] === $cnb_user->address->country ? ' selected="selected"' : '';
|
380 |
+
}
|
381 |
+
echo '<option value="' . $country['code'] . '"' . $selected . '>' . $country['country'] . '</option>' . "\n";
|
382 |
+
}
|
383 |
+
?>
|
384 |
+
</select>
|
385 |
+
</label>
|
386 |
+
</td>
|
387 |
+
</tr>
|
388 |
+
|
389 |
+
<tr class="cnb_show_vat_toggle" style="display:none">
|
390 |
+
<th scope="row"><label for="cnb-euvatbusiness">VAT registered business?</label></th>
|
391 |
+
<td>
|
392 |
+
<input type="hidden" name="user[euvatbusiness]" value="0">
|
393 |
+
<input id="cnb-euvatbusiness" type="checkbox" name="user[euvatbusiness]" value="1"
|
394 |
+
<?php if(!empty($cnb_user->taxIds[0]->value)) { ?>checked="checked"<?php } ?>
|
395 |
+
class="ltr cnb_eu_values_only">
|
396 |
+
<label for="cnb-euvatbusiness">Yes</label>
|
397 |
+
</td>
|
398 |
+
</tr>
|
399 |
|
400 |
<tr class="cnb_vat_companies_show" style="display:none">
|
401 |
<th scope="row"><label for="user[address][line1]">Address<span class="cnb_required">*</span></label></th>
|
412 |
</td>
|
413 |
</tr>
|
414 |
|
415 |
+
<tr>
|
416 |
+
<th scope="row"><label for="user[address][postalCode]"><span class="cnb_ie_only" style="display:none">Eircode/</span>Zip/Postal code<span class="cnb_required">*</span></label></th>
|
417 |
<td>
|
418 |
<input type="text" id="user[address][postalCode]" name="user[address][postalCode]"
|
419 |
value="<?php esc_html_e( isset($cnb_user->address) ? $cnb_user->address->postalCode : '' ) ?>"
|
437 |
</td>
|
438 |
</tr>
|
439 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
|
442 |
<tr class="cnb_vat_companies_show" style="display:none">
|
443 |
+
<th scope="row"><label for="cnb_profile_vat">VAT number<span class="cnb_required">*</span></label>
|
444 |
</th>
|
445 |
<td>
|
446 |
<input id="cnb_profile_vat" type="text" name="user[taxIds][0][value]"
|
448 |
class="regular-text ltr cnb_vat_companies_required cnb_eu_values_only">
|
449 |
<input id="cnb_user_taxids_type" type="hidden" name="user[taxIds][0][type]" value="eu_vat"
|
450 |
class="regular-text ltr cnb_vat_companies_required cnb_eu_values_only">
|
451 |
+
|
|
|
452 |
<?php
|
453 |
if ($cnb_user_stripe_verified) {
|
454 |
echo '<p class="description"><span class="dashicons dashicons-saved"></span><em>Your VAT number is verified.</em></p>';
|
src/admin/settings.php
CHANGED
@@ -93,6 +93,16 @@ function cnb_settings_options_validate($input) {
|
|
93 |
if (isset($input['api_key']) && empty($input['api_key'])) {
|
94 |
unset($input['api_key']);
|
95 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
$updated_options = array_merge($original_settings, $input);
|
98 |
|
@@ -105,6 +115,7 @@ function cnb_settings_options_validate($input) {
|
|
105 |
$updated_options['cloud_use_id'] = $cloud_id;
|
106 |
}
|
107 |
}
|
|
|
108 |
if (!empty($original_settings['api_key']) && !empty($input['api_key']) && $original_settings['api_key'] !== $input['api_key']) {
|
109 |
unset($updated_options['cloud_use_id']);
|
110 |
$cloud_id = CnbAdminCloud::cnb_set_default_option_for_cloud( $updated_options );
|
@@ -191,6 +202,28 @@ function cnb_admin_setting_migrate() {
|
|
191 |
exit;
|
192 |
}
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
function cnb_admin_settings_page() {
|
195 |
global $cnb_options;
|
196 |
|
@@ -203,19 +236,7 @@ function cnb_admin_settings_page() {
|
|
203 |
$api_key = null;
|
204 |
$api_key_ott = filter_input(INPUT_GET, 'api_key_ott', FILTER_SANITIZE_STRING);
|
205 |
if (!empty($api_key_ott)) {
|
206 |
-
$
|
207 |
-
if ($api_key_obj !== null) {
|
208 |
-
if (!is_wp_error($api_key_obj)) {
|
209 |
-
$api_key = $api_key_obj->key;
|
210 |
-
} else {
|
211 |
-
if (empty($cnb_options['api_key'])) {
|
212 |
-
$error_details = CnbAdminCloud::cnb_admin_get_error_message_details( $api_key_obj );
|
213 |
-
$message = '<p>We could not enable <strong>Premium</strong> with the <em>one-time token</em> <code>' . esc_html( $api_key_ott ) . '</code> :-(.' . $error_details . '</p>';
|
214 |
-
$notice = new CnbNotice( 'error', $message );
|
215 |
-
CnbAdminNotices::get_instance()->renderNotice( $notice );
|
216 |
-
}
|
217 |
-
}
|
218 |
-
}
|
219 |
}
|
220 |
|
221 |
// If the API key was not passed via api_key_ott, see if it was passed directly via api_key
|
@@ -281,21 +302,7 @@ function cnb_admin_settings_page() {
|
|
281 |
});
|
282 |
</script>
|
283 |
<?php
|
284 |
-
|
285 |
-
$domain_timezone = $cnb_cloud_domain->timezone;
|
286 |
-
if (empty($domain_timezone)) {
|
287 |
-
$url = admin_url( 'admin.php' );
|
288 |
-
$redirect_link =
|
289 |
-
add_query_arg(
|
290 |
-
array(
|
291 |
-
'page' => 'call-now-button-settings',
|
292 |
-
'tab' => 'advanced_options#domain_timezone',
|
293 |
-
|
294 |
-
),
|
295 |
-
$url );
|
296 |
-
$redirect_url = esc_url( $redirect_link );
|
297 |
-
CnbAdminNotices::get_instance()->renderWarning("<p>Please set your timezone in the <a href=\"". $redirect_url . "\">Advanced settings</a> tab to avoid unpredictable behavior when using the scheduler.</p>");
|
298 |
-
}
|
299 |
} ?>
|
300 |
<div class="cnb-two-column-section">
|
301 |
<div class="cnb-body-column">
|
@@ -384,12 +391,27 @@ function cnb_admin_settings_page() {
|
|
384 |
<tr>
|
385 |
<th scope="row">API key</th>
|
386 |
<td>
|
387 |
-
<?php if ($cnb_user
|
388 |
-
<label
|
389 |
-
|
390 |
-
|
|
|
391 |
<?php } ?>
|
392 |
-
<?php if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
</td>
|
394 |
</tr>
|
395 |
<?php if ($cnb_user !== null && !$cnb_user instanceof WP_Error) { ?>
|
@@ -541,10 +563,10 @@ function cnb_admin_settings_page() {
|
|
541 |
'Go Premium for free',
|
542 |
'Premium comes in 2 versions: <em>Free</em> and <em>Paid</em>.</p>
|
543 |
<p>Both plans give you access to <strong>all features</strong>.</p>
|
544 |
-
<p>The only
|
545 |
'info-outline',
|
546 |
'',
|
547 |
-
'
|
548 |
cnb_legacy_upgrade_page()
|
549 |
);
|
550 |
} ?>
|
93 |
if (isset($input['api_key']) && empty($input['api_key'])) {
|
94 |
unset($input['api_key']);
|
95 |
}
|
96 |
+
// If api_key is "delete_me", this is the special value to trigger "forget this key"
|
97 |
+
if ((isset($input['api_key']) && $input['api_key'] === 'delete_me') ||
|
98 |
+
(isset($original_settings['api_key']) && $original_settings['api_key'] === 'delete_me') ) {
|
99 |
+
$input['api_key'] = '';
|
100 |
+
$updated_options['api_key'] = '';
|
101 |
+
$input['cloud_use_id'] = '';
|
102 |
+
$updated_options['cloud_use_id'] = '';
|
103 |
+
|
104 |
+
$messages[] = new CnbNotice( 'success', '<p>Your API key has been removed - you can now activate Call Now Button with another API key.</p>' );
|
105 |
+
}
|
106 |
|
107 |
$updated_options = array_merge($original_settings, $input);
|
108 |
|
115 |
$updated_options['cloud_use_id'] = $cloud_id;
|
116 |
}
|
117 |
}
|
118 |
+
|
119 |
if (!empty($original_settings['api_key']) && !empty($input['api_key']) && $original_settings['api_key'] !== $input['api_key']) {
|
120 |
unset($updated_options['cloud_use_id']);
|
121 |
$cloud_id = CnbAdminCloud::cnb_set_default_option_for_cloud( $updated_options );
|
202 |
exit;
|
203 |
}
|
204 |
|
205 |
+
/**
|
206 |
+
* @param $api_key_ott
|
207 |
+
*
|
208 |
+
* @return {string} The API key if found
|
209 |
+
*/
|
210 |
+
function cnb_try_api_key_ott($api_key_ott, $render_notice=true) {
|
211 |
+
$api_key_obj = CnbAppRemote::cnb_remote_get_apikey_via_ott($api_key_ott);
|
212 |
+
if ($api_key_obj !== null) {
|
213 |
+
if (!is_wp_error($api_key_obj)) {
|
214 |
+
return $api_key_obj->key;
|
215 |
+
} else {
|
216 |
+
if (empty($cnb_options['api_key']) && $render_notice) {
|
217 |
+
$error_details = CnbAdminCloud::cnb_admin_get_error_message_details( $api_key_obj );
|
218 |
+
$message = '<p>We could not enable <strong>Premium</strong> with the <em>one-time token</em> <code>' . esc_html( $api_key_ott ) . '</code> :-(.' . $error_details . '</p>';
|
219 |
+
$notice = new CnbNotice( 'error', $message );
|
220 |
+
CnbAdminNotices::get_instance()->renderNotice( $notice );
|
221 |
+
}
|
222 |
+
}
|
223 |
+
}
|
224 |
+
return null;
|
225 |
+
}
|
226 |
+
|
227 |
function cnb_admin_settings_page() {
|
228 |
global $cnb_options;
|
229 |
|
236 |
$api_key = null;
|
237 |
$api_key_ott = filter_input(INPUT_GET, 'api_key_ott', FILTER_SANITIZE_STRING);
|
238 |
if (!empty($api_key_ott)) {
|
239 |
+
$api_key = cnb_try_api_key_ott($api_key_ott);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
}
|
241 |
|
242 |
// If the API key was not passed via api_key_ott, see if it was passed directly via api_key
|
302 |
});
|
303 |
</script>
|
304 |
<?php
|
305 |
+
cnb_warn_about_timezone($cnb_cloud_domain);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
} ?>
|
307 |
<div class="cnb-two-column-section">
|
308 |
<div class="cnb-body-column">
|
391 |
<tr>
|
392 |
<th scope="row">API key</th>
|
393 |
<td>
|
394 |
+
<?php if (is_wp_error($cnb_user) || $show_advanced_view_only) { ?>
|
395 |
+
<label>
|
396 |
+
<input type="text" class="regular-text" name="cnb[api_key]" id="cnb_api_key" placeholder="e.g. b52c3f83-38dc-4493-bc90-642da5be7e39"/>
|
397 |
+
</label>
|
398 |
+
<p class="description">Get your API key at <a href="<?php echo CNB_WEBSITE?>"><?php echo CNB_WEBSITE?></a></p>
|
399 |
<?php } ?>
|
400 |
+
<?php if (is_wp_error($cnb_user) && !empty($cnb_options['api_key'])) { ?>
|
401 |
+
<p><span class="dashicons dashicons-warning"></span> There is an API key, but it seems to be invalid or outdated.</p>
|
402 |
+
<p class="description">Clicking "Disconnect account" will drop the API key and disconnect the plugin from your account. You will lose access to your buttons and Premium functionality until you reconnect with a callnowbutton.com account.
|
403 |
+
<br>
|
404 |
+
<input type="button" name="cnb_api_key_delete" id="cnb_api_key_delete" class="button button-link" value="<?php _e('Disconnect account') ?>" onclick="return cnb_delete_apikey();">
|
405 |
+
</p>
|
406 |
+
<?php } ?>
|
407 |
+
<?php if (!is_wp_error($cnb_user) && isset($cnb_options['api_key'])) { ?>
|
408 |
+
<p><strong><span class="dashicons dashicons-saved"></span>Success!</strong> <Br>The plugin is connected to your callnowbutton.com account.</p>
|
409 |
+
<p class="description">Clicking "Disconnect account" will drop the API key and disconnect the plugin from your account. You will lose access to your buttons and Premium functionality until you reconnect with a callnowbutton.com account.
|
410 |
+
<br>
|
411 |
+
<input type="button" name="cnb_api_key_delete" id="cnb_api_key_delete" class="button button-link" value="<?php _e('Disconnect account') ?>" onclick="return cnb_delete_apikey();">
|
412 |
+
</p>
|
413 |
+
<input type="hidden" name="cnb[api_key]" id="cnb_api_key" value="delete_me" disabled="disabled" />
|
414 |
+
<?php }?>
|
415 |
</td>
|
416 |
</tr>
|
417 |
<?php if ($cnb_user !== null && !$cnb_user instanceof WP_Error) { ?>
|
563 |
'Go Premium for free',
|
564 |
'Premium comes in 2 versions: <em>Free</em> and <em>Paid</em>.</p>
|
565 |
<p>Both plans give you access to <strong>all features</strong>.</p>
|
566 |
+
<p>The only differences are that the Free version shows <em>Powered by Call Now Button</em> next to your buttons and there\'s a monthly pageviews limit of 20k.</p>',
|
567 |
'info-outline',
|
568 |
'',
|
569 |
+
'Try Premium',
|
570 |
cnb_legacy_upgrade_page()
|
571 |
);
|
572 |
} ?>
|
src/autoload.php
CHANGED
@@ -16,6 +16,7 @@ spl_autoload_register(
|
|
16 |
'cnbactionproperties' => '/admin/models/CnbAction.class.php',
|
17 |
'cnbadmincloud' => '/admin/api/CnbAdminCloud.php',
|
18 |
'cnbadminnotices' => '/utils/CnbAdminNotices.class.php',
|
|
|
19 |
'cnbappremote' => '/admin/api/CnbAppRemote.php',
|
20 |
'cnbappremotehelper' => '/admin/api/CnbAppRemote.php',
|
21 |
'cnbappremotepayment' => '/admin/api/CnbAppRemotePayment.php',
|
16 |
'cnbactionproperties' => '/admin/models/CnbAction.class.php',
|
17 |
'cnbadmincloud' => '/admin/api/CnbAdminCloud.php',
|
18 |
'cnbadminnotices' => '/utils/CnbAdminNotices.class.php',
|
19 |
+
'cnbapikey' => '/admin/models/CnbApiKey.class.php',
|
20 |
'cnbappremote' => '/admin/api/CnbAppRemote.php',
|
21 |
'cnbappremotehelper' => '/admin/api/CnbAppRemote.php',
|
22 |
'cnbappremotepayment' => '/admin/api/CnbAppRemotePayment.php',
|
src/call-now-button.php
CHANGED
@@ -6,6 +6,11 @@ require_once dirname( __FILE__ ) . '/admin/admin-ajax.php';
|
|
6 |
require_once dirname( __FILE__ ) . '/utils/CnbAdminNotices.class.php';
|
7 |
require_once dirname( __FILE__ ) . '/admin/partials/admin-header.php';
|
8 |
|
|
|
|
|
|
|
|
|
|
|
9 |
/**
|
10 |
* There are a few global used throughout the plugin.
|
11 |
*
|
@@ -98,8 +103,8 @@ function cnb_register_admin_pages() {
|
|
98 |
$has_changelog = has_changelog($cnb_options);
|
99 |
if ($has_changelog) $counter++;
|
100 |
|
101 |
-
$
|
102 |
-
if ($
|
103 |
|
104 |
// Detect errors (specific, - Premium enabled, but API key is not present yet)
|
105 |
if ($cnb_cloud_hosting && !array_key_exists('api_key', $cnb_options)) {
|
@@ -350,6 +355,12 @@ function cnb_options_init() {
|
|
350 |
array(CNB_SLUG . '-call-now-button'),
|
351 |
CNB_VERSION,
|
352 |
true);
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
|
354 |
// Special case: since the preview functionality depends on this,
|
355 |
// and the source is always changing - we include it as external script
|
6 |
require_once dirname( __FILE__ ) . '/utils/CnbAdminNotices.class.php';
|
7 |
require_once dirname( __FILE__ ) . '/admin/partials/admin-header.php';
|
8 |
|
9 |
+
// Only include the WP_CLI suite when it is available
|
10 |
+
if ( class_exists( 'WP_CLI' ) && class_exists( 'WP_CLI_Command' ) ) {
|
11 |
+
require_once dirname( __FILE__ ) . '/cli/CNB_CLI.class.php';
|
12 |
+
}
|
13 |
+
|
14 |
/**
|
15 |
* There are a few global used throughout the plugin.
|
16 |
*
|
103 |
$has_changelog = has_changelog($cnb_options);
|
104 |
if ($has_changelog) $counter++;
|
105 |
|
106 |
+
$has_welcome_banner = cnb_show_welcome_banner() && !$cnb_cloud_hosting;
|
107 |
+
if ($has_welcome_banner) $counter++;
|
108 |
|
109 |
// Detect errors (specific, - Premium enabled, but API key is not present yet)
|
110 |
if ($cnb_cloud_hosting && !array_key_exists('api_key', $cnb_options)) {
|
355 |
array(CNB_SLUG . '-call-now-button'),
|
356 |
CNB_VERSION,
|
357 |
true);
|
358 |
+
wp_register_script(
|
359 |
+
CNB_SLUG . '-action-edit-scheduler',
|
360 |
+
plugins_url( '../resources/js/action-edit-scheduler.js', __FILE__ ),
|
361 |
+
array(CNB_SLUG . '-call-now-button'),
|
362 |
+
CNB_VERSION,
|
363 |
+
true);
|
364 |
|
365 |
// Special case: since the preview functionality depends on this,
|
366 |
// and the source is always changing - we include it as external script
|
src/cli/CNB_CLI.class.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace cnb\cli;
|
4 |
+
|
5 |
+
use WP_CLI;
|
6 |
+
use WP_CLI_Command;
|
7 |
+
|
8 |
+
require_once dirname( __FILE__ ) . '/CNB_CLI_Api.class.php';
|
9 |
+
require_once dirname( __FILE__ ) . '/CNB_CLI_User.class.php';
|
10 |
+
require_once dirname( __FILE__ ) . '/CNB_CLI_Button.class.php';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Adds, removes and fetches Call Now Buttons objects
|
14 |
+
*
|
15 |
+
* @since 1.0.6
|
16 |
+
* @author Jasper Roel
|
17 |
+
*
|
18 |
+
* @noinspection PhpUnused (it is used as a WP CLI class)
|
19 |
+
*/
|
20 |
+
class CNB_CLI extends WP_CLI_Command {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Registers the Call Now Button commands when CLI gets initialized.
|
24 |
+
*
|
25 |
+
* @noinspection PhpUnused (it is used via cli_init)
|
26 |
+
*/
|
27 |
+
static function cli_register_command() {
|
28 |
+
WP_CLI::add_command( 'cnb', 'cnb\cli\CNB_CLI' );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
add_action( 'cli_init', '\cnb\cli\CNB_CLI::cli_register_command' );
|
src/cli/CNB_CLI_Api.class.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace cnb\cli;
|
4 |
+
|
5 |
+
use CnbAdminCloud;
|
6 |
+
use WP_CLI;
|
7 |
+
use WP_CLI_Command;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Adds, removes and fetches Call Now Buttons API keys
|
11 |
+
*
|
12 |
+
* @since 1.0.6
|
13 |
+
* @author Jasper Roel
|
14 |
+
*
|
15 |
+
* @noinspection PhpUnused (it is used as a WP CLI class)
|
16 |
+
*/
|
17 |
+
class CNB_CLI_Api extends WP_CLI_Command {
|
18 |
+
private $adminCloud;
|
19 |
+
|
20 |
+
public function __construct() {
|
21 |
+
$this->adminCloud = new CnbAdminCloud();
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Gets the stored API key
|
26 |
+
*
|
27 |
+
* It will only show the first part by default, so it can be safely passed to Support
|
28 |
+
*
|
29 |
+
* ## OPTIONS
|
30 |
+
*
|
31 |
+
* [--reveal]
|
32 |
+
* : Shows the full API key
|
33 |
+
*
|
34 |
+
* ## Examples
|
35 |
+
*
|
36 |
+
* # Get the API key
|
37 |
+
* $ wp cnb api get
|
38 |
+
* Success: 0a45e023-1242-4410-a17a-xxxxxxxxxxxx
|
39 |
+
*
|
40 |
+
* # Get the API key and reveal it
|
41 |
+
* $ wp cnb api get --reveal
|
42 |
+
* Success: 0a45e023-1242-4410-a17a-123456789012
|
43 |
+
*
|
44 |
+
* @param $args array [optional]
|
45 |
+
* @param $assoc_args array [optional]
|
46 |
+
*
|
47 |
+
*
|
48 |
+
* @return void
|
49 |
+
*
|
50 |
+
* @noinspection PhpUnusedParameterInspection ($args is required for a CLI command)
|
51 |
+
*/
|
52 |
+
function get($args = array(), $assoc_args = array()) {
|
53 |
+
|
54 |
+
$options = get_option('cnb');
|
55 |
+
if (is_array($options) && key_exists('api_key', $options)) {
|
56 |
+
$key = $options['api_key'];
|
57 |
+
if (!isset($assoc_args['reveal'])) {
|
58 |
+
$key = $this->obfuscate_key( $options['api_key'] );
|
59 |
+
}
|
60 |
+
WP_CLI::success( $key );
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
WP_CLI::warning('API key not found');
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Set the provided API key
|
68 |
+
*
|
69 |
+
* ## OPTIONS
|
70 |
+
*
|
71 |
+
* <api_key>
|
72 |
+
* : The API key to set.
|
73 |
+
*
|
74 |
+
* [--set-if-valid]
|
75 |
+
* : Only store the API key if valid
|
76 |
+
*
|
77 |
+
* ## EXAMPLES
|
78 |
+
*
|
79 |
+
* # Set an API key
|
80 |
+
* $ wp cnb api set 0a45e023-...
|
81 |
+
*
|
82 |
+
* # Set an API key (but only if the key is tested and valid)
|
83 |
+
* $ wp cnb api set 0a45e023-... --set-if-valid
|
84 |
+
*
|
85 |
+
* @param $args array should contain 1 entry, only the API key
|
86 |
+
* @param $assoc_args array [optional]
|
87 |
+
*
|
88 |
+
* @return void
|
89 |
+
*
|
90 |
+
*/
|
91 |
+
public function set($args, $assoc_args) {
|
92 |
+
// Check of key is provided
|
93 |
+
if (sizeof($args) !== 1) {
|
94 |
+
WP_CLI::error('Wrong amount of arguments, 1 (the API key) expected');
|
95 |
+
return;
|
96 |
+
}
|
97 |
+
|
98 |
+
$api_key = $args[0];
|
99 |
+
WP_CLI::log( sprintf('Key provided: %s',
|
100 |
+
WP_CLI::colorize(sprintf('%%G%s%%n', $api_key))
|
101 |
+
));
|
102 |
+
|
103 |
+
if (isset($assoc_args['set-if-valid'])) {
|
104 |
+
WP_CLI::log('Testing key...');
|
105 |
+
$is_valid = $this->test_api_key($api_key);
|
106 |
+
if ($is_valid) {
|
107 |
+
$options = array();
|
108 |
+
$options['api_key'] = $api_key;
|
109 |
+
update_option('cnb', $options);
|
110 |
+
WP_CLI::success('API key updated');
|
111 |
+
} else {
|
112 |
+
WP_CLI::error('API key incorrect, nothing updated');
|
113 |
+
}
|
114 |
+
return;
|
115 |
+
}
|
116 |
+
|
117 |
+
// No options provided, just set the key
|
118 |
+
$options = array();
|
119 |
+
$options['api_key'] = $api_key;
|
120 |
+
update_option('cnb', $options);
|
121 |
+
WP_CLI::success('API key updated');
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Test the provided API key
|
126 |
+
*
|
127 |
+
* ## OPTIONS
|
128 |
+
*
|
129 |
+
* <api_key>
|
130 |
+
* : The API key to test.
|
131 |
+
*
|
132 |
+
* ## EXAMPLES
|
133 |
+
*
|
134 |
+
* # Test an API key
|
135 |
+
* $ wp cnb api test 0a45e023-...
|
136 |
+
*
|
137 |
+
*
|
138 |
+
* @param $args {array} should contain 1 entry, only the API key
|
139 |
+
*
|
140 |
+
* @return boolean true if valid
|
141 |
+
*
|
142 |
+
*/
|
143 |
+
public function test($args) {
|
144 |
+
// Check of key is provided
|
145 |
+
if (sizeof($args) !== 1) {
|
146 |
+
WP_CLI::error('Wrong amount of arguments, 1 (the API key) expected');
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
$api_key = $args[0];
|
150 |
+
|
151 |
+
WP_CLI::log('Testing key...');
|
152 |
+
$is_valid = $this->test_api_key($api_key);
|
153 |
+
if ($is_valid) {
|
154 |
+
WP_CLI::success('API key valid');
|
155 |
+
} else {
|
156 |
+
WP_CLI::error('API key invalid');
|
157 |
+
}
|
158 |
+
return $is_valid;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @param $api_key string the API key to test
|
163 |
+
*
|
164 |
+
* @return boolean true if the key is valid
|
165 |
+
*/
|
166 |
+
private function test_api_key($api_key) {
|
167 |
+
return $this->adminCloud->is_api_key_valid($api_key);
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param $api_key string any API key
|
172 |
+
*
|
173 |
+
* @return string Obfucscated string (last part of key removed)
|
174 |
+
*/
|
175 |
+
private function obfuscate_key($api_key) {
|
176 |
+
$hide_chars = 12;
|
177 |
+
return substr($api_key, 0, -$hide_chars)
|
178 |
+
. str_repeat('x', $hide_chars);
|
179 |
+
}
|
180 |
+
/**
|
181 |
+
* Registers the Call Now Button commands when CLI gets initialized.
|
182 |
+
*
|
183 |
+
* @noinspection PhpUnused (it is used via cli_init)
|
184 |
+
*/
|
185 |
+
static function cli_register_command() {
|
186 |
+
WP_CLI::add_command( 'cnb api', 'cnb\cli\CNB_CLI_Api' );
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
add_action( 'cli_init', '\cnb\cli\CNB_CLI_Api::cli_register_command' );
|
src/cli/CNB_CLI_Button.class.php
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace cnb\cli;
|
4 |
+
|
5 |
+
use CnbAdminCloud;
|
6 |
+
use CnbAppRemote;
|
7 |
+
use CnbButton;
|
8 |
+
use CnbButtonOptions;
|
9 |
+
use WP_CLI;
|
10 |
+
use WP_CLI_Command;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Query the Call Now Button Buttons
|
14 |
+
*
|
15 |
+
* @since 1.0.6
|
16 |
+
* @author Jasper Roel
|
17 |
+
*
|
18 |
+
* @noinspection PhpUnused (it is used as a WP CLI class)
|
19 |
+
*/
|
20 |
+
class CNB_CLI_Button extends WP_CLI_Command {
|
21 |
+
/**
|
22 |
+
* List all the buttons for this User
|
23 |
+
*
|
24 |
+
* ## OPTIONS
|
25 |
+
*
|
26 |
+
* [--format=<format>]
|
27 |
+
* : Render output in a particular format.
|
28 |
+
* ---
|
29 |
+
* default: table
|
30 |
+
*
|
31 |
+
* options:
|
32 |
+
* - table
|
33 |
+
* - csv
|
34 |
+
* - json
|
35 |
+
* - count
|
36 |
+
* - yaml
|
37 |
+
* ---
|
38 |
+
*
|
39 |
+
* [--fields=<fields>]
|
40 |
+
* : Render specific fields. Default is to show all available fields.
|
41 |
+
* ---
|
42 |
+
* default: id,name,active,type,domain,actions,conditions,options
|
43 |
+
*
|
44 |
+
* options:
|
45 |
+
* - id
|
46 |
+
* - name
|
47 |
+
* - active
|
48 |
+
* - type
|
49 |
+
* - domain
|
50 |
+
* - actions
|
51 |
+
* - conditions
|
52 |
+
* - options
|
53 |
+
* ---
|
54 |
+
*
|
55 |
+
* ## EXAMPLES
|
56 |
+
*
|
57 |
+
* # List all buttons
|
58 |
+
* $ wp cnb button list
|
59 |
+
*
|
60 |
+
* # Specify fields
|
61 |
+
* $ wp cnb button list --fields=id,name,active
|
62 |
+
*
|
63 |
+
* # Specify output
|
64 |
+
* $ wp cnb button list --output=yaml
|
65 |
+
*
|
66 |
+
* # Specify fields and output
|
67 |
+
* $ wp cnb button list --fields=id,name --output=yaml
|
68 |
+
*
|
69 |
+
* @subcommand list
|
70 |
+
*/
|
71 |
+
public function list_($args, $assoc_args) {
|
72 |
+
$buttons = CnbAppRemote::cnb_remote_get_buttons();
|
73 |
+
if (!is_wp_error($buttons)) {
|
74 |
+
// Convert into array
|
75 |
+
$items = CnbButton::convert($buttons);
|
76 |
+
|
77 |
+
$format = WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'table' );
|
78 |
+
$fields = WP_CLI\Utils\get_flag_value( $assoc_args, 'fields', array( 'id', 'name', 'active', 'type', 'domain', 'actions', 'conditions', 'options' ) );
|
79 |
+
WP_CLI::log($fields);
|
80 |
+
WP_CLI\Utils\format_items( $format, $items, $fields );
|
81 |
+
WP_CLI::log(''); // Force a new line since that isn't included in the format_items output
|
82 |
+
} else {
|
83 |
+
WP_CLI::error($buttons, false);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Create a Button
|
89 |
+
*
|
90 |
+
* ## OPTIONS
|
91 |
+
*
|
92 |
+
* <name>
|
93 |
+
* : The name of the Button
|
94 |
+
*
|
95 |
+
* [--type=<type>]
|
96 |
+
* : default: SINGLE
|
97 |
+
* ---
|
98 |
+
* options:
|
99 |
+
* - SINGLE
|
100 |
+
* - FULL
|
101 |
+
* - MULTI
|
102 |
+
* ---
|
103 |
+
*
|
104 |
+
* [--active=<action>]
|
105 |
+
* : default: true
|
106 |
+
* ---
|
107 |
+
* options:
|
108 |
+
* - true
|
109 |
+
* - false
|
110 |
+
* ---
|
111 |
+
*
|
112 |
+
* [--placement=<placement>]
|
113 |
+
* : default: BOTTOM_RIGHT
|
114 |
+
* ---
|
115 |
+
* options:
|
116 |
+
* - BOTTOM_LEFT
|
117 |
+
* - BOTTOM_CENTER
|
118 |
+
* - BOTTOM_RIGHT
|
119 |
+
* - MIDDLE_LEFT
|
120 |
+
* - MIDDLE_RIGHT
|
121 |
+
* - TOP_LEFT
|
122 |
+
* - TOP_CENTER
|
123 |
+
* - TOP_RIGHT
|
124 |
+
*
|
125 |
+
* ## EXAMPLES
|
126 |
+
*
|
127 |
+
* # Create a button
|
128 |
+
* $ wp cnb button create "Button via WP CLI"
|
129 |
+
*
|
130 |
+
* # Create a MULTI button
|
131 |
+
* $ wp cnb button create "Multi Button via WP CLI" --type=MULTI
|
132 |
+
*
|
133 |
+
* # Create an inactive FULL button
|
134 |
+
* $ wp cnb button create "Full Button via WP CLI" --type=FULL --active=false
|
135 |
+
*
|
136 |
+
* # Create an FULL button with TOP_CENTER placement
|
137 |
+
* $ wp cnb button create "Full Button at top via WP CLI" --type=FULL --placement=TOP_CENTER
|
138 |
+
* @return void
|
139 |
+
*/
|
140 |
+
public function create($args, $assoc_args) {
|
141 |
+
// Check of key is provided
|
142 |
+
if (sizeof($args) !== 1) {
|
143 |
+
WP_CLI::error('Wrong amount of arguments, 1 (the name) expected');
|
144 |
+
return;
|
145 |
+
}
|
146 |
+
|
147 |
+
list ($button_name) = $args;
|
148 |
+
|
149 |
+
$notifications = array();
|
150 |
+
|
151 |
+
$default_domain = CnbAppRemote::cnb_remote_get_wp_domain();
|
152 |
+
|
153 |
+
$button = new CnbButton();
|
154 |
+
$button->name = $button_name;
|
155 |
+
$button->type = WP_CLI\Utils\get_flag_value( $assoc_args, 'type', 'SINGLE' );
|
156 |
+
$button->active = WP_CLI\Utils\get_flag_value( $assoc_args, 'active', 'true' ) == 'true';
|
157 |
+
$button->domain = $default_domain->id;
|
158 |
+
|
159 |
+
$options = new CnbButtonOptions();
|
160 |
+
$options->placement = WP_CLI\Utils\get_flag_value( $assoc_args, 'placement', 'BOTTOM_RIGHT' );
|
161 |
+
$button->options = $options;
|
162 |
+
|
163 |
+
$result = CnbAdminCloud::cnb_create_button( $notifications, $button->toArray() );
|
164 |
+
if ( is_wp_error( $result ) ) {
|
165 |
+
WP_CLI::error( $result );
|
166 |
+
}
|
167 |
+
WP_CLI::success('Created ' . $result->name . ' with ID ' .$result->id);
|
168 |
+
|
169 |
+
}
|
170 |
+
/**
|
171 |
+
* Registers the Call Now Button commands when CLI gets initialized.
|
172 |
+
*
|
173 |
+
* @noinspection PhpUnused (it is used via cli_init)
|
174 |
+
*/
|
175 |
+
static function cli_register_command() {
|
176 |
+
WP_CLI::add_command( 'cnb button', 'cnb\cli\CNB_CLI_Button' );
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
add_action( 'cli_init', '\cnb\cli\CNB_CLI_Button::cli_register_command' );
|
src/cli/CNB_CLI_User.class.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace cnb\cli;
|
4 |
+
|
5 |
+
use cnb\admin\models\Cnb_User;
|
6 |
+
use CnbAppRemote;
|
7 |
+
use WP_CLI;
|
8 |
+
use WP_CLI_Command;
|
9 |
+
use WP_Error;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Query the Call Now Button User
|
13 |
+
*
|
14 |
+
* @since 1.0.6
|
15 |
+
* @author Jasper Roel
|
16 |
+
*
|
17 |
+
* @noinspection PhpUnused (it is used as a WP CLI class)
|
18 |
+
*/
|
19 |
+
class CNB_CLI_User extends WP_CLI_Command {
|
20 |
+
/**
|
21 |
+
* Returns the logged-in User
|
22 |
+
*
|
23 |
+
* ## EXAMPLES
|
24 |
+
*
|
25 |
+
* # Get the current logged-in User
|
26 |
+
* $ wp cnb user get
|
27 |
+
* ID: 67a54fd0-b048-4522-8e23-ddfeffa6b129
|
28 |
+
* Name: Jasper Roel
|
29 |
+
* Email: jasper@studiostacks.com
|
30 |
+
*
|
31 |
+
* @return Cnb_User|WP_Error
|
32 |
+
*/
|
33 |
+
public function get() {
|
34 |
+
$user = CnbAppRemote::cnb_remote_get_user_info();
|
35 |
+
if (!is_wp_error($user)) {
|
36 |
+
WP_CLI::log( sprintf( 'ID: %s', $user->id ) );
|
37 |
+
WP_CLI::log( sprintf( 'Name: %s', $user->name ) );
|
38 |
+
WP_CLI::log(
|
39 |
+
sprintf( 'Email: %s',
|
40 |
+
WP_CLI::colorize(
|
41 |
+
sprintf( '%%G%s%%n', $user->email )
|
42 |
+
)
|
43 |
+
)
|
44 |
+
);
|
45 |
+
} else {
|
46 |
+
WP_CLI::error($user, false);
|
47 |
+
}
|
48 |
+
return $user;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Registers the Call Now Button commands when CLI gets initialized.
|
53 |
+
*
|
54 |
+
* @noinspection PhpUnused (it is used via cli_init)
|
55 |
+
*/
|
56 |
+
static function cli_register_command() {
|
57 |
+
WP_CLI::add_command( 'cnb user', 'cnb\cli\CNB_CLI_User' );
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
add_action( 'cli_init', '\cnb\cli\CNB_CLI_User::cli_register_command' );
|
src/cli/mocks/WP_CLI.class.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// This file should not be "require"d anywhere
|
4 |
+
|
5 |
+
// These are not a real classes, but mocks only used during development
|
6 |
+
// So the IDE is "tricked" into knowing the class and functions without
|
7 |
+
// having to include the whole WP_CLI suite during development.
|
8 |
+
|
9 |
+
if (!class_exists('WP_CLI')) {
|
10 |
+
class WP_CLI {
|
11 |
+
|
12 |
+
public static function error( $string, $die=true ) {
|
13 |
+
}
|
14 |
+
|
15 |
+
public static function colorize( $sprintf ) {
|
16 |
+
return '';
|
17 |
+
}
|
18 |
+
|
19 |
+
public static function success( $string ) {
|
20 |
+
}
|
21 |
+
|
22 |
+
public static function log( $string ) {
|
23 |
+
}
|
24 |
+
|
25 |
+
public static function add_command( $string, $string1 ) {
|
26 |
+
}
|
27 |
+
|
28 |
+
public static function warning( $string ) {
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
if (!class_exists('WP_CLI_Command')) {
|
34 |
+
class WP_CLI_Command {}
|
35 |
+
}
|
src/cli/mocks/WP_CLI_Utils.class.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// This file should not be "require"d anywhere
|
3 |
+
|
4 |
+
// These are not a real classes or functions, but mocks only used during development
|
5 |
+
// So the IDE is "tricked" into knowing the class and functions without
|
6 |
+
// having to include the whole WP_CLI suite during development.
|
7 |
+
|
8 |
+
namespace WP_CLI\Utils;
|
9 |
+
|
10 |
+
function get_flag_value($array, $value, $default) { return ''; }
|
11 |
+
function format_items($format, $items, $fields) {}
|
src/utils/notices.php
CHANGED
@@ -49,12 +49,13 @@ function cnb_upgrade_notice($cnb_options, $cnb_changelog) {
|
|
49 |
}
|
50 |
|
51 |
function cnb_settings_email_activation_input() {
|
52 |
-
$message
|
53 |
-
$message .= '<input type="text" class="
|
54 |
$message .= get_submit_button(__('Activate Premium'), 'primary', 'cnb_email_activation_alternate', false, array('onclick' => 'return cnb_email_activation_alternate()'));
|
55 |
$message .= '</div>';
|
56 |
$message .= '<p id="cnb_email_activation"></p>';
|
57 |
-
|
|
|
58 |
|
59 |
return $message;
|
60 |
}
|
@@ -117,7 +118,7 @@ function cnb_settings_api_key_input() {
|
|
117 |
$message .= ob_get_clean();
|
118 |
$message .= '<input type="hidden" name="page" value="call-now-button-settings" />
|
119 |
<div>
|
120 |
-
<input type="text" class="
|
121 |
placeholder="Paste API key here"/>
|
122 |
'. get_submit_button(__('Store API key'), 'primary', 'submit', false).'
|
123 |
</div>
|
@@ -199,7 +200,7 @@ function cnb_button_disabled_notice() {
|
|
199 |
$url );
|
200 |
$redirect_url = esc_url( $redirect_link );
|
201 |
|
202 |
-
$message = '<p>
|
203 |
|
204 |
$adminNotices = CnbAdminNotices::get_instance();
|
205 |
$adminNotices->warning($message);
|
@@ -231,16 +232,16 @@ function cnb_caching_plugin_warning_notice($caching_plugin_name) {
|
|
231 |
$adminNotices->error($message);
|
232 |
}
|
233 |
|
234 |
-
function
|
235 |
-
$
|
236 |
-
$dismissed_option = CnbAdminNotices::get_instance()->get_dismiss_option_name($
|
237 |
$is_dismissed = CnbAdminNotices::get_instance()->is_dismissed($dismissed_option);
|
238 |
return !$is_dismissed;
|
239 |
}
|
240 |
|
241 |
-
function
|
242 |
-
if (!
|
243 |
-
$
|
244 |
|
245 |
$url = admin_url('admin.php');
|
246 |
$upgrade_link =
|
@@ -251,47 +252,73 @@ function cnb_get_welcome_panel() {
|
|
251 |
|
252 |
$dismiss_data_url = '';
|
253 |
$dismiss_url = add_query_arg( array(
|
254 |
-
CNB_SLUG . '_dismiss' => $
|
255 |
), $url );
|
256 |
|
257 |
$dismiss_data_url .= ' data-dismiss-url="' . esc_url( $dismiss_url ) . '"';
|
258 |
|
259 |
?>
|
260 |
-
<div id="welcome-
|
261 |
-
<
|
262 |
-
|
263 |
-
<div class="welcome-panel-content">
|
264 |
-
<h2>Welcome to Call Now Button verson 1.0</h2>
|
265 |
<p class="about-description">After 10 years we have finally reached v1!</p>
|
266 |
-
<div class="welcome-
|
267 |
-
<div class="welcome-
|
268 |
<h3>Here's why</h3>
|
269 |
<div class="welcome-column-box">
|
270 |
<p class="only-in-columns">Why we promoted the plugin from the zeros to a 1:</p>
|
271 |
|
272 |
-
<p class="cnb-mobile-inline">🎉 The Call Now Button is turning 10!</p>
|
273 |
<p class="cnb-mobile-inline">❤️ 200k+ active installs and rated 4.9!</p>
|
274 |
-
<p class="cnb-mobile-inline">💎 Premium
|
275 |
</div>
|
276 |
</div>
|
277 |
-
<div class="welcome-
|
278 |
-
<h3>What's
|
279 |
<p class="cnb-mobile-inline">+ Create multiple buttons</p>
|
280 |
-
<p class="cnb-mobile-inline">+ WhatsApp, Email, Maps and Links</p>
|
281 |
-
<p class="cnb-mobile-inline">+
|
282 |
<p class="cnb-mobile-inline">+ Button scheduler</p>
|
283 |
<p class="cnb-mobile-inline">+ Advanced page targeting</p>
|
284 |
</div>
|
285 |
-
<div class="welcome-
|
286 |
-
<a class="button button-primary button-hero" href="<?php echo $upgrade_url ?>">
|
287 |
-
<p
|
288 |
<h3>Other resources</h3>
|
289 |
-
<p>
|
290 |
-
|
291 |
-
<a href="<?php echo CNB_SUPPORT; ?>wordpress-free/#faq">FAQ</a>
|
292 |
-
</p>
|
293 |
</div>
|
294 |
</div>
|
295 |
</div>
|
|
|
296 |
</div>
|
297 |
<?php }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
function cnb_settings_email_activation_input() {
|
52 |
+
$message = '<div id="cnb_email_activation_alternate_formd">';
|
53 |
+
$message .= '<input type="text" class="cnb_activation_input_field" name="cnb_email_activation_alternate_address" id="cnb_email_activation_alternate_address" placeholder="email@example.com" value="' . esc_attr(get_bloginfo('admin_email')) . '"/> ';
|
54 |
$message .= get_submit_button(__('Activate Premium'), 'primary', 'cnb_email_activation_alternate', false, array('onclick' => 'return cnb_email_activation_alternate()'));
|
55 |
$message .= '</div>';
|
56 |
$message .= '<p id="cnb_email_activation"></p>';
|
57 |
+
|
58 |
+
$message .= '<p class="nonessential">By clicking <u>Activate Premium</u> an account will be created with your email address on callnowbutton.com and you agree to our <a href="https://callnowbutton.com/terms.html" target="_blank">Terms & Conditions</a> and <a href="https://callnowbutton.com/privacy.html" target="_blank">Privacy statement</a>. You also acknowledge that the Free plan allows up to 20k pageviews per month.</p>';
|
59 |
|
60 |
return $message;
|
61 |
}
|
118 |
$message .= ob_get_clean();
|
119 |
$message .= '<input type="hidden" name="page" value="call-now-button-settings" />
|
120 |
<div>
|
121 |
+
<input type="text" class="cnb_activation_input_field" name="cnb[api_key]"
|
122 |
placeholder="Paste API key here"/>
|
123 |
'. get_submit_button(__('Store API key'), 'primary', 'submit', false).'
|
124 |
</div>
|
200 |
$url );
|
201 |
$redirect_url = esc_url( $redirect_link );
|
202 |
|
203 |
+
$message = '<p>The Call Now Button is currently <strong>inactive</strong>.';
|
204 |
|
205 |
$adminNotices = CnbAdminNotices::get_instance();
|
206 |
$adminNotices->warning($message);
|
232 |
$adminNotices->error($message);
|
233 |
}
|
234 |
|
235 |
+
function cnb_show_welcome_banner() {
|
236 |
+
$dismiss_value = 'welcome-panel';
|
237 |
+
$dismissed_option = CnbAdminNotices::get_instance()->get_dismiss_option_name($dismiss_value);
|
238 |
$is_dismissed = CnbAdminNotices::get_instance()->is_dismissed($dismissed_option);
|
239 |
return !$is_dismissed;
|
240 |
}
|
241 |
|
242 |
+
function cnb_get_welcome_banner() {
|
243 |
+
if (!cnb_show_welcome_banner()) return;
|
244 |
+
$dismiss_value = 'welcome-panel';
|
245 |
|
246 |
$url = admin_url('admin.php');
|
247 |
$upgrade_link =
|
252 |
|
253 |
$dismiss_data_url = '';
|
254 |
$dismiss_url = add_query_arg( array(
|
255 |
+
CNB_SLUG . '_dismiss' => $dismiss_value
|
256 |
), $url );
|
257 |
|
258 |
$dismiss_data_url .= ' data-dismiss-url="' . esc_url( $dismiss_url ) . '"';
|
259 |
|
260 |
?>
|
261 |
+
<div id="welcome-banner" class="welcome-banner is-dismissible notice-call-now-button" <?php echo $dismiss_data_url ?>>
|
262 |
+
<div class="welcome-banner-content">
|
263 |
+
<h2>Welcome to Call Now Button verson 1.0</h2>
|
|
|
|
|
264 |
<p class="about-description">After 10 years we have finally reached v1!</p>
|
265 |
+
<div class="welcome-banner-column-container">
|
266 |
+
<div class="welcome-banner-column">
|
267 |
<h3>Here's why</h3>
|
268 |
<div class="welcome-column-box">
|
269 |
<p class="only-in-columns">Why we promoted the plugin from the zeros to a 1:</p>
|
270 |
|
271 |
+
<p class="cnb-mobile-inline">🎉 The Call Now Button is turning 10 years!</p>
|
272 |
<p class="cnb-mobile-inline">❤️ 200k+ active installs and rated 4.9!</p>
|
273 |
+
<p class="cnb-mobile-inline">💎 Call Now Button <strong>Premium</strong> is finally here!</p>
|
274 |
</div>
|
275 |
</div>
|
276 |
+
<div class="welcome-banner-column">
|
277 |
+
<h3>What's Premium?</h3>
|
278 |
<p class="cnb-mobile-inline">+ Create multiple buttons</p>
|
279 |
+
<p class="cnb-mobile-inline">+ WhatsApp, SMS/text, Email, Maps and Links</p>
|
280 |
+
<p class="cnb-mobile-inline">+ Multi action buttons</p>
|
281 |
<p class="cnb-mobile-inline">+ Button scheduler</p>
|
282 |
<p class="cnb-mobile-inline">+ Advanced page targeting</p>
|
283 |
</div>
|
284 |
+
<div class="welcome-banner-column">
|
285 |
+
<a class="button button-primary button-hero" href="<?php echo $upgrade_url ?>">Try Premium for Free</a>
|
286 |
+
<p><a href="<?php echo $upgrade_url ?>">More info about Premium</a></p>
|
287 |
<h3>Other resources</h3>
|
288 |
+
<p><a href="<?php echo CNB_SUPPORT; ?>wordpress-free/">The new help center</a></p>
|
289 |
+
<p><a href="<?php echo CNB_SUPPORT; ?>wordpress-free/#faq">FAQ</a></p>
|
|
|
|
|
290 |
</div>
|
291 |
</div>
|
292 |
</div>
|
293 |
+
<button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php _e('Dismiss this notice.') ?></span></button>
|
294 |
</div>
|
295 |
<?php }
|
296 |
+
|
297 |
+
/**
|
298 |
+
*
|
299 |
+
* Also warning if timezone is not yet set
|
300 |
+
* @param $domain
|
301 |
+
*
|
302 |
+
* @return boolean true is all is alright
|
303 |
+
*/
|
304 |
+
function cnb_warn_about_timezone($domain) {
|
305 |
+
if ($domain && !is_wp_error($domain)) {
|
306 |
+
$domain_timezone = $domain->timezone;
|
307 |
+
if ( empty( $domain_timezone ) ) {
|
308 |
+
$url = admin_url( 'admin.php' );
|
309 |
+
$redirect_link =
|
310 |
+
add_query_arg(
|
311 |
+
array(
|
312 |
+
'page' => 'call-now-button-settings',
|
313 |
+
'tab' => 'advanced_options#domain_timezone',
|
314 |
+
|
315 |
+
),
|
316 |
+
$url );
|
317 |
+
$redirect_url = esc_url( $redirect_link );
|
318 |
+
CnbAdminNotices::get_instance()->renderWarning( "<p>Please set your timezone in the <a href=\"" . $redirect_url . "\">Advanced settings</a> tab to avoid unpredictable behavior when using the scheduler.</p>" );
|
319 |
+
|
320 |
+
return false;
|
321 |
+
}
|
322 |
+
}
|
323 |
+
return true;
|
324 |
+
}
|
src/utils/utils.php
CHANGED
@@ -71,10 +71,14 @@ function cnb_update_needed($cnb_options) {
|
|
71 |
function cnb_update_options() {
|
72 |
$cnb_options = get_option('cnb');
|
73 |
$cnb_defaults = cnb_get_defaults();
|
|
|
74 |
// Bugfix for v0.4.5 - a wrong semicolon caused this variable to become a boolean(true) instead of a string
|
75 |
// This fix checks for that exact scenario and forces it back to the default "right" if needed.
|
76 |
// If this variable is set correctly (i.e. is a string), it will retain that value
|
77 |
-
$cnb_options['appearance'] = ($cnb_options['appearance']
|
|
|
|
|
|
|
78 |
if(cnb_update_needed($cnb_options)) { // Check current version and if it needs an update
|
79 |
$cnb_options['active'] = isset($cnb_options['active'])
|
80 |
? $cnb_options['active'] == 1 ? 1 : 0
|
@@ -239,15 +243,24 @@ function zindexToOrder($zindex) {
|
|
239 |
return 1;
|
240 |
}
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
function cnb_actiontype_to_icontext($actionType) {
|
243 |
switch ($actionType) {
|
244 |
case 'ANCHOR': return 'anchor';
|
245 |
-
case 'WHATSAPP': return 'whatsapp';
|
246 |
case 'EMAIL': return 'email';
|
|
|
247 |
case 'LINK': return 'link';
|
248 |
case 'MAP': return 'directions';
|
249 |
-
case '
|
250 |
-
case '
|
|
|
251 |
default:
|
252 |
return 'call';
|
253 |
}
|
71 |
function cnb_update_options() {
|
72 |
$cnb_options = get_option('cnb');
|
73 |
$cnb_defaults = cnb_get_defaults();
|
74 |
+
|
75 |
// Bugfix for v0.4.5 - a wrong semicolon caused this variable to become a boolean(true) instead of a string
|
76 |
// This fix checks for that exact scenario and forces it back to the default "right" if needed.
|
77 |
// If this variable is set correctly (i.e. is a string), it will retain that value
|
78 |
+
$cnb_options['appearance'] = (!isset($cnb_options['appearance']) || $cnb_options['appearance'] === true)
|
79 |
+
? $cnb_defaults['appearance']
|
80 |
+
: $cnb_options['appearance'];
|
81 |
+
|
82 |
if(cnb_update_needed($cnb_options)) { // Check current version and if it needs an update
|
83 |
$cnb_options['active'] = isset($cnb_options['active'])
|
84 |
? $cnb_options['active'] == 1 ? 1 : 0
|
243 |
return 1;
|
244 |
}
|
245 |
|
246 |
+
/**
|
247 |
+
* Get the default glyph for a particular action type.
|
248 |
+
*
|
249 |
+
* This should have the same content as the JS function cnbActiontypeToIcontext
|
250 |
+
* @param $actionType string
|
251 |
+
*
|
252 |
+
* @return string
|
253 |
+
*/
|
254 |
function cnb_actiontype_to_icontext($actionType) {
|
255 |
switch ($actionType) {
|
256 |
case 'ANCHOR': return 'anchor';
|
|
|
257 |
case 'EMAIL': return 'email';
|
258 |
+
case 'HOURS': return 'access_time';
|
259 |
case 'LINK': return 'link';
|
260 |
case 'MAP': return 'directions';
|
261 |
+
case 'PHONE': return 'call';
|
262 |
+
case 'SMS': return 'chat';
|
263 |
+
case 'WHATSAPP': return 'whatsapp';
|
264 |
default:
|
265 |
return 'call';
|
266 |
}
|