Permalink
Browse files

adding email_manager and activity_log plugins to SOS; making those ge…

…neric; adding handler for IPNs to POST to /handle_ipn
  • Loading branch information...
1 parent 970f72b commit 8a0560c8bbcc516b9ec63936f89ce4b33cb5b6b7 @jayfresh committed Mar 17, 2013
Showing with 355 additions and 1 deletion.
  1. +1 −0 themes/sos/_inc/activity-log.php
  2. +246 −0 themes/sos/_inc/email-manager.php
  3. +108 −1 themes/sos/functions.php
View
1 themes/sos/_inc/activity-log.php
@@ -0,0 +1 @@
+<?php
View
246 themes/sos/_inc/email-manager.php
@@ -0,0 +1,246 @@
+<?php
+
+ /* function for sending templated emails, with text of email making use of shortcodes */
+ function email_manager( $event_type, $post_id, $extraVars ) {
+
+ global $email_types;
+ if( !$event_type || !isset( $email_types[$event_type] ) ) return false;
+
+ $email_template = new WP_Query( array(
+ 'post_type' => 'emails',
+ 'meta_key' => '_email_event_type',
+ 'meta_value' => $event_type
+ ));
+
+ $extraVars['post_id'] = $post_id;
+
+ if ( $email_template->posts ) {
+ $post = $email_template->posts[0];
+
+ $meta = get_post_custom( $post->ID );
+
+ // Transitional version
+ if( $meta['_email_template'] ) {
+ $url = get_permalink($post->ID) .'?'. http_build_query($extraVars);
+
+ // create curl resource
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $body = curl_exec($ch);
+ curl_close($ch);
+
+ add_filter( 'wp_mail_content_type', 'set_html_email' );
+ } else {
+ $body = email_shortcodes( $meta['_email_text'][0], $extraVars );
+ }
+
+ $subject = email_shortcodes( $meta['_email_subject'][0], $extraVars );
+
+ // If this template has a 'FROM' email address use that, else use the admin email address
+ $fromAddress = $meta['_email_from'][0] != '' ? $meta['_email_from'][0] : get_option( 'admin_email');
+ $toAddresses = '';
+ $toFunc = $event_type."_to";
+ if( function_exists($toFunc) ) {
+ $toAddresses = $toFunc($extraVars);
+ }
+ // This allows to-addresses to be added to the email manager arguments directly
+ $toAddresses = array_merge( (array) $extraVars['to_addresses'], (array) $toAddresses );
+
+ $headers = '';
+ if( $fromAddress ) {
+ $headers .= "Reply-To: $fromAddress\r\n";
+ $headers .= "From: Seen On Screen Fitness <$fromAddress>\r\n"; // TO-DO: make the "Seen On Screen Fitness" set from an admin panel
+ }
+
+ send_email_and_log( $post_id, $toAddresses, $subject, $body, $headers );
+ }
+ return (bool)$email_template->posts;
+ }
+
+ /* support custom location for email templates, used when requesting email with HTML template */
+ function filter_email_template( $template ) {
+ global $wp_query;
+
+ if( $wp_query->post->post_type == 'emails' ) {
+ if( $filename = get_post_meta( $wp_query->post->ID, '_email_template', true ) ) {
+
+ if ( file_exists( get_stylesheet_directory() . '/' . $filename ) ) {
+ $template = get_stylesheet_directory() . '/' . $filename;
+ }
+ }
+ }
+
+ return $template;
+ }
+ add_filter( 'single_template', 'filter_email_template' );
+
+ function set_html_email( $content_type ) {
+ return 'text/html';
+ }
+
+ /* create post type: Emails */
+
+ if ( ! function_exists( 'post_type_emails' ) ) :
+ function post_type_emails() {
+ register_post_type(
+ 'emails',
+ array(
+ 'label' => __('Emails'),
+ 'description' => __('Edit an Email.'),
+ 'public' => true,
+ 'show_ui' => true,
+ 'register_meta_box_cb' => 'init_email_metaboxes',
+ 'supports' => array (
+ 'editor', // added to support text editor for email body content
+ 'title',
+ 'revisions'
+ )
+ )
+ );
+ }
+ endif;
+
+ add_action('init', 'post_type_emails');
+
+ /* add metaboxes to email post type */
+
+ function init_email_metaboxes() {
+ add_meta_box('email_metaboxes', 'Email Content', 'email_metaboxes', 'emails', 'normal', 'default');
+ }
+
+ function email_metaboxes() {
+ global $post;
+
+ // Noncename needed to verify where the data originated
+ echo '<input type="hidden" name="emailmeta_noncename" id="emailmeta_noncename" value="' .
+ wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
+
+ // Get the location data if its already been entered
+ $email_subject = get_post_meta($post->ID, '_email_subject', true);
+ $email_text = get_post_meta($post->ID, '_email_text', true);
+ $email_from = get_post_meta($post->ID, '_email_from', true);
+ $email_template = get_post_meta($post->ID, '_email_template', true);
+
+ // Echo out the fields
+ ?>
+
+ <div style="overflow:hidden; margin-top:10px;">
+ <div style="width:100px; float:left; padding-top:7px;"><label for="_email_subject"><strong>Email Subject</strong></label></div>
+ <div style="width:500px; float:left;"><input style="width: 80%%;" type="text" name="_email_subject" value="<?php echo $email_subject; ?>" />
+ <p style="clear:both"><em>Subject line for the email</em></p></div>
+ </div>
+
+ <div style="overflow:hidden; margin-top:10px; ">
+ <div style="width:100px; float:left; padding-top:7px;"><label for="_email_text"><strong>Email text</strong></label></div>
+ <div style="width:500px; float:left;"><textarea style="width: 90%%; height:200px;" name="_email_text"><?php echo $email_text; ?></textarea>
+ <p style="clear:both"><em>Body of the email</em></p></div>
+ </div>
+
+ <div style="overflow:hidden; margin-top:10px;">
+ <div style="width:100px; float:left; padding-top:7px;"><label for="_email_from"><strong>Email From Address</strong></label></div>
+ <div style="width:500px; float:left;"><input style="width: 80%%;" type="text" name="_email_from" value="<?php echo $email_from; ?>" />
+ <p style="clear:both"><em>Enter the address this email is from</em></p></div>
+ </div>
+
+ <div style="overflow:hidden; margin-top:10px; ">
+ <div style="width:100px; float:left;"><label for="_email_template"><strong>Email Template</strong></label></div>
+ <div style="width:500px; float:left;">
+ <select name="_email_template" id="_email_template">
+ <?php
+ $templates = array_merge( array( '' => 'No Template' ), array_flip( get_page_templates() ) );
+ foreach($templates as $value => $label){
+
+ // if this value is the currently selected template we'll mark it selected
+ $selected = ($email_template == $value) ? ' selected="selected"' : '';
+
+ // escape value for quotes so they won't break the html
+ $value = addslashes($value);
+
+ echo '<option value="'.$value.'"'.$selected.'>'.$label.'</option>';
+ }
+ ?>
+ </select>
+ <p><em>Select an HTML template to render the email</em></p>
+ </div>
+ </div>
+
+ <?php
+ }
+
+ function email_save_meta($post_id, $post) {
+
+ // verify this came from the our screen and with proper authorization,
+ // because save_post can be triggered at other times
+ if ( !wp_verify_nonce( $_POST['emailmeta_noncename'], plugin_basename(__FILE__) )) {
+ return $post->ID;
+ }
+
+ // Is the user allowed to edit the post or page?
+ if ( !current_user_can( 'edit_post', $post->ID ))
+ return $post->ID;
+
+ // OK, we're authenticated: we need to find and save the data
+ // We'll put it into an array to make it easier to loop though.
+
+ $email_meta['_email_subject'] = $_POST['_email_subject'];
+ $email_meta['_email_text'] = $_POST['_email_text'];
+ $email_meta['_email_from'] = $_POST['_email_from'];
+ $email_meta['email_template'] = $_POST['_email_template'];
+
+ // Add values of $email_meta as custom fields
+
+ foreach ($email_meta as $key => $value) { // Cycle through the $events_meta array!
+ if( $post->post_type == 'revision' ) return; // Don't store custom data twice
+ $value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
+ if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
+ update_post_meta($post->ID, $key, $value);
+ } else { // If the custom field doesn't have a value
+ add_post_meta($post->ID, $key, $value);
+ }
+ if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
+ }
+
+ }
+
+ add_action('save_post', 'email_save_meta', 1, 2);
+
+ function email_shortcodes( $body, $extraVars ) {
+
+ // replace all the shortcodes that match variables passed in extraVars
+ foreach($extraVars as $key => $value) {
+ $shortcode = $key; // TO-DO: make $key uppercase
+ $body = str_ireplace( '%'.$key.'%', $value, $body );
+ }
+
+ $message = sprintf(__('%s'), $body) . "\r\n";
+ return $message;
+ }
+
+ function send_email_and_log($post_id, $to_address, $subject, $body, $headers='', $no_reply=FALSE) {
+
+ if($headers=='') {
+ if($no_reply) {
+ $headers .= "Reply-To: no-reply@seenonscreenfitness.com\r\n"; // TO-DO: put these emails in a setting
+ $headers .= "From: Seen On Screen (No-reply) <no-reply@seenonscreenfitness.com>\r\n";
+ } else {
+ $replyTo = get_option('admin_email');
+ $headers .= "Reply-To: $replyTo\r\n";
+ $headers .= "From: Seen On Screen Fitness <$replyTo>\r\n"; // TO-DO: put the name in a setting (perhaps the setting could be the entirety e.g. "Seen On Screen Fitness <email@seenonscreenfitness.com>"
+ }
+ }
+ $log_string = $to_address."~~".$headers."~~".$body;
+
+ do_action('activity_log', array(
+ 'type' => 'email',
+ 'entry'=> array(
+ 'to'=>$to_address,
+ 'subject'=>$subject,
+ 'body'=>$body,
+ 'headers'=>$headers
+ )
+ ), $post_id);
+ if(!TEST_MODE) {
+ wp_mail($to_address, $subject, $body, $headers);
+ }
+ }
View
109 themes/sos/functions.php
@@ -1,5 +1,8 @@
<?php
+require_once( '_inc/activity-log.php' );
+require_once( '_inc/email-manager.php' );
+
// support featured images etc.
add_theme_support( 'post-thumbnails' );
@@ -10,7 +13,7 @@
add_image_size( 'blog', 700, 370, true );
add_image_size( 'blog-sub', 430, 300, true );
-// Register the 'Team' custom post type
+// Register the custom post types
add_action( 'init', 'sos_register_custom_post_types');
function sos_register_custom_post_types() {
register_post_type( 'sos_team',
@@ -64,6 +67,8 @@ function sos_register_custom_post_types() {
);
}
+/* add metaboxes to studio post type */
+
function sos_add_studio_metabox() {
add_meta_box('studio_metabox', 'Studio details', 'studio_metabox', 'sos_studio', 'normal', 'default');
}
@@ -117,6 +122,8 @@ function sos_studio_save_meta($post_id, $post) {
add_action('save_post', 'sos_studio_save_meta', 1, 2);
+/* add meta boxes to team post type */
+
function sos_add_team_credits_metabox() {
add_meta_box('team_credits_box', 'Team member credits', 'team_credits_box', 'sos_team', 'normal', 'default');
}
@@ -248,6 +255,106 @@ function attachment_toolbox($size = 'thumbnail', $ulClass = '', $liClass = '') {
return count($images);
}
+/* handle PayPal IPNs */
+
+/*
+ * Query vars allow us to use rewrites without upsetting WordPress
+ * see the rewrite rules and template redirect for their actual use
+ */
+function sos_add_query_vars( $qvars ) {
+ $qvars[] = 'handle-ipn';
+ return $qvars;
+}
+add_action('query_vars', 'sos_add_query_vars');
+
+/* Generally triggered on a "save permalinks", this adds new rules at the top of the pile */
+function sos_add_rewrite_rules( $wp_rewrite ) {
+ $newrules = array();
+
+ $new_rules['^analytics'] = 'index.php?analytics=true';
+ $new_rules['^supermum'] = 'index.php?supermum=true';
+ $new_rules['^account-details'] = 'index.php?account-details=true';
+
+ $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
+}
+add_action('generate_rewrite_rules', 'sos_add_rewrite_rules');
+
+/* Allows us to point WordPress in a different direction if desired. */
+function sos_template_redirect() {
+ if( get_query_var('handle-ipn') ) {
+ handle_ipn($_POST);
+ exit();
+ }
+}
+add_action('template_redirect','sos_template_redirect');
+
+/*
+ Variables we need to pull from the IPN:
+
+ - product name e.g. "End of Time Workshop"
+ - sent as item_name
+ - series name e.g. "Beyonce Dance Series" or "Jazz Funk"
+ - could be sent in "custom"
+ - date e.g. "Saturday 16th March"
+ - perhaps this needs to be part of the item_name
+ - time e.g. 1:30-3pm
+ - perhaps this needs to be part of the item_name
+
+ Variables we want to calculate:
+
+ - studio address e.g.
+ Central YMCA
+ 112 Great Russell Street
+ London
+ WC1B 3NQ
+ - this can come from knowing the series name and looking up the studio attached to that page
+ - nearest tube e.g. "Tottenham Court Road"
+ - as above
+ - link to studio e.g. "http://seenonscreenfitness.com/studios/central-ymca"
+ - as above
+
+*/
+
+function handle_ipn($vars) {
+ $IPN_all = implode($vars,"~~");
+ $IPN_payment_status = $vars['payment_status']; // Completed/Refunded
+ $IPN_item_name = $vars['item_name']; // e.g. "End of Time workshop"
+ $IPN_txn_id = $vars['txn_id']; // Reference/"cash"
+ $IPN_item_number = $vars['item_number']; // TBC
+ $IPN_custom = $vars['custom']; // TBC
+ $IPN_payer_email = $vars['payer_email']; // email of the payer
+ if($IPN_payment_status and $IPN_item_name and $IPN_txn_id and $IPN_payer_email) {
+ $meta = array(
+ 'ipn_txn_id' => $IPN_txn_id,
+ 'ipn_payer_email' => $IPN_payer_email,
+ 'ipn_all' => $IPN_all,
+ 'ipn_datetime' => time()
+ );
+ $extraVars = array(
+ 'user_email' => $IPN_payer_email,
+ 'address' => $IPN_address,
+ );
+ $post_id = 0; // TO-DO: where is this going to come from? Do we need it?
+ if($IPN_payment_status=="Completed") {
+ email_manager('', $post_id, $extraVars); // TO-DO: which first and second arguments to use?
+ echo "Payment acknowledged";
+ } else if ($payment_status=="Refunded") {
+ email_manager('', $post_id, $extraVars); // TO-DO: which first and second arguments to use?
+ echo "Refund processed";
+ }
+ do_action('activity_log', array(
+ 'type' => 'IPN',
+ 'entry'=> $vars
+ ), $post_id); // TO-DO: which post_id to use?
+ } else {
+ do_action('activity_log', array(
+ 'type' => 'invalid_IPN',
+ 'entry'=> $vars
+ ), 0);
+ echo "error: send at least 'payment_status', 'item_name', 'txn_id' and 'payer_email'";
+ }
+}
+
// add scripts
function sos_load_scripts() {
$stylesheet_directory = get_stylesheet_directory_uri();

0 comments on commit 8a0560c

Please sign in to comment.