Skip to content

Commit 280a307

Browse files
author
Martin Steel
committed
updated base class for WordPress plugins
1 parent fc135ea commit 280a307

1 file changed

Lines changed: 219 additions & 54 deletions

File tree

wordpress/class-clockwork-plugin.php

Lines changed: 219 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ abstract class Clockwork_Plugin {
3535
/**
3636
* Version of the Clockwork Wordpress wrapper
3737
*/
38-
const VERSION = '1.1.0';
38+
const VERSION = '1.2.1';
3939
/**
4040
* URL to signup for a new Clockwork account
4141
*/
@@ -97,6 +97,7 @@ public function __construct() {
9797
add_action( 'admin_notices', array( $this, 'setup_admin_message' ) );
9898
add_action( 'admin_bar_menu', array( $this, 'setup_admin_bar' ), 999 );
9999
add_action( 'admin_init', array( $this, 'setup_admin_init' ) );
100+
add_action( 'admin_enqueue_scripts', array( $this, 'setup_clockwork_js' ) );
100101

101102
$this->plugin_callback = array( $this, 'main' );
102103
}
@@ -161,7 +162,7 @@ public function setup_admin_message() {
161162
// Don't bother showing the "You need to set your Clockwork options" message if it's that form we're viewing
162163
if( !isset( $this->clockwork ) && ( get_current_screen()->base != 'toplevel_page_clockwork_options' ) ) {
163164
$this->show_admin_message('You need to set your <a href="' . site_url() . '/wp-admin/admin.php?page=clockwork_options">Clockwork options</a> before you can use ' . $this->plugin_name . '.');
164-
}
165+
}
165166
}
166167

167168
/**
@@ -175,27 +176,29 @@ public function setup_admin_bar() {
175176
if ( !is_super_admin() || !is_admin_bar_showing() ) {
176177
return;
177178
}
178-
// Display a low credit notification if there's no credit
179-
try {
180-
if( !isset( $this->clockwork ) ) {
181-
$options = get_option( 'clockwork_options' );
182-
183-
$clockwork = new WordPressClockwork( $options['api_key'] );
179+
180+
$options = get_option( 'clockwork_options' );
181+
if( isset( $options['api_key'] ) ) {
182+
// Display a low credit notification if there's no credit
183+
try {
184+
if( !isset( $this->clockwork ) ) {
185+
$clockwork = new WordPressClockwork( $options['api_key'] );
186+
}
187+
$balance = $this->clockwork->checkBalance();
188+
if( $balance['balance'] <= 0 && $balance['account_type'] == 'PAYG' ) {
189+
$balance_string = '£0. Top up now!';
190+
} else {
191+
$balance_string = $balance['symbol'] . $balance['balance'];
192+
}
193+
// Add a node to the Admin bar
194+
$wp_admin_bar->add_node( array(
195+
'id' => 'clockwork_balance',
196+
'title' => 'Clockwork: ' . $balance_string,
197+
'href' => self::BUY_URL )
198+
);
199+
} catch( Exception $e ) {
200+
// Don't kill the entire admin panel because we can't get the balance
184201
}
185-
$balance = $this->clockwork->checkBalance();
186-
if( $balance <= 0 ) {
187-
$balance_string = '£0. Top up now!';
188-
} else {
189-
$balance_string = $balance['symbol'] . $balance['balance'];
190-
}
191-
// Add a node to the Admin bar
192-
$wp_admin_bar->add_node( array(
193-
'id' => 'clockwork_balance',
194-
'title' => 'Clockwork: ' . $balance_string,
195-
'href' => self::BUY_URL )
196-
);
197-
} catch( Exception $e ) {
198-
// Don't kill the entire admin panel because we can't get the balance
199202
}
200203
}
201204

@@ -220,12 +223,23 @@ public function setup_admin_navigation() {
220223
if( !$menu_exists ) {
221224
add_menu_page( __( 'Clockwork SMS', $this->language_string ), __( 'Clockwork SMS', $this->language_string ), 'manage_options', 'clockwork_options', array( $this, 'clockwork_options' ), plugins_url( 'images/logo_16px_16px.png', dirname( __FILE__ ) ) );
222225
add_submenu_page( 'clockwork_options', __( 'Clockwork Options', $this->language_string ), __( 'Clockwork Options', $this->language_string ), 'manage_options', 'clockwork_options', array( $this, 'clockwork_options' ) );
226+
add_submenu_page( NULL, 'Test', 'Test', 'manage_options', 'clockwork_test_message', array( $this, 'clockwork_test_message' ) );
223227
}
224228

225229
// Setup options for this plugin
226230
add_submenu_page( 'clockwork_options', __( $this->plugin_name, $this->language_string ), __( $this->plugin_name, $this->language_string ), 'manage_options', $this->plugin_callback[1], $this->plugin_callback );
227231
}
228232

233+
/**
234+
* Set up javascript for the Clockwork admin functions
235+
*
236+
* @return void
237+
* @author James Inman
238+
*/
239+
public function setup_clockwork_js() {
240+
wp_enqueue_script( 'clockwork_options', plugins_url( 'js/clockwork_options.js', dirname( __FILE__ ) ), array( 'jquery' ) );
241+
}
242+
229243
/**
230244
* Register global Clockwork settings for API keys
231245
*
@@ -238,7 +252,7 @@ public function setup_admin_init() {
238252
add_settings_field( 'clockwork_api_key', 'Your API Key', array( $this, 'settings_api_key_input' ), 'clockwork', 'clockwork_api_keys' );
239253

240254
add_settings_section( 'clockwork_defaults', 'Default Settings', array( $this, 'settings_default_text' ), 'clockwork' );
241-
add_settings_field( 'clockwork_from', "'From' Name/Number ", array( $this, 'settings_from_input' ), 'clockwork', 'clockwork_defaults' );
255+
add_settings_field( 'clockwork_from', "'From' Number ", array( $this, 'settings_from_input' ), 'clockwork', 'clockwork_defaults' );
242256
}
243257

244258
/**
@@ -268,25 +282,33 @@ public function settings_default_text() {
268282
* @author James Inman
269283
*/
270284
public function settings_api_key_input() {
271-
try {
272-
if( !isset( $this->clockwork ) ) {
273-
$options = get_option( 'clockwork_options' );
274-
$this->clockwork = new WordPressClockwork( $options['api_key'] );
275-
}
285+
$options = get_option( 'clockwork_options' );
286+
287+
if( isset( $options['api_key'] ) ) {
288+
try {
289+
if( !isset( $this->clockwork ) ) {
290+
$this->clockwork = new WordPressClockwork( $options['api_key'] );
291+
}
276292

277-
echo "<input id='clockwork_api_key' name='clockwork_options[api_key]' size='40' type='text' value='{$this->clockwork->key}' />";
293+
echo "<input id='clockwork_api_key' name='clockwork_options[api_key]' size='40' type='text' value='{$this->clockwork->key}' />";
278294

279-
// Show balance
280-
$balance = $this->clockwork->checkBalance();
281-
if( $balance ) {
282-
echo '<p><strong>Balance:</strong> ' . $balance['symbol'] . $balance['balance'] . '&nbsp;&nbsp;&nbsp;<a href="' . self::BUY_URL . '" class="button">Buy More</a></p>';
283-
} else { // We can't get the credits for some reason
284-
echo '<p><a href="' . self::BUY_URL . '" class="button">Buy More Credit</a></p>';
285-
}
295+
// Show balance
296+
$balance = $this->clockwork->checkBalance();
297+
if( $balance ) {
298+
echo '<p><strong>Balance:</strong> ' . $balance['symbol'] . $balance['balance'] . '&nbsp;&nbsp;&nbsp;<a href="' . self::BUY_URL . '" class="button">Buy More</a></p>';
299+
} else { // We can't get the credits for some reason
300+
echo '<p><a href="' . self::BUY_URL . '" class="button">Buy More Credit</a></p>';
301+
}
286302

287-
} catch( ClockworkException $e ) {
303+
} catch( ClockworkException $e ) {
304+
echo "<input id='clockwork_api_key' name='clockwork_options[api_key]' size='40' type='text' value='' />";
305+
echo '<p><a href="' . self::SIGNUP_URL . '" class="button">Get An API Key</a></p>';
306+
}
307+
308+
return;
309+
} else {
288310
echo "<input id='clockwork_api_key' name='clockwork_options[api_key]' size='40' type='text' value='' />";
289-
echo '<p><a href="' . self::SIGNUP_URL . '" class="button">Get An API Key</a></p>';
311+
echo '<p><a href="' . self::SIGNUP_URL . '" class="button">Get An API Key</a></p>';
290312
}
291313
}
292314

@@ -299,12 +321,12 @@ public function settings_api_key_input() {
299321
public function settings_from_input() {
300322
$options = get_option( 'clockwork_options' );
301323
if( isset( $options['from'] ) ) {
302-
echo "<input id='clockwork_from' name='clockwork_options[from]' size='40' type='text' value='{$options['from']}' />";
324+
echo "<input id='clockwork_from' name='clockwork_options[from]' size='40' maxlength='14' type='text' value='{$options['from']}' />";
303325
} else {
304-
echo "<input id='clockwork_from' name='clockwork_options[from]' size='40' type='text' value='' />";
326+
echo "<input id='clockwork_from' name='clockwork_options[from]' size='40' maxlength='14' type='text' value='' />";
305327
}
306328

307-
echo "<p>You can use an alphabetic string, e.g. the name of your store, which must be 11 characters or less. These are not supported by all international networks. You can also enter any normal mobile phone number, which will allow people to reply to your text messages.</p>";
329+
echo "<p>Enter the number your messages will be sent from. We recommend your mobile phone number.<br />UK customers can use alphanumeric strings up to 11 characters.</p>";
308330
}
309331

310332
/**
@@ -314,25 +336,41 @@ public function settings_from_input() {
314336
* @author James Inman
315337
*/
316338
public function clockwork_options_validate( $val ) {
317-
try {
318-
$key = trim( $val['api_key'] );
339+
// From santization
340+
$val['from'] = preg_replace( '/[^A-Za-z0-9]/', '', $val['from'] );
341+
if( preg_match( '/[0-9]/', $val['from'] ) ) {
342+
$val['from'] = substr( $val['from'], 0, 14 );
343+
} else {
344+
$val['from'] = substr( $val['from'], 0, 11 );
345+
}
346+
$val['api_key']= trim($val['api_key']);
347+
// API key checking
348+
try {
349+
$key = $val['api_key'];
319350
if( $key ) {
351+
320352
$clockwork = new WordPressClockwork( $key );
321-
$clockwork->checkKey();
322-
$this->clockwork = $clockwork;
323-
add_settings_error( 'clockwork_options', 'clockwork_options', 'Your settings were saved! You can now start using Clockwork SMS.', 'updated' );
353+
if( $clockwork->checkKey() ) {
354+
355+
$this->clockwork = $clockwork;
356+
add_settings_error( 'clockwork_options', 'clockwork_options', 'Your settings were saved! You can now start using Clockwork SMS.', 'updated' );
357+
return $val;
358+
359+
} else {
360+
add_settings_error( 'clockwork_options', 'clockwork_options', 'Your API key was incorrect. Please enter it again.', 'error' );
361+
return false;
362+
}
363+
324364
} else {
325-
$key = '';
365+
// Key is blank, but a blank update (they might have added 'from') is okay
366+
$key = '';
367+
add_settings_error( 'clockwork_options', 'clockwork_options', 'Your settings were saved! You can now start using Clockwork SMS.', 'updated' );
368+
return $val;
326369
}
370+
327371
} catch( ClockworkException $ex ) {
328372
add_settings_error( 'clockwork_options', 'clockwork_options', 'Your API key was incorrect. Please enter it again.', 'error' );
329-
}
330-
331-
$val['from'] = preg_replace( '/[^A-Za-z0-9]/', '', $val['from'] );
332-
if( preg_match( '/[0-9]/', $val['from'] ) ) {
333-
$val['from'] = substr( $val['from'], 0, 14 );
334-
} else {
335-
$val['from'] = substr( $val['from'], 0, 11 );
373+
return false;
336374
}
337375

338376
return $val;
@@ -348,6 +386,133 @@ public function clockwork_options() {
348386
$this->render_template( 'clockwork-options' );
349387
}
350388

389+
/**
390+
* Send a test SMS message
391+
*
392+
* @param string $to Mobile number to send to
393+
* @return void
394+
* @author James Inman
395+
*/
396+
public function clockwork_test_message( $to ) {
397+
$log = array();
398+
399+
global $wp_version;
400+
$log[] = "Using Wordpress " . $wp_version;
401+
$log[] = "Clockwork PHP wrapper initalised: using " . Clockwork::VERSION;
402+
$log[] = "Plugin wrapper initialised: using " . get_class($this) . ' ' . self::VERSION;
403+
$log[] = '';
404+
405+
$options = get_option( 'clockwork_options' );
406+
407+
// Check API key for sanity
408+
if( isset( $options['api_key'] ) && strlen( $options['api_key'] ) == 40 ) {
409+
$log[] = "API key is set and appears valid – " . $options['api_key'];
410+
} else {
411+
$log[] = "API key is not set, or is the incorrect length.";
412+
$log[] = "No credit has been used for this test";
413+
$this->output_test_message_log( $log );
414+
return;
415+
}
416+
417+
// Check originator for sanity
418+
if( isset( $options['from'] ) && strlen( $options['from'] ) <= 14 ) {
419+
$log[] = "Originator is set to " . $options['from'] . " and is below 14 characters";
420+
421+
// Then remove special characters
422+
$from = $options['from'];
423+
$replaced_from = preg_replace( '/[^a-zA-Z0-9]/', '', $from );
424+
425+
if( $from == $replaced_from ) {
426+
$log[] = 'Replaced special characters in originator, no changes';
427+
} else {
428+
$log[] = 'Removed special characters from originator: ' . $replaced_from;
429+
}
430+
431+
// Is it alphanumeric?
432+
if( preg_match( '/[a-zA-Z]/', $replaced_from ) == 1 ) {
433+
// Is it under 11 characters?
434+
if( strlen( $replaced_from ) <= 11 ) {
435+
$log[] = 'Alphanumeric originator is less than 11 characters – note that some countries reject alpha originators';
436+
} else {
437+
$log[] = 'You are trying to send with an alphanumeric originator over 11 characters in length';
438+
$log[] = "No credit has been used for this test";
439+
$this->output_test_message_log( $log );
440+
return;
441+
}
442+
} else {
443+
$log[] = 'Originator is set as numeric';
444+
}
445+
446+
} else {
447+
$log[] = "Originator is not set, using your Clockwork account default (probably 84433)";
448+
}
449+
450+
// Check if API key is valid
451+
$log[] = '';
452+
453+
$clockwork = new WordPressClockwork( $options['api_key'] );
454+
if( $clockwork->checkKey() ) {
455+
$log[] = 'API key exists according to clockworksms.com';
456+
}
457+
458+
// Check what the balance is
459+
$balance_resp = $clockwork->checkBalance();
460+
461+
if( $balance_resp['balance'] > 0 ) {
462+
$log[] = 'Balance is ' . $balance_resp['symbol'] . $balance_resp['balance'];
463+
}
464+
elseif($balance_resp['account_type']== 'Invoice'){
465+
$log[] = 'You have a credit account. No need to check the balance.';
466+
}
467+
else {
468+
$log[] = 'Balance is 0. You need to add more credit to your Clockwork account';
469+
$log[] = "No credit has been used for this test";
470+
$this->output_test_message_log( $log );
471+
return;
472+
}
473+
474+
// Can we authenticate?
475+
$log[] = '';
476+
477+
$message = 'This is a test message from Clockwork';
478+
479+
if( !$clockwork->is_valid_msisdn( $_GET['to'] ) ) {
480+
$log[] = $_GET['to'] . ' appears an invalid number to send to, this message may not send';
481+
}
482+
483+
$log[] = 'Attempting test send with API key ' . $options['api_key'] . ' to ' . $_GET['to'];
484+
485+
try {
486+
$message_data = array( array( 'from' => $options['from'], 'to' => $_GET['to'], 'message' => $message ) );
487+
$result = $clockwork->send( $message_data );
488+
489+
$log[] = '';
490+
491+
if( isset( $result[0]['id'] ) && isset( $result[0]['success'] ) && ( $result[0]['success'] == '1' ) ) {
492+
$log[] = 'Message successfully sent with ID ' . $result[0]['id'];
493+
494+
$log[] = '';
495+
$log[] = 'Used 5p of your Clockwork credit for this test';
496+
497+
$balance_resp = $clockwork->checkBalance();
498+
$log[] = 'Your new balance is ' . $balance_resp['symbol'] . $balance_resp['balance'];
499+
} else {
500+
$log[] = 'There was an error sending the message: error code ' . $result[0]['error_code'] . '' . $result[0]['error_message'];
501+
$log[] = "No credit has been used for this test";
502+
}
503+
} catch( ClockworkException $e ) {
504+
$log[] = "Error: " . $e->getMessage();
505+
} catch( Exception $e ) {
506+
$log[] = "Error: " . $e->getMessage();
507+
}
508+
509+
$this->output_test_message_log( $log );
510+
}
511+
512+
protected function output_test_message_log( $log ) {
513+
$this->render_template( 'clockwork-test-message', array( 'log' => implode( "\r\n", $log ) ) );
514+
}
515+
351516
/**
352517
* Show a message at the top of the administration panel
353518
*

0 commit comments

Comments
 (0)