protected function specific_definition($mform)
 {
     global $CFG, $OUTPUT;
     $image = '<a href="http://www.sebsoft.nl" target="_new"><img src="' . $OUTPUT->pix_url('logo', 'blocks_mailchimp') . '" /></a>';
     $mform->addElement('header', 'configheader', get_string('promo', 'block_mailchimp'));
     $mform->addElement('html', get_string('promodesc', 'block_mailchimp', $image));
     $mailchimplists = \block_mailchimp\helper::call_api_lists();
     // If we're having trouble loading mailing lists.
     if ($mailchimplists === false) {
         $mform->addElement('html', "<b>" . get_string('error:load_api_lists', 'block_mailchimp') . "</b>");
         // Or if we simply have no lists yet.
     } else {
         if (empty($mailchimplists)) {
             $mform->addElement('html', "<b>" . get_string('missing_mailing_lists', 'block_mailchimp') . "</b>");
         }
     }
 }
    public function get_content()
    {
        global $CFG;
        if ($this->content !== null) {
            return $this->content;
        }
        $this->content = new stdClass();
        $this->content->text = '';
        $this->content->footer = '';
        if (empty($this->instance)) {
            print_error('No instance ' . 'block_mailchimp');
        }
        $permissions = \block_mailchimp\helper::get_permission();
        // Make sure the correct settings are set.
        if (!isset($CFG->block_mailchimp_apicode) || !isset($CFG->block_mailchimp_linked_profile_field) || !isset($CFG->block_mailchimp_listid)) {
            $this->content->text .= get_string('not_setup_yet', 'block_mailchimp');
            return false;
        }
        if ($permissions['administration']) {
            // Global block settings.
            $url = "{$CFG->wwwroot}/admin/settings.php?section=blocksettingmailchimp";
            $this->content->text .= "<br /><a href='{$url}'>" . get_string('goto_settings', 'block_mailchimp') . "</a><br />";
        }
        $isregistered = \block_mailchimp\helper::is_mailchimp_registered_user($CFG->block_mailchimp_linked_profile_field);
        $submitbutton = !$isregistered ? 'subscribe' : 'unsubscribe';
        $welcometxtid = $isregistered ? 'welcome_txt_subscribed' : 'welcome_txt_unsubscribed';
        if (isloggedin() && !isguestuser()) {
            // Now time to start outputting the info.
            $this->content->text .= get_string($welcometxtid, 'block_mailchimp');
            $this->content->text .= '
            <div id="mailchimp">
            <form name="process_mailchimp" method="POST" action="' . $CFG->wwwroot . '/blocks/mailchimp/view/register.php">
                <input type="hidden" name="sourcePage" value="' . $_SERVER['PHP_SELF'] . '" />
                <input type="hidden" name="submit" value="true" />

                <input type="submit" name="process_mailchimp" value="' . get_string($submitbutton, 'block_mailchimp') . '" />
            </form>
            </div>';
        }
    }
    $userparams->timecreated = time();
    $userparams->timemodified = time();
    $DB->insert_record('block_mailchimp_users', $userparams);
    $usertoprocess = $DB->get_record('block_mailchimp_users', array('userid' => $USER->id));
} else {
    $usertoprocess->registered = $actionregister;
    $DB->update_record('block_mailchimp_users', $usertoprocess);
}
if (!$profilefieldtoprocess) {
    $profilefieldparams = new stdClass();
    $profilefieldparams->userid = $USER->id;
    $profilefieldparams->fieldid = $CFG->block_mailchimp_linked_profile_field;
    $profilefieldparams->data = $actionregister ? 1 : 0;
    $profilefieldparams->dataformat = 0;
    $DB->insert_record('user_info_data', $profilefieldparams);
    $profilefieldtoprocess = $DB->get_record('user_info_data', array('userid' => $USER->id));
} else {
    $profilefieldtoprocess->data = $actionregister;
    $DB->update_record('user_info_data', $profilefieldtoprocess);
}
// Mailchimp.
if ($actionregister) {
    $mergevars = array('EMAIL' => $USER->email, 'FNAME' => $USER->firstname, 'LNAME' => $USER->lastname);
    // We can already have a subscription, in which case we'll get an error code returned.
    \block_mailchimp\helper::listSubscribe($CFG->block_mailchimp_listid, $USER->email, $mergevars);
    redirect($CFG->wwwroot, get_string('subscribed_to_mailchimp', 'block_mailchimp'));
} else {
    // We can have already been unsubscribed, in which case we'll get an error code returned.
    \block_mailchimp\helper::listUnsubscribe($CFG->block_mailchimp_listid, $USER->email);
    redirect($CFG->wwwroot, get_string('unsubscribed_to_mailchimp', 'block_mailchimp'));
}
 /**
  * Synchronise Mailchimp account/subscription for single moodle user
  * 
  * @param \stdClass record from user table $moodleuser
  * 
  */
 private function synchronize_user($moodleuser, $listusers)
 {
     global $CFG, $DB;
     // First collect appropriate data.
     $mailchimpprofiledata = $this->mc_get_profile_data($moodleuser);
     $mailchimpinternaluser = $this->mc_get_internal_user($moodleuser);
     $externaluservars = array('EMAIL' => $moodleuser->email, 'FNAME' => $moodleuser->firstname, 'LNAME' => $moodleuser->lastname);
     // We might want to update the email.
     if ($mailchimpinternaluser->email != $moodleuser->email) {
         $this->mc_update_email_internal($moodleuser);
     }
     // Load external mailchimp userdata.
     $listmemberinfo = \block_mailchimp\helper::listMemberInfoSync($mailchimpinternaluser->email, $listusers);
     // In case of an error, the external user does not yet exist.
     if (!$listmemberinfo) {
         $externaluserregistered = false;
     } else {
         $externaluserregistered = true;
     }
     // If there's no subscription and we have no external user, abandon.
     // External: NA
     if (!$externaluserregistered) {
         if ($mailchimpprofiledata->data == '0') {
             // Add user to the mailchimp list, just as unsubscribed (we want the list to match moodle users)
             // Internal: U
             \block_mailchimp\helper::listUnsubscribe($CFG->block_mailchimp_listid, $moodleuser->email, $externaluservars, 'html', $listusers);
         } else {
             if ($mailchimpprofiledata->data == '1') {
                 // If there's no external user but a profile setting to subscribe, handle it.
                 // Internal: S
                 \block_mailchimp\helper::listSubscribe($CFG->block_mailchimp_listid, $moodleuser->email, $externaluservars, 'html', $listusers);
                 // Update the internal status if for some reason not synced
                 if (!(bool) $mailchimpinternaluser->registered) {
                     $this->mc_update_subscription_internal($moodleuser, true);
                 }
             }
         }
     } else {
         if ($externaluserregistered === true) {
             $externaluserinfo = $listmemberinfo;
             // User is externally known.
             if ($externaluserinfo['status'] == 'pending') {
                 // We do absolutely nothing while statusses are pending.
                 return;
             } else {
                 if ($externaluserinfo['status'] == 'unsubscribed') {
                     // Handle unsubscription sync.
                     // External: U
                     $comparison = $this->compareModified($mailchimpinternaluser->timemodified, $externaluserinfo['last_changed']);
                     if (!$comparison) {
                         // Error in comparison. Do something clever
                     } else {
                         if ((int) $comparison == 1) {
                             // Internal subscription status is newer, change mailchimp subscription status if needed.
                             if ($mailchimpprofiledata->data == '1') {
                                 // Internal: S
                                 // Subscribe the user in mailchimp
                                 \block_mailchimp\helper::listSubscribe($CFG->block_mailchimp_listid, $moodleuser->email, $externaluservars, 'html', $listusers);
                             }
                             // If data == 0, internal and external subscription status match.
                         } else {
                             if ((int) $comparison == 2) {
                                 // External subscription status is newer, change the internal status to unsubscribed if needed.
                                 if ($mailchimpprofiledata->data == '1') {
                                     // Internal: S
                                     // Unsubscribe the user in Moodle since MailChimp is last modified.
                                     $this->mc_update_profile_subscription($moodleuser, false);
                                     $this->mc_update_subscription_internal($moodleuser, false);
                                 }
                             }
                         }
                     }
                 } else {
                     if ($externaluserinfo['status'] == 'subscribed') {
                         // Handle subscription sync.
                         // External: S
                         $comparison = $this->compareModified($mailchimpinternaluser->timemodified, $externaluserinfo['last_changed']);
                         if (!$comparison) {
                             // Error in comparison. Do something clever. Get a fez.
                         } else {
                             if ((int) $comparison == 1) {
                                 // Internal subscription status is newer, change mailchimp subscription status if needed.
                                 if ($mailchimpprofiledata->data == '0') {
                                     // Internal: U
                                     // Unsubscribe the user from mailchimp
                                     \block_mailchimp\helper::listUnsubscribe($CFG->block_mailchimp_listid, $moodleuser->email, $externaluservars, 'html', $listusers);
                                 }
                                 // If data == 1, internal and external subscription status match.
                             } else {
                                 if ((int) $comparison == 2) {
                                     // External subscription status is newer, change the internal status to subscribed if needed.
                                     if ($mailchimpprofiledata->data == '0') {
                                         // Internal: U
                                         // Subscribe the user in Moodle since MailChimp is last modified.
                                         $this->mc_update_profile_subscription($moodleuser, true);
                                         $this->mc_update_subscription_internal($moodleuser, true);
                                     }
                                 }
                             }
                         }
                     } else {
                         if ($externaluserinfo['status'] == 'cleaned') {
                             // No idea what to do here.
                         }
                     }
                 }
             }
         }
     }
 }
 /**
  * Execute task
  * 
  * @global \moodle_database $DB
  * @global \stdClass $CFG
  * @return void
  * @throws \moodle_exception
  */
 public function execute_interestsync()
 {
     global $DB, $CFG;
     // Not going to work if we're missing settings.
     if (!isset($CFG->block_mailchimp_apicode) || !isset($CFG->block_mailchimp_listid) || !isset($CFG->block_mailchimp_linked_profile_field)) {
         cli_error("No API code or list selected. Aborting interest sync.", 1);
         return;
     }
     if (empty($CFG->block_mailchimp_interest) || $CFG->block_mailchimp_interest == "0") {
         cli_error("No interest selected. Aborting interest sync.", 1);
         return;
     }
     $listid = $CFG->block_mailchimp_listid;
     // Get all users in MailChimp.
     $listusers = \block_mailchimp\helper::getMembersSync();
     if (!$listusers) {
         cli_error("ERROR: Failed to get list of all members. Unable to synchronize users.", 1);
         return;
     }
     $listuserscount = count($listusers['members']);
     // Get list of users in Moodle
     cli_heading('Getting list of users in Moodle');
     $moodleusers = $DB->get_records('user');
     cli_heading('Sorting user lists');
     // Sort MailChimp users list
     // foreach ($listusers['members'] as $key => $row) {
     //     $emails[$key] = $row['email_address'];
     // }
     // array_multisort($emails, SORT_ASC, $listusers['members']);
     // unset($emails);
     // Sort Moodle users list
     foreach ($moodleusers as $key => $row) {
         $emails[$key] = $row->email;
     }
     array_multisort($emails, SORT_ASC, $moodleusers);
     unset($emails);
     // // Update all the users that are present in moodle so they have the interest added.
     // cli_heading('Adding interest to MailChimp users that are present in Moodle');
     // foreach ($moodleusers as $moodleuser) {
     //         foreach ($listusers['members'] as $listuser) {
     //             // Search through the moodleusers to find the user with corresponding email address
     //             $maxkey = count($moodleusers) - 1;
     //             $minkey = 0;
     //             $searchkey = round((($maxkey + $minkey)/2), 0, PHP_ROUND_HALF_UP);
     //             $moodleuser = false;
     //             $listuseremail = strtowlower($listuser['email_address']);
     //             while($minkey <= $maxkey) {
     //                 $moodleuseremail = strtolower($moodleusers[$searchkey]->email);
     //                 if ($listuseremail == $moodleuseremail) {
     //                     $moodleuser = $moodleusers[$searchkey];
     //                     break;
     //                 }
     //                 else if ($listuseremail > $moodleuseremail) {
     //                     $minkey = $searchkey + 1;
     //                     $searchkey = round((($maxkey + $minkey)/2), 0, PHP_ROUND_HALF_UP);
     //                 }
     //                 else if ($listuseremail < $moodleuseremail) {
     //                     $maxkey = $searchkey - 1;
     //                     $searchkey = round((($maxkey + $minkey)/2), 0, PHP_ROUND_HALF_UP);
     //                 }
     //         }
     //         // No corresponding moodleuser for the user in mailchimp
     //         if ($moodleuser == false) {
     //             // Do nothing for now
     //             break;
     //         }
     //     // Maybe add some error handling here
     // }
     // Update subscription status info
     cli_heading('Applying interest label and updating subscription status');
     foreach ($listusers['members'] as $listuserkey => $listuser) {
         $statuspercent = round($listuserkey / $listuserscount * 100, 1, PHP_ROUND_HALF_UP);
         echo $statuspercent, "%        \r";
         // Search through the mailchimp users to find the user with corresponding email address
         $maxkey = count($moodleusers) - 1;
         $minkey = 0;
         $searchkey = round(($maxkey + $minkey) / 2, 0, PHP_ROUND_HALF_UP);
         $moodleuser = false;
         $listuseremail = strtolower($listuser['email_address']);
         while ($minkey <= $maxkey) {
             $moodleuseremail = strtolower($moodleusers[$searchkey]->email);
             if ($listuseremail == $moodleuseremail) {
                 $moodleuser = $moodleusers[$searchkey];
                 break;
             } else {
                 if ($listuseremail > $moodleuseremail) {
                     $minkey = $searchkey + 1;
                     $searchkey = round(($maxkey + $minkey) / 2, 0, PHP_ROUND_HALF_UP);
                 } else {
                     if ($listuseremail < $moodleuseremail) {
                         $maxkey = $searchkey - 1;
                         $searchkey = round(($maxkey + $minkey) / 2, 0, PHP_ROUND_HALF_UP);
                     }
                 }
             }
         }
         // No corresponding moodleuser for the user in mailchimp
         if ($moodleuser == false) {
             // Do nothing for now
             break;
         }
         // Apply interest label to the user in MailChimp (First and last names are updated from Moodle)
         $args['EMAIL'] = strtolower($moodleuser->email);
         $args['FNAME'] = $moodleuser->firstname;
         $args['LNAME'] = $moodleuser->lastname;
         $updatestatus = \block_mailchimp\helper::listUpdateMember($listid, $moodleuser->email, $args, 'html');
         // Get the profile data for this moodleuser
         $moodleuserprofiledata = $this->mc_get_profile_data($moodleuser);
         // Check subscription status in MC
         if ($listuser['status'] == 'unsubscribed' && $moodleuserprofiledata->data == '1') {
             // User is unsubscribed in mailchimp but marked as subscribed in moodle. Mailchimp is the source of truth for this sync. We'll unsubscribe in moodle
             $this->mc_update_profile_subscription($moodleuser, false);
         }
         if ($listuser['status'] == 'subscribed' && $moodleuserprofiledata->data == '0') {
             // User is subscribed in mailchimp but marked as unsubscribed in moodle. Subscribe the user in moodle
             $this->mc_update_profile_subscription($moodleuser, true);
         }
     }
     // New line for next output
     echo 'Done.', "\n";
 }
    } else {
        if (empty($mailchimplists)) {
            $mailchimplists = array('' => get_string('no_lists', 'block_mailchimp'));
            $strheader = "<p><b>" . get_string("missing_mailing_lists", 'block_mailchimp') . "</b></p>";
        }
    }
    if ($mailchimpinterests === false) {
        $mailchimpinterests = array();
        $strheader = "<p><b>" . get_string("error:load_interests", 'block_mailchimp') . "</b></p>";
        // If we simply have no interests in mailchimp yet.
    } else {
        if (empty($mailchimpinterests)) {
            $mailchimpinterests = array('' => get_string('no_interests', 'block_mailchimp'));
            $strheader = "<p><b>" . get_string("missing_interests", 'block_mailchimp') . "</b></p>";
        }
    }
    // Block name.
    $settings->add(new admin_setting_configtext('block_mailchimp_title', get_string("title", 'block_mailchimp'), get_string("config:title_description", 'block_mailchimp'), get_string('blockname', 'block_mailchimp')));
    // Api code.
    // We're using custom admin settings cause we want to use some validation.
    $settings->add(new \block_mailchimp\setting\apikey('block_mailchimp_apicode', get_string("apicode", 'block_mailchimp') . $helpbuttonapicode, get_string("config:api_code_description", 'block_mailchimp'), ''));
    if (!($mailchimpprofilefields = \block_mailchimp\helper::get_chipmail_profile_fields())) {
        $mailchimpprofilefields = array('' => get_string('no_profile_fields', 'block_mailchimp'));
    }
    // List id.
    $settings->add(new admin_setting_configselect('block_mailchimp_listid', get_string("listid", 'block_mailchimp') . $helpbuttonapilists, get_string("config:api_list_description", 'block_mailchimp'), ' ', $mailchimplists));
    // Interest name.
    $settings->add(new admin_setting_configselect('block_mailchimp_interest', get_string("interest", 'block_mailchimp') . $helpbuttoninterest, get_string("config:interest_description", 'block_mailchimp'), ' ', $mailchimpinterests));
    // Profile field.
    $settings->add(new admin_setting_configselect('block_mailchimp_linked_profile_field', get_string("linked_profile_field", 'block_mailchimp') . $helpbuttonprofilefield, get_string("config:linked_profile_field_description", 'block_mailchimp'), ' ', $mailchimpprofilefields));
}
 /**
  * Validate data before storage
  * @param string data
  * @return mixed true if ok string if error found
  */
 public function validate($data)
 {
     global $CFG;
     $listcall = \block_mailchimp\helper::call_api_lists($data);
     if (!$listcall) {
         //There was an error calling the lists.
         return get_string('error:save_api_code', 'block_mailchimp');
     }
     return true;
 }