From e3375f0159e4f625629f75c0f14396a21fca5cb9 Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Sun, 3 Mar 2019 22:00:56 +0100 Subject: [PATCH 1/4] add form to be able to configure which memberships a user can edit themselves --- fulcrm_membership.admin.inc | 52 +++++++++++++++++++++++++++++++++++++ fulcrm_membership.module | 16 ++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 fulcrm_membership.admin.inc diff --git a/fulcrm_membership.admin.inc b/fulcrm_membership.admin.inc new file mode 100644 index 0000000..6a6b134 --- /dev/null +++ b/fulcrm_membership.admin.inc @@ -0,0 +1,52 @@ + 'item', + '#title' => 'fulcrm Membership Integration Settings', + '#description' => '', + ); + + $products = array( '' => '-- disabled --' ); + + $membership_data = fulcrm_apiv2_GET( 'membership/', + $query = array( 'page_size' => 1000, + ) ); + if ( $membership_data[ 'success' ] ) { + if ( $membership_data[ 'data' ][ 'results' ] ) { + foreach ( $membership_data[ 'data' ][ 'results' ] as $membership ) { + $memberships[ $membership[ 'id' ] ] = $membership[ 'name' ]; + if ( $membership[ 'archived' ] ) + $memberships[ $membership[ 'id' ] ] .= ' (archived)'; + } + } + } else { + $memberships[ 'ERROR' ] = '** ERROR fetching memberships from fulcrm **'; + } + + $form[ 'self_set_membership_ids' ] = array( '#type' => 'checkboxes', + '#title' => 'Self-Set Memberships', + '#options' => $memberships, + '#default_value' => variable_get( 'fulcrm_membership_self_set_membership_ids', array() ), + '#description' => 'Which memberships can users add/remove for themselves?', + ); + + $form[ 'actions' ] = array( '#type' => 'actions' ); + $form[ 'actions' ][ 'save' ] = array( '#type' => 'submit', + '#value' => t('Save'), + '#submit' => array( 'fulcrm_membership_admin_form_submit' ), + ); + + return $form; +} + +function fulcrm_membership_admin() { + return drupal_get_form( 'fulcrm_membership_admin_form' ); +} diff --git a/fulcrm_membership.module b/fulcrm_membership.module index 423a549..b9c2ad8 100644 --- a/fulcrm_membership.module +++ b/fulcrm_membership.module @@ -1,7 +1,23 @@ array( 'title' => t('Administer fulcrm membership'), + 'description' => t('Perform main installation/administration tasks for fulcrm membership integration.'), + ), + ); +} + function fulcrm_membership_menu() { $items = array(); + + $items[ 'admin/config/services/fulcrm/membership' ] = array( 'page callback' => 'fulcrm_membership_admin', + 'file' => 'fulcrm_membership.admin.inc', + 'title' => 'fulcrm Membership', + 'description' => 'Configure Membership integration with fulcrm.org.', + 'access callback' => 'user_access', + 'access arguments' => array('administer fulcrm membership'), + ); + $items[ 'user/fulcrm/optin/%' ] = array( 'page callback' => 'fulcrm_membership_optin', 'page arguments' => array(3), 'title' => 'Subscription Opt-In', From f47111a85e5263269a274a04bb783d53138eacf6 Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Sun, 3 Mar 2019 23:50:47 +0100 Subject: [PATCH 2/4] add page for users to edit their memberships --- fulcrm_membership.module | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/fulcrm_membership.module b/fulcrm_membership.module index b9c2ad8..e6c1628 100644 --- a/fulcrm_membership.module +++ b/fulcrm_membership.module @@ -25,9 +25,42 @@ function fulcrm_membership_menu() { 'access callback' => 'user_access', 'access arguments' => array('access content'), ); + $items[ 'user/fulcrm/membership' ] = array( 'page callback' => 'fulcrm_membership_self_set', + 'title' => 'Choose Your Settings', + 'description' => 'Opt-In Membership Settings.', + 'access callback' => 'user_access', + 'access arguments' => array('access content'), + ); return $items; } +function fulcrm_membership_person2membership_is_current( $p2m ) { + if ( $p2m[ 'timescale' ] ) { + $tz = new DateTimeZone('UTC'); + $now = new DateTime(); + + $ts_start = $p2m[ 'timescale' ][ 'start' ]; + if ( $ts_start ) { + $start = DateTime::createFromFormat( 'Y-m-d\TH:i:s.u\Z', $ts_start, $timezone = $tz ); + $start = $start ? $start : DateTime::createFromFormat( 'Y-m-d\TH:i:s\Z', $ts_start, $timezone = $tz ); + } else { + $start = NULL; + } + + $ts_finish = $p2m[ 'timescale' ][ 'finish' ]; + if ( $ts_finish ) { + $finish = DateTime::createFromFormat( 'Y-m-d\TH:i:s.u\Z', $ts_finish, $timezone = $tz ); + $finish = $finish ? $finish : DateTime::createFromFormat( 'Y-m-d\TH:i:s\Z', $ts_finish, $timezone = $tz ); + } else { + $finish = NULL; + } + + return ( ( is_null( $start ) || ( $start <= $now ) ) && ( is_null( $finish ) || ( $finish > $now ) ) ); + } else { + return true; + } +} + function fulcrm_membership_optin_form_submit( $form, &$form_state ) { foreach ( $form_state[ 'values' ][ 'person2memberships' ] as $p2m_id ) { $p2m_id = fulcrm_crypto_get_object_id_form_value( 'person2membership-optin', $p2m_id ); @@ -98,3 +131,83 @@ function fulcrm_membership_optin( $passport ) { return drupal_get_form( 'fulcrm_membership_optin_form', $api_data[ 'data' ][ 'results' ] ); } } + +function fulcrm_membership_self_set_form_submit( $form, &$form_state ) { + +} + +function fulcrm_membership_self_set_form( $form, &$form_state ) { + global $user; + + $form[ 'title' ] = array( '#type' => 'item', + '#title' => 'Subscription Preferences', + '#description' => '', + ); + + $person_id = fulcrm_webhook_get_pk_for_entity_type( 'user', $user->uid, 'person' ); + if ( $person_id ) { + $person_data = fulcrm_apiv2_GET( 'person/' . $person_id . '/', + $query = array( 'expand' => implode( ',', array( 'person2memberships', + 'person2memberships.membership', + 'person2memberships.timescale' ) ) ) ); + + if ( $person_data[ 'success' ] ) { + $membership_data = fulcrm_apiv2_GET( 'membership/', + $query = array( 'page_size' => 1000, + ) ); + + if ( $membership_data[ 'success' ] ) { + $membership_name = array(); + foreach ( $membership_data[ 'data' ][ 'results' ] as $membership ) + $membership_name[ $membership[ 'id' ] ] = $membership[ 'name' ]; + + $possible_ids = variable_get( 'fulcrm_membership_self_set_membership_ids', array() ); + $membership_map = array(); + $options = array(); + + foreach ( $possible_ids as $membership_id => $is_possible ) { + if ( $is_possible ) { + $membership_map[ $membership_id ] = 0; + if ( array_key_exists( $membership_id, $membership_name ) ) + $options[ $membership_id ] = $membership_name[ $membership_id ]; + } + } + + foreach ( $person_data[ 'data' ][ 'person2memberships' ] as $p2m ) { + $membership_id = $p2m[ 'membership' ][ 'id' ]; + if ( array_key_exists( $membership_id, $possible_ids ) && $possible_ids[ $membership_id ] ) { + if ( fulcrm_membership_person2membership_is_current( $p2m ) ) { + $membership_map[ $membership_id ] = $membership_id; + } + } + } + + $form[ 'memberships' ] = array( '#type' => 'checkboxes', + '#title' => 'Subscriptions', + '#options' => $options, + '#default_value' => $membership_map, + ); + } else { + drupal_set_message( t('There was a problem fetching membership information.'), 'error', FALSE ); + } + } else { + drupal_set_message( t('There was a problem fetching your subscription information.'), 'error', FALSE ); + } + } + + $form[ 'actions' ] = array( '#type' => 'actions' ); + $form[ 'actions' ][ 'save' ] = array( '#type' => 'submit', + '#value' => t('Save'), + '#submit' => array( 'fulcrm_membership_self_set_form_submit' ), + ); + + return $form; +} + +function fulcrm_membership_self_set() { + //if ( user_is_logged_in() ) { + return drupal_get_form( 'fulcrm_membership_self_set_form' ); + //} else { + //drupal_goto( 'user?destination=user/fulcrm/membership' ); + //} +} From 29e742394bf404c9cf0a2c59bb361c27b0029cd1 Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Mon, 4 Mar 2019 00:29:27 +0100 Subject: [PATCH 3/4] can now begin a membership; but cease needs a fix --- fulcrm_membership.module | 127 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/fulcrm_membership.module b/fulcrm_membership.module index e6c1628..9d55dc4 100644 --- a/fulcrm_membership.module +++ b/fulcrm_membership.module @@ -132,8 +132,129 @@ function fulcrm_membership_optin( $passport ) { } } +function fulcrm_membership_cease_person2membership( $p2m, $now = NULL ) { + if ( is_null( $now ) ) + $now = new DateTime(); + $tz = new DateTimeZone('UTC'); + $now->setTimeZone( $tz ); + $finish = $now->format( 'Y-m-d\TH:i:s.u\Z' ); + + if ( $p2m[ 'timescale' ] ) { + $api_data = fulcrm_apiv2_PATCH( $p2m[ 'url' ], $data = array( 'finish' => $finish ) ); + if ( $api_data[ 'success' ] ) { + return true; + } else { + watchdog('fulcrm_membership', 'could not patch person2membership %id cease', array('%id'=>$p2m['id']), WATCHDOG_ERROR); + } + } else { + $timescale_data = fulcrm_apiv2_POST( 'timescale/', $data = array( 'finish' => $finish ) ); + if ( $timescale_data[ 'success' ] ) { + $api_data = fulcrm_apiv2_PATCH( $p2m[ 'url' ], $data = array( 'timescale' => $timescale_data[ 'data' ][ 'url' ] ) ); + if ( $api_data[ 'success' ] ) { + return true; + } else { + watchdog('fulcrm_membership', 'could not patch person2membership %id to add timescale %tid', array('%id'=>$p2m['id'],'%tid'=>$timescale_data['data']['id']), WATCHDOG_ERROR); + } + } else { + watchdog('fulcrm_membership', 'could not create timescale to cease membership %id', array('%id'=>$p2m['id']), WATCHDOG_ERROR); + } + } + return false; +} + +function fulcrm_membership_begin_person2membership( $person_id, $membership_id, $now = NULL ) { + if ( is_null( $now ) ) + $now = new DateTime(); + $tz = new DateTimeZone('UTC'); + $now->setTimeZone( $tz ); + $start = $now->format( 'Y-m-d\TH:i:s.u\Z' ); + + $timescale_data = fulcrm_apiv2_POST( 'timescale/', $data = array( 'start' => $start ) ); + if ( $timescale_data[ 'success' ] ) { + $api_data = fulcrm_apiv2_POST( 'person2membership/', $data = array( 'person' => '/api/v2/person/' . $person_id . '/', + 'membership' => '/api/v2/membership/' . $membership_id . '/', + 'timescale' => $timescale_data[ 'data' ][ 'url' ], + ) ); + if ( $api_data[ 'success' ] ) { + return true; + } else { + watchdog('fulcrm_membership', 'could not post person2membership to create membership %mid for %pid', array('%mid'=>$membership_id,'%pid'=>$person_id), WATCHDOG_ERROR); + } + } else { + watchdog('fulcrm_membership', 'could not post timescale to create membership %mid for %pid', array('%mid'=>$membership_id,'%pid'=>$person_id), WATCHDOG_ERROR); + } + +} + function fulcrm_membership_self_set_form_submit( $form, &$form_state ) { + global $user; + $person_id = fulcrm_webhook_get_pk_for_entity_type( 'user', $user->uid, 'person' ); + if ( $person_id ) { + $person_data = fulcrm_apiv2_GET( 'person/' . $person_id . '/', + $query = array( 'expand' => implode( ',', array( 'person2memberships', + 'person2memberships.membership', + 'person2memberships.timescale' ) ) ) ); + if ( $person_data[ 'success' ] ) { + $membership_data = fulcrm_apiv2_GET( 'membership/', + $query = array( 'page_size' => 1000, + ) ); + if ( $membership_data[ 'success' ] ) { + $membership_name = array(); + foreach ( $membership_data[ 'data' ][ 'results' ] as $membership ) + $membership_name[ $membership[ 'id' ] ] = $membership[ 'name' ]; + + $possible_ids = variable_get( 'fulcrm_membership_self_set_membership_ids', array() ); + + $current_map = array(); + $new_map = array(); + foreach ( $possible_ids as $membership_id => $is_possible ) { + if ( $is_possible ) { + $current_map[ $membership_id ] = false; + $new_map[ $membership_id ] = array_key_exists( $membership_id, $form_state[ 'values' ][ 'memberships' ] ) ? $form_state[ 'values' ][ 'memberships' ][ $membership_id ] : 0; + } + } + foreach ( $person_data[ 'data' ][ 'person2memberships' ] as $p2m ) { + $membership_id = $p2m[ 'membership' ][ 'id' ]; + if ( array_key_exists( $membership_id, $possible_ids ) && $possible_ids[ $membership_id ] ) { + if ( fulcrm_membership_person2membership_is_current( $p2m ) ) { + $current_map[ $membership_id ] = true; + } + } + } + + // figure out the differences + foreach ( $possible_ids as $membership_id => $is_possible ) { + if ( $is_possible ) { + if ( $current_map[ $membership_id ] && $new_map[ $membership_id ] ) { + // do nothing + } elseif ( !$current_map[ $membership_id ] && !$new_map[ $membership_id ] ) { + // do nothing + } elseif ( $current_map[ $membership_id ] && !$new_map[ $membership_id ] ) { + // REMOVE MEMBERSHIP $membership_id + foreach ( $person_data[ 'data' ][ 'person2memberships' ] as $p2m ) { + if ( $p2m[ 'membership' ][ 'id' ] == $membership_id ) { + if ( fulcrm_membership_person2membership_is_current( $p2m ) ) { + if ( fulcrm_membership_cease_person2membership( $p2m ) ) + drupal_set_message( t('Ceased your "' . $p2m[ 'membership' ][ 'name' ] . '" membership.'), 'status', FALSE ); + } + } + } + } elseif ( !$current_map[ $membership_id ] && $new_map[ $membership_id ] ) { + // ADD MEMBERSHIP $membership_id + if ( fulcrm_membership_begin_person2membership( $person_id, $membership_id ) ) { + drupal_set_message( t('You have begun your "' . $membership_name[ $membership_id ] . '" membership.'), 'status', FALSE ); + } + } + } + } + } else { + drupal_set_message( t('There was a problem fetching membership information.'), 'error', FALSE ); + } + } else { + drupal_set_message( t('There was a problem fetching your subscription information.'), 'error', FALSE ); + } + } } function fulcrm_membership_self_set_form( $form, &$form_state ) { @@ -141,7 +262,7 @@ function fulcrm_membership_self_set_form( $form, &$form_state ) { $form[ 'title' ] = array( '#type' => 'item', '#title' => 'Subscription Preferences', - '#description' => '', + '#description' => 'This page lets you choose which subscriptions you will receive. Simply tick or untick the boxes as required.', ); $person_id = fulcrm_webhook_get_pk_for_entity_type( 'user', $user->uid, 'person' ); @@ -183,7 +304,7 @@ function fulcrm_membership_self_set_form( $form, &$form_state ) { } $form[ 'memberships' ] = array( '#type' => 'checkboxes', - '#title' => 'Subscriptions', + '#title' => 'Your Current Subscriptions', '#options' => $options, '#default_value' => $membership_map, ); @@ -196,11 +317,13 @@ function fulcrm_membership_self_set_form( $form, &$form_state ) { } $form[ 'actions' ] = array( '#type' => 'actions' ); + $form[ 'actions' ][ 'cancel' ] = array( '#markup' => l(t('Cancel'), 'user' ) ); $form[ 'actions' ][ 'save' ] = array( '#type' => 'submit', '#value' => t('Save'), '#submit' => array( 'fulcrm_membership_self_set_form_submit' ), ); + return $form; } From 6eab2ea47b5b3692292c5b1e876047ed2be05be5 Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Mon, 4 Mar 2019 10:40:05 +0100 Subject: [PATCH 4/4] can now cease a membership too --- fulcrm_membership.module | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/fulcrm_membership.module b/fulcrm_membership.module index 9d55dc4..e304ce9 100644 --- a/fulcrm_membership.module +++ b/fulcrm_membership.module @@ -132,6 +132,22 @@ function fulcrm_membership_optin( $passport ) { } } +function fulcrm_membership_can_self_set_person2membership( $p2m ) { + if ( array_key_exists( 'membership', $p2m ) ) { + if ( is_array( $p2m[ 'membership' ] ) ) + $membership_id = $p2m[ 'membership' ][ 'id' ]; + else + $membership_id = fulcrm_apiv2_url_to_pk( $p2m[ 'membership' ] ); + + $self_set_membership_ids = variable_get( 'fulcrm_membership_self_set_membership_ids', array() ); + if ( array_key_exists( $membership_id, $self_set_membership_ids ) ) { + if ( $self_set_membership_ids[ $membership_id ] ) + return true; + } + } + return false; +} + function fulcrm_membership_cease_person2membership( $p2m, $now = NULL ) { if ( is_null( $now ) ) $now = new DateTime(); @@ -140,7 +156,7 @@ function fulcrm_membership_cease_person2membership( $p2m, $now = NULL ) { $finish = $now->format( 'Y-m-d\TH:i:s.u\Z' ); if ( $p2m[ 'timescale' ] ) { - $api_data = fulcrm_apiv2_PATCH( $p2m[ 'url' ], $data = array( 'finish' => $finish ) ); + $api_data = fulcrm_apiv2_PATCH( $p2m[ 'timescale' ][ 'url' ], $data = array( 'finish' => $finish ) ); if ( $api_data[ 'success' ] ) { return true; } else {