public static function install()
 {
     // set up options array
     $new_stored_options = array('zws_contacts_database_plugin_table_name' => self::TABLE_NAME_NO_PREFIX, 'zws_contacts_database_memcached_active' => self::USE_MEMCACHED, 'zws_contacts_database_memcached_period' => self::MEMCACHED_PERIOD, 'zws_contacts_database_memcached_ip' => self::DEFAULT_MEMCACHED_IP, 'zws_contacts_database_memcached_port' => self::DEFAULT_MEMCACHED_PORT, 'zws_contacts_database_plugin_db_version' => self::DB_VERSION, 'zws_contacts_database_plugin_privacy_policy_url' => self::DEFAULT_PRIVACY_POLICY_URL, 'zws_contacts_database_google_server_api_key' => self::DEFAULT_GOOGLE_SERVER_API_KEY, 'zws_contacts_database_plugin_map_contact_icon_url' => self::DEFAULT_MAP_CONTACT_ICON, 'zws_contacts_database_plugin_map_target_icon_url' => self::DEFAULT_MAP_TARGET_ICON, 'zws_contacts_database_plugin_map_base_icon_url' => self::DEFAULT_MAP_BASE_ICON, 'zws_contacts_database_plugin_memcached_keybase' => self::MEMCACHED_KEY_BASE . '_' . rand(), 'zws_contacts_database_plugin_google_map_zoom' => self::GOOGLE_MAP_ZOOM, 'zws_contacts_database_plugin_base_name' => '', 'zws_contacts_database_plugin_base_postcode' => '', 'zws_contacts_database_plugin_base_coordinates' => array(), 'zws_contacts_database_plugin_admin_email_active' => self::ADMIN_EMAIL_ACTIVE, 'zws_contacts_database_plugin_admin_email' => array(), 'zws_contacts_database_plugin_reg_email_active' => self::REG_EMAIL_ACTIVE, 'zws_contacts_database_plugin_reg_email_from' => array(get_site_option('blogname'), get_site_option('admin_email')), 'zws_contacts_database_plugin_reg_email_subject' => self::REG_EMAIL_SUBJECT, 'zws_contacts_database_plugin_country_of_use' => self::COUNTRY_CODE);
     // set options array if does not exist
     if (!get_site_option(self::OPTIONS_LABEL)) {
         add_site_option(self::OPTIONS_LABEL, $new_stored_options);
     } else {
         // update array with new key/values if do not exist
         self::$existing_stored_options = get_site_option(self::OPTIONS_LABEL);
         foreach ($new_stored_options as $new_key => $new_value) {
             // if option and/or option value does not exist ...
             if (!self::check_exists($new_key)) {
                 // update existing options with the non-existent new key/value
                 self::$existing_stored_options[$new_key] = $new_value;
             }
         }
         // update the options with the newly updated existing_stored_options array
         update_site_option(self::OPTIONS_LABEL, self::$existing_stored_options);
     }
     // the special option for removal of data on uninstall
     if (!get_site_option('zws_contact_database_remove_data')) {
         add_site_option('zws_contacts_database_remove_data', self::DEFAULT_FULL_REMOVAL);
     }
     // create or update the database
     require_once __DIR__ . '/Database.php';
     \ZwsContactsDatabase\Database::update_database();
     // return true when successful
     return True;
 }
 public static function nearestContacts($how_many = 5, $target = NULL)
 {
     /* returns a multidimensional array of x contacts, sorted by distance from target, containing an innter array of details */
     if (isset($target)) {
         // set up variables
         $distance_array = array();
         // grab all registered users from db
         require_once __DIR__ . '/Database.php';
         $days_of_week = array(1 => 'mondays', 2 => 'tuesdays', 3 => 'wednesdays', 4 => 'thursdays', 5 => 'fridays', 6 => 'saturdays', 7 => 'sundays');
         // set variabe for earliest_time field corresponding to 'today'
         $earliest_time_today = 'earliest_time_' . $days_of_week[current_time(date('N', time()))];
         $latest_time_today = 'latest_time_' . $days_of_week[current_time(date('N', time()))];
         $result_set = \ZwsContactsDatabase\Database::getAllRecordsWhereIsNot('id', array('field' => $earliest_time_today, 'value' => 'UNAVL'));
         // loop postcodes and get distances
         if (!empty($result_set) && $result_set !== false && is_array($result_set)) {
             foreach ($result_set as $key => $row) {
                 // get distance from contact to each target. Returns false if error or target not found.
                 $distance = \ZwsContactsDatabase\DistanceCalculator::getDistance(sanitize_text_field($target), sanitize_text_field($row->postcode));
                 // if distance successfully returned add to the distance array
                 if ($distance !== false) {
                     $distance_array[sanitize_text_field($row->id)] = array('distance' => $distance, 'postcode' => sanitize_text_field($row->postcode), 'lng' => sanitize_text_field($row->lng), 'lat' => sanitize_text_field($row->lat), 'first_name' => sanitize_text_field($row->first_name), 'last_name' => sanitize_text_field($row->last_name), 'phone' => sanitize_text_field($row->phone), 'email' => sanitize_email($row->email), $earliest_time_today => sanitize_text_field($row->{$earliest_time_today}), $latest_time_today => sanitize_text_field($row->{$latest_time_today}), 'max_radius' => sanitize_text_field($row->max_radius), 'extra_info' => esc_textarea($row->extra_info));
                 }
             }
             if (!empty($distance_array)) {
                 $top_n = [];
                 $c = 0;
                 foreach ($distance_array as $key => $value) {
                     // if within max radius, and available, and within requested size of resultset
                     if (apply_filters('zws_filter_enforce_numeric', $value['distance']) <= apply_filters('zws_filter_enforce_numeric', $value['max_radius']) && $c < $how_many) {
                         // add the id to the actual dataset, at it will no longer be available as the key
                         $value['id'] = sanitize_text_field($key);
                         $top_n[$c] = $value;
                         $c++;
                     }
                 }
                 return $top_n;
             }
         }
         return false;
     }
 }
 private static function display_or_action()
 {
     $safe_values = array();
     // checks if incoming POST, and that nonce was set, and that nonce details match
     if (isset($_POST['submitted']) && isset($_POST['my_nonce_field']) && wp_verify_nonce(apply_filters('zws_filter_basic_sanitize', $_POST['my_nonce_field']), 'submit_details_action')) {
         // sanitise values
         $safe_values['first_name'] = apply_filters('zws_filter_basic_sanitize', $_POST['first_name']);
         $safe_values['last_name'] = apply_filters('zws_filter_basic_sanitize', $_POST['last_name']);
         $safe_values['postcode'] = apply_filters('zws_filter_sanitize_postcode', $_POST['postcode']);
         $safe_values['phone'] = apply_filters('zws_filter_enforce_numeric', $_POST['phone']);
         $safe_values['email'] = apply_filters('zws_filter_basic_sanitize', $_POST['email']);
         $safe_values['max_radius'] = apply_filters('zws_filter_enforce_numeric', $_POST['max_radius']);
         $safe_values['extra_info'] = apply_filters('zws_filter_limit_chars', apply_filters('zws_filter_text_with_linebreak', $_POST['extra_info']));
         $safe_values['pp_accepted'] = true ? isset($_POST['privacy_accept']) : false;
         foreach (unserialize(ZWS_CDB_DAYS) as $key => $day) {
             if (sanitize_text_field($_POST['earliest_time_' . $day]) !== 'Unavailable') {
                 $safe_values['earliest_time_' . $day] = apply_filters('zws_filter_basic_sanitize', $_POST['earliest_time_' . $day]);
             } else {
                 $safe_values['earliest_time_' . $day] = 'UNAVL';
             }
             $safe_values['latest_time_' . $day] = apply_filters('zws_filter_basic_sanitize', $_POST['latest_time_' . $day]);
         }
         // verify privacy policy has been accepted
         if (!$safe_values['pp_accepted']) {
             return self::failure_view('privacy');
         }
         // query google maps api to get longitute and latitude for the postcode, to pull back from db when displayed on map
         require_once __DIR__ . '/QueryAPI.php';
         $google_api_key = apply_filters('zws_filter_basic_sanitize', get_site_option(self::OPTIONS_LABEL)['zws_contacts_database_google_server_api_key']);
         $country_code = get_site_option(self::OPTIONS_LABEL)['zws_contacts_database_plugin_country_of_use'];
         $country_list = unserialize(ZWS_CDB_COUNTRY);
         $country_name = array_search($country_code, $country_list);
         $path = '?address=' . $safe_values['postcode'] . ',' . $country_name . '&language=en-EN&sensor=false&key=' . $google_api_key;
         $data = \ZwsContactsDatabase\QueryAPI::makeQuery(self::MAPS_API_BASE_URL, $path);
         if ($data['returned_data'] && $data['returned_data']['status'] === 'OK') {
             if ($data['cached']) {
                 // error_log('THE DATA WAS CACHED ...'); // debug
             }
             $safe_values['lat'] = sanitize_text_field($data['returned_data']['results'][0]['geometry']['location']['lat']);
             $safe_values['lng'] = sanitize_text_field($data['returned_data']['results'][0]['geometry']['location']['lng']);
         } else {
             return self::failure_view();
         }
         // send to database
         require_once __DIR__ . '/Database.php';
         if (\ZwsContactsDatabase\Database::insert($safe_values, $user_signup = True)) {
             // email admins
             if (!self::email_notifications($safe_values)) {
                 error_log('Error sending email to administrator ...');
             }
             // return success
             return self::success_view();
         } else {
             return self::failure_view();
         }
     } else {
         // if it wasn't a form submission, create / present the form
         return self::create_form();
     }
 }
 private static function get_records_for_name($last_name)
 {
     // grab all registered users from db
     require_once __DIR__ . '/Database.php';
     $result_set = \ZwsContactsDatabase\Database::getAllRecordsWhere('id', array('field' => 'last_name', 'value' => $last_name));
     // display the results
     require_once __DIR__ . '/ZwsPaginator.php';
     $page_size = 5;
     return true ? \ZwsContactsDatabase\ZwsPaginator::paginate($result_set, $page_size, $last_name) : false;
 }