Skip to content

Instantly share code, notes, and snippets.

@ChrisFlannagan
Last active September 11, 2015 18:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisFlannagan/27ad1be39d2739bf69b3 to your computer and use it in GitHub Desktop.
Save ChrisFlannagan/27ad1be39d2739bf69b3 to your computer and use it in GitHub Desktop.
Chris Flannagan - Code Samples
/**
* admin-beerjs, Beer Check In ADMIN JS
*
* @version 1.0.0
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @author Chris Flannagan
* @created 2015-08-26
* @updated 2015-08-26
* @link http://fltapmap.com
*/
var listcnt = 0;
jQuery(function ($) {
$(document).ready(function()
{
$("#add-beer").click(function() {
var btn_build = "<li class='tm_beer_btn'>";
btn_build += "<strong><span class='store_name'>" + $("#tm_name_input").val() + "</span></strong> <input type='button' class='remove_beer_btn' value='remove' /><br />";
btn_build += "<span class='store_style'>" + $("#tm_style_input").val() + "</span><br />";
btn_build += "<span class='store_brewery'>" + $("#tm_brewery_input").val() + "</span><br />";
btn_build += "<span class='store_abv'>" + $("#tm_abv_input").val().replace("%", "") + "</span><br />";
btn_build += "<span class='store_url'>" + $("#tm_url_input").val() + "</span></li>";
console.log(btn_build);
$("#tm_current_list").html($("#tm_current_list").html() + btn_build);
});
$(document).on('click', '.remove_beer_btn', function() {
console.log("whats up");
$(this).closest('li').remove();
});
$("#save-beer").click(function() {
var send_list = { };
var beer_count = 0;
$("#tm_current_list li").each(function() {
console.log($(this).find(".store_name").text());
var beer_array = new Array();
beer_array[0] = $(this).find(".store_name").text();
beer_array[1] = $(this).find(".store_style").text();
beer_array[2] = $(this).find(".store_brewery").text();
beer_array[3] = $(this).find(".store_abv").text();
beer_array[4] = $(this).find(".store_url").text();
send_list[beer_count + $(this).find(".store_name").text()] = beer_array;
beer_count++;
});
console.log(send_list);
});
});
});
<?php
/**
* Plugin Name: Beer Check In
* Plugin URI: http://fltapmap.com
* Description: This plugin allows bar websites to let users check in what they are drinking at their establishment on Facebook and Twitter
* Version: 1.0.0
* Author: Chris Flannagan
* Author URI: http://whoischris.com
* License: GPL2
*/
global $beer_db_version;
$beer_db_version = '1.0';
function beer_install () {
global $wpdb;
$table_name = $wpdb->prefix . 'beer_check_in';
$charset_collate = $wpdb->get_charset_collate();
$sql = 'CREATE TABLE $table_name (
id mediumint( 9 ) NOT NULL AUTO_INCREMENT,
time datetime DEFAULT "0000-00-00 00:00:00" NOT NULL,
name varchar( 155 ) DEFAULT "" NOT NULL,
brewery varchar( 155 ) DEFAULT "" NOT NULL,
url varchar( 255 ) DEFAULT "" NOT NULL,
abv varchar( 15 ) DEFAULT "" NOT NULL,
UNIQUE KEY id ( id )
) $charset_collate;';
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
add_option( 'beer_db_version', $beer_db_version );
}
add_action( 'admin_menu', 'beer_check_in_menu' );
function beer_check_in_menu() {
add_options_page( 'Beer Check In Options', 'Beer Check In', 'manage_options', 'beer-check-in', 'beer_check_in_options' );
}
register_activation_hook( __FILE__, 'beer_install' );
//BEER SETTINGS PAGE
function beer_check_in_options() {
$current_list = '';
//UPDATE BEERS AND DISPLAY UPDATE MESSAGE
if( !current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
}
if( isset( $_POST[$hidden_field_name] ) && $_POST[$hidden_field_name] == 'Y' ) {
$beer_list = explode( '[tm_SP]', $_POST['tm_final_list'] );
?>
<div class='updated'><p><strong><?php
echo 'Beer List Saved!';
//_e( 'Beer list saved!', 'menu-beer' ); ?></strong></p></div>
<?php
}
//DISPLAY BEER MENU OPTIONS AND SETTINGS
echo '<div class="wrap">';
// Add localization support later
//echo '<h2>' . __( 'Beer Check In Settings', 'menu-beer' ) . '</h2>';
echo '<h2>Beer Check In Settings</h2>';
?>
<!-- Creat form for entering beers one at a time //-->
<form name='beerform' method='post' action=''>
<input type='hidden' name='<?php echo $hidden_field_name; ?>' value='Y' />
<p><?php
echo 'Beer Name: ';
//_e( 'Add Beer Name: ', 'menu-beer' ); ?>
<input type='text' id='tm_name_input' size='40' maxlength='140'>
</p>
<p><?php
echo 'Style: '; ?>
<select id='tm_style_input'>
<option value='Pale Ale'>Pale Ale</option>
<option value='Stout'>Stout</option>
<option value='IPA'>IPA</option>
<option value='Porter'>Porter</option>
<option value='Wheat'>Wheat</option>
<option value='Belgian'>Belgian</option>
</select>
</p>
<p><?php
echo 'Brewery: '; ?>
<input type='text' id='tm_brewery_input' value='<?php echo $opt_val; ?>' size='40' maxlength='140'>
</p>
<p><?php
echo 'Website: '; ?>
<input type='text' id='tm_url_input' value='<?php echo $opt_val; ?>' size='40' maxlength='140'>
</p>
<p><?php
echo 'ABV: ';?>
<input type='text' id='tm_abv_input' value='<?php echo $opt_val; ?>' size='5'>%
</p>
<hr />
<p class='submit'>
<input type='button' id='add-beer' class='button-primary' value='Add Beer' /> <input type='button' id='save-beer' class='button-primary' value='Save Tap List' />
</p>
</form>
</div>
<ul id='tm_current_list'><?php
//foreach current list, remove button option
?></ul>
<?php
}
add_action( 'wp_head', 'my_beer_js' );
function my_beer_js() {
echo '<!-- Beer Check In Powered By FLTapMap.com //-->';
}
add_action( 'admin_enqueue_scripts', 'my_load_scripts' );
function my_load_scripts() {
wp_enqueue_script( 'custom-js', plugin_dir_url( __FILE__ ) . 'js/admin-beerjs.js', array( 'jquery' ), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'my_enqueued_assets' );
function my_enqueued_assets() {
wp_enqueue_script( 'beerjs', plugin_dir_url( __FILE__ ) . 'beerjs.js', array( 'jquery' ), '1.0', true );
}
<?php
function search_beers( $q ) {
global $wpdb;
$scrub_q = esc_sql( $q );
//we will combine brewery and name of beers in database for searching as well as searching
$results = $wpdb->get_results( "SELECT * FROM wp_beer_check_in WHERE CONCAT_WS(' ', brewery, name) LIKE '%$scrub_q%' OR CONCAT_WS(' ', name, brewery) LIKE '%$scrub_q%'");
//if results comes back empty we are going to search each individual keyword in the search string and at least show some results if possible
if( empty( $results ) ) {
$wide_q = explode( " ", $scrub_q );
//id='0' saves have to deal with the first or last item having a dangling "OR"
$sql = "SELECT * FROM wp_beer_check_in WHERE ID='0'";
foreach( $wide_q as $single ) {
$sql .= " OR brewery LIKE '%$single%' OR name LIKE '%$single%'";
}
$results = $wpdb->get_results( $sql );
}
$beers = array();
if( $results ) {
//build our return json array
foreach( $results as $beer ) {
$beers[] = $beer;
}
return json_encode($beers, JSON_PRETTY_PRINT);
} //no results, return null
}
<?php
//create posts for each individual machine
//each posts will have optional meta data attached
//meta data will be searchable in final product
require_once("our_db_info.php");
$db_conn = new mysqli( $our_server, $our_db_user, $our_db_pass, $our_db );
if ( $db_conn->connect_error ) {
die( "DB Connect ERROR: " . $db_conn->connect_error);
}
//prepare data rows of machine logistics
$csv = explode( "\n", file_get_contents( "dtd.txt" ) );
$meta_titles = array();
//initiate prepared statements
$prepsql_machines = "INSERT INTO wp_posts (post_title, post_name, post_author) VALUE (?, ?, '1')";
$prepsql_machines->bind_param( "ss", $col_name, $col_small );
foreach( $csv as $row ) {
if( empty( $meta_titles ) ) {
//first row, set titles for meta fields
$meta_titles = explode( ",", $row );
} else {
$cols = explode( ",", $row );
$cnt = 0;
$nid = 0;
foreach( $cols as $col ) {
if( $cnt == 0 ) {
//first column is always the title of the machine
$col_name = $col;
$col_small = strtolower( $col );
$prepsql_machines->execute();
//show me the sql so I can check formatting/output
echo $sql . "<br />";
//since our sql statement could have any number of meta entries we can't use a prepared statement (I don't think)
$nid = mysqli_insert_id();
$sql = "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUE ";
} else {
//gonna add a comma only if this is past our first meta entry
if( $cnt > 1 ) {
$sql .= ", ";
}
$sql .= "('" . $nid . "', '" . $meta_titles[ $cnt ] . "', '" . $col . "')";
}
$cnt++;
}
//show me dat meta
echo "META: " . $sql . "<br />";
//insert
if ( $db_conn->query( $sql ) === TRUE ) {
echo "<em>cool</em><br />";
} else {
echo "sql error: " . $db_conn->error . "<hr />";
}
}
}
$prepsql_machines->close();
$db_conn->close();
?>
<?php
/*
data file is horrible and they control, many rows just ,,,,,,,,,, instead of actual data, excess white space in key columns at times
data is always 'owner name, franchise key, phone' ... sometimes 4th column is area name, sometimes 4th is empty and 5th is area name /sigh
SOMETIMES the area is just one field followed by an inconsistent number of commas until it reaches the final column which is always email.
Oh yea and sometimes the data fields are inclosed in parenthesis
Client unwilling to redo data format, kill me now
*/
//clean the input, make sure proper search string
$all_states = ',AL,AK,AZ,AR,CA,CO,CT,DE,DC,FL,GA,HI,ID,IL,IN,IA,KS,KY,LA,ME,MD,MA,MI,MN,MS,MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,OH,OK,OR,PA,RI,SC,SD,TN,TX,UT,VT,VA,WA,WV,WI,WY,';
if( strpos( ',' . sanitize_text_field( $_GET['state'] ) . ',', $all_states ) !== false ) {
$my_file = 'http://dramakids.com/public_html/wp-content/themes/Karma/data.csv';
$data = explode( '\n', file_get_contents( $my_file ) );
$areas = array();
$found = 0;
foreach ( $data as $dat ) {
$county_start = 3;
$cols = explode( ',', preg_replace( '/[^(\x20-\x7F)]*/', '', $dat ) );
//detect proper data in row and state search
if ( preg_match( '/[a-z]+/', $dat ) && strpos( strtoupper( str_replace( ' ', '', $cols[1] ) ), $_GET['state'] ) !== false ) {
if (!preg_match('/[a-z]+/', $cols[3])) {
$county_start = 4;
}
$primary_county = $cols[$county_start];
//$areas[region][franchise key][data]
$areas[ $primary_county ]['primary_county'] = $primary_county;
$areas[ $primary_county ][ $cols[1] ]['owner'] = $cols[0];
$areas[ $primary_county ][ $cols[1] ]['franchise_key'] = $cols[1];
$areas[ $primary_county ][ $cols[1] ]['phone'] = $cols[2];
$areas[ $primary_county ][ $cols[1] ]['email'] = $cols[ count( $cols ) - 1 ];
//since counties have to be separated with commas and even if one county still followed by string of commas
for ( $i = 4; $i < ( count( $cols ) - 1 ); $i++ ) {
if ( $i > 4 && preg_match( '/[a-z]+/', $cols[ $i ] ) ) {
$areas[ $primary_county ][ $cols[1] ]['counties'] .= ', ';
}
$areas[ $primary_county ][ $cols[1] ]['counties'] .= $cols[ $i ];
}
$found++;
}
}
//let's make these results look good.
ksort( $areas );
$other_areas = '';
//prepare output for cleanup
$allowed_html = array(
'h1' => array(),
'p' => array(),
'br' => array(),
'span' => array(),
'a' => array(
'href' => array()
)
);
foreach ( $areas as $area ) {
$skip = 0;
$build_list = '';
foreach ( $area as $county ) {
//skip first element (primary_county)
if ( $skip > 0 ) {
$build_list .= '<p><span>' . $county['counties'] . '</span><br />';
$build_list .= $county['phone'] . '<br />';
$build_list .= '<a href='http://dramakids.com/' . $county['franchise_key'] . ''>Visit the Local Website</a>';
}
$skip++;
}
if ( count( $area ) > 2 ) {
echo '<h1>' . $area['primary_county'] . '</h1>' . $build_list;
} else {
echo wp_kses( $other_areas .= $build_list, $allowed_html );
}
}
if ( $other_areas != '' ) {
echo wp_kses( '<h1>Other ' . $_GET['state'] . ' Locations</h1>' . $other_areas, $allowed_html );
}
}
<!--
All the links in these pages point to documents ranging from pdf to docx files.
These links need to be listed as "documents of supporting evidence" in a single page.
The links are very messy from an import of 400+ html pages that were terribly formatted.
Cycling through every page we extract all <a> tags and list in alpha order.
//-->
<ul class='anchor_letters'>
<?php
//Create alpha index navigation
$az_range = range( 'A', 'Z' );
foreach ( $az_range as $letter )
{
//floating list
echo '<li>[<a href="#letter' . $letter . '">' . $letter . '</a>]</li>';
}
?>
</ul>
<?php
//final results array for listing
$all_documents = array();
$args = array(
'order' => 'ASC',
'orderby' => 'menu_order',
'post_type' => 'nav_menu_item',
'post_status' => 'publish',
'output' => ARRAY_A,
'output_key' => 'menu_order',
'nopaging' => true,
'update_post_term_cache' => false );
$menu_items = wp_get_nav_menu_items( 4, $args );
foreach( $menu_items as $item ) {
$page = get_post( $item->object_id );
$dom = new DOMDocument;
$dom->loadHTML( $page->post_content );
foreach ( $dom->getElementsByTagName( 'a' ) as $node )
{
//don't list email links and avoid links with empty nodeValue, there's a lot for some reason.
//also quite a few links are just a no break space in the value and we don't want those listed per instruction
if( strpos( $node->getAttribute( 'href' ), '@' ) === false && strpos( $node->getAttribute( 'href' ), '.' ) !== false ) {
//we default to labeling the link as the nodevalue but the client wanted an option to set the name in the html of the page
//we are pulling the link from. I added a 'title' attribute option where they can name the link what they'd like.
//For some reason they don't always want it listed in the supporting document index the same it is listed in the page .
if( $node->hasAttribute( 'title' ) ) {
// We add the letter the link value starts with to the beginning of the string, will remove letter but will use for sorting and listing later
// We add the link value into a comment immediately after so we can sort by the value and not the filename/link directory
// I can't use the title as the array key because we are using the filename to avoid duplicate links to the same file
// We test for 'title' first so we can overwrite a file's listing based on user created titles instead of possible
// The only option for a link's value other than the optional title attribute is the current value
//we strtolower in order to sort correctly, php sorts capitals before lowercase (or vice-verse?) and we do not want to sort by any numbers or odd characters so we remove all non-alpha
$alpha_only = strtolower( preg_replace( "/[^A-Za-z]/", '', $node->getAttribute( 'title' ) ) );
$all_documents[ $node->getAttribute( 'href' ) ] = substr( $alpha_only, 0, 1 ) . '<!--' . $alpha_only . '//--><a href="' . $node->getAttribute( 'href' ) . '">' . $node->getAttribute( 'title' ) . '</a><br />[<a class="citation" href="' . $item->url . '">source - ' . $item->title . '</a>]';
} elseif( !array_key_exists($node->getAttribute( 'href' ), $all_documents ) ) {
$alpha_only = strtolower( preg_replace( "/[^A-Za-z]/", '', $node->nodeValue ) );
$all_documents[ $node->getAttribute( 'href' ) ] = substr( $alpha_only, 0, 1 ) . '<!--' . $alpha_only . '//--><a href="' . $node->getAttribute( 'href' ) . '">' . $node->nodeValue . '</a><br />[<a class="citation" href="' . $item->url . '">source - ' . $item->title . '</a>]';
}
}
}
}
sort( $all_documents );
//so we can start with the first character of the first item in our sorted list we just set this to a dash.
$current_letter = "-";
//prepare cleanup for output
$allowedhtml = array(
'h2' => array(),
'br' => array(),
'ul' => array(),
'li' => array(),
'a' => array(
'href' => array(),
'title' => array(),
'class' => array(),
'name' => array()
)
);
//if the link value contains no alpha characters we put in $extra for now and do no display per client request
//if the link has no alpha then the first character will be < from the sort comment
$extra = array();
foreach( $all_documents as $document ) {
$link_letter = substr( $document, 0, 1 );
if($link_letter != "<") {
if( $link_letter != $current_letter ) {
//if this is not the first list we need to close out the previous
if( $current_letter != '-' ) {
echo '</ul>';
}
$current_letter = $link_letter;
echo wp_kses( '<h2><a name="letter' . strtoupper( $current_letter ) . '"></a>' . strtoupper( $current_letter ) . '</h2><ul>', $allowedhtml );
}
echo wp_kses( '<li>' . substr( $document, 1 ) . '</li>', $allowedhtml );
} else {
$extra = $link_letter;
}
}
package com.tapmap.app.tapmapapp;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.content.res.Resources;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.tapmap.app.tapmapapp.util.onTaskCompleted;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Period;
/**
* Created by Flanntation on 6/8/2015.
*/
public class RetrieveFeedTask extends AsyncTask<String,Void,String> {
/* Not sure this is necessary since I found a way to just handle marker clicks in maps activity */
private onTaskCompleted listener;
public RetrieveFeedTask(onTaskCompleted listener){
this.listener=listener;
}
/* END NOT SURE ABOUT CODE LOL */
private Exception exception;
private HttpURLConnection urlConnection;
public InputStream in;
private String total;
SimpleDateFormat simpleDateFormat;
protected String doInBackground(String... urls) {
Log.i("RetrieveFeedTask","IN EHER");
//return null;
try {
URL url = new URL("http://fltapmap.com/app-locs.php");
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
in = new BufferedInputStream(urlConnection.getInputStream());
try {
BufferedReader r = new BufferedReader(new InputStreamReader(in));
String line;
total = "";
while ((line = r.readLine()) != null) {
total += line + "\n";
}
urlConnection.disconnect();
return total;
} catch(IOException ioe) {
Log.i("RetrieveFeedTask", ioe.getMessage());
urlConnection.disconnect();
return null;
}
} catch (IOException ioe) {
urlConnection.disconnect();
return null;
}
} catch (MalformedURLException ioex) {
return null;
}
}
protected void onPostExecute(String feed) {
// TODO: check this.exception
Log.i("RetrieveFeedTask","Reading a line:" + feed);
Date lastUp = new Date();
float alph = 1.0f;
String textStr[] = feed.toString().split("\\r?\\n");
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
for (int i = 0; i < textStr.length; i++) {
try {
if(textStr[i].length() > 10) {
Log.i("RetrieveFeedTask", "Reading a line:" + textStr[i].toString());
String[] separated = textStr[i].split(",");
alph = 1.0f;
try {
if(calcDiff(simpleDateFormat.parse(separated[4]), new Date()).getDays() > 5) {
alph = 0.8f;
}
if(calcDiff(simpleDateFormat.parse(separated[4]), new Date()).getDays() > 10) {
alph = 0.5f;
}
if(calcDiff(simpleDateFormat.parse(separated[4]), new Date()).getDays() > 18) {
alph = 0.2f;
}
Log.i("CALC", simpleDateFormat.parse(separated[4]).toString());
} catch (Exception e3) {
alph = 0.1f;
}
double currentLatitude = Double.parseDouble(separated[1]);
double currentLongitude = Double.parseDouble(separated[2]);
Log.i("RetrieveFeedTask", "As double: " + currentLatitude + "-" + currentLongitude);
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
MapsActivity.venues.add(new MarkerActivity());
MapsActivity.venues.get(i).venueid = separated[0];
MapsActivity.venues.get(i).venuename = separated[3];
MapsActivity.venues.get(i).latLng = latLng;
MapsActivity.venues.get(i).markid = i;
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!")
.snippet(Integer.toString(i))
.alpha(alph)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.tmico));
MapsActivity.mMap.addMarker(options);
}
} catch(Exception is)
{
Log.i("RetrieveFeedTask-EXC",is.getMessage());
is.printStackTrace();
}
}
listener.onTaskCompleted();
}
private Days calcDiff(Date startDate,Date endDate)
{
DateTime START_DT = (startDate==null)?null:new DateTime(startDate);
DateTime END_DT = (endDate==null)?null:new DateTime(endDate);
Days period = Days.daysBetween(START_DT, END_DT);
return period;
}
}
<?php
/**
Template Name: Tap Map SEARCH
*/
get_header();
global $query_string;
?>
<?php while ( have_posts() ) : the_post(); ?>
<div id="title-bar">
<h1 class="bar-entry-title container"><?php the_title(); ?></h1>
</div>
<div id="primary" class="full-width content-area col-md-12">
<main id="main" class="site-main" role="main">
<?php get_template_part( 'content', 'page' ); ?>
<div id='search_results'>
</div>
<script language="javascript" type="text/javascript">
curlat = "0";
curlon = "0";
//calculate distance between user and the beer on tap
function getDistance(lat1, lon1, lat2, lon2, unit) {
var radlat1 = Math.PI * lat1/180
var radlat2 = Math.PI * lat2/180
var radlon1 = Math.PI * lon1/180
var radlon2 = Math.PI * lon2/180
var theta = lon1-lon2
var radtheta = Math.PI * theta/180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180/Math.PI
dist = dist * 60 * 1.1515
if (unit=="K") { dist = dist * 1.609344 }
if (unit=="N") { dist = dist * 0.8684 }
return dist
};
//init location tracking
function initGeolocation() {
if (navigator && navigator.geolocation) {
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
} else {
console.log('Geolocation is not supported');
}
}
function errorCallback() {
//still need to setup results listing with no user location
}
//if we have user position let's sort these results by distance!
function successCallback(position) {
curlat = position.coords.latitude;
curlon = position.coords.longitude;
console.log(curlat + "," + curlon);
//grab our results and parse in javascript json
var beers = JSON.parse('{ "ontap" : <?php
if(isset($_GET['q']) && $_GET['q'] != '') {
$located = search_beers( $_GET['q'] );
echo $located;
}
?> }');
//we need to sort these results by distance
sort_results = new Array();
for(var i = 0; i < beers.ontap.length; i++) {
//get distance in float miles
var distance = getDistance(curlat, curlon, beers.ontap[i].lat, beers.ontap[i].lon, 'm');
//add our print output but precede it with the distance for sorting ... will be removed in final output
sort_results[i] = distance + "<li><span class='dist'>" + ( Math.round( distance * 10 ) / 10 ) + " miles away</span> " + beers.ontap[i].brewery + " <a href='../beers/" + beers.ontap[i].id + "'>" + beers.ontap[i].name + "</a> (" + beers.ontap[i].abv + "%)</li>";
}
//sort these decimals by popping off the <li> and everything after then shifting based on decimal split
sort_results.sort(function (a, b) {
var result;
prev_a = a.split('<li>');
a = prev_a[0].split(".");
prev_b = b.split('<li>');
b = prev_b[0].split('.');
while (a.length) {
if (result = a.shift() - (b.shift() || 0)) {
return result;
}
}
return -b.length;
});
//no we cycle through the sorted distances and use the key related to the result that needs to be printed and removing the preceding miles number
var build = "<ul>";
for(var key in sort_results) {
c = sort_results[key].split("<li>");
build += "<li>" + c[1];
}
build += "</ul>";
document.getElementById('search_results').innerHTML = build;
}
//everything in place, let's go!
this.initGeolocation();
</script>
<?php endwhile; // end of the loop. ?>
</main><!-- #main -->
</div><!-- #primary -->
<?php get_sidebar('footer'); ?>
<?php get_footer(); ?>
package com.tapmap.app.tapmapapp;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.lang.*;
import java.util.Iterator;
public class SearchBeer extends Activity {
private Exception exception;
private HttpURLConnection urlConnection;
public InputStream in;
private String total;
private Boolean done = false;
private Boolean search_one = false;
private CountDownTimer countDownTimer;
EditText searchBox;
Thread t;
Long curTime;
Long thenTime;
boolean timerStarted = false;
long lastCall;
String[] btnStrings;
LinearLayout resultsLayout;
LayoutInflater inflater;
View search_beer;
TextView tap_list;
public String[] location;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_search_beer);
t = new Thread(getTaps);
thenTime = System.nanoTime();
countDownTimer = new MyCountDownTimer(1000, 1000);
inflater = this.getLayoutInflater();
search_beer = inflater.inflate(R.layout.activity_search_beer, (ViewGroup) findViewById(R.id.rootlinear), true);
resultsLayout = (LinearLayout) search_beer.findViewById(R.id.resultsbuttons);
location = getIntent().getStringExtra("tloc").split(",");
tap_list = (TextView) findViewById(R.id.tap_list);
searchBox = (EditText) findViewById(R.id.EditTextSearch);
searchBox.addTextChangedListener(searchAgain);
}
TextWatcher searchAgain = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
resultsLayout.removeAllViews();
tap_list.setText("loading results ...");
if(searchBox.getText().length() < 4) {
tap_list.setText("");
}
curTime = System.nanoTime();
if(timerStarted) {
countDownTimer.cancel();
countDownTimer = new MyCountDownTimer(1000, 1000);
}
countDownTimer.start();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
@Override
public void onFinish() {
runSearch();
}
@Override
public void onTick(long millisUntilFinished) {
}
}
public void runSearch() {
Log.i("Time", String.valueOf(t.isAlive()));
if(searchBox.getText().length() > 3) {
search_one = true;
done = false;
t.interrupt();
t = null;
t = new Thread(getTaps);
t.start();
while(done.equals(false)) {
//do nothing
}
setTaps(total);
lastCall = System.nanoTime();
tap_list.setText("");
done = true;
}
}
View.OnClickListener getOnClickDoSomething(final Button button) {
return new View.OnClickListener() {
public void onClick(View v) {
String[] pieces = button.getTag().toString().split(",");
Intent bar = new Intent(SearchBeer.this, BarBrewry.class);
bar.putExtra("venuename", pieces[1]);
bar.putExtra("venueid", pieces[0]);
bar.putExtra("latlng", pieces[4] + "," + pieces[5]);
bar.putExtra("distance", pieces[3]);
startActivity(bar);
}
};
}
public Boolean setTaps(String total) {
Log.i("TIME", "total val = " + total);
btnStrings = total.split("SPLITHERE");
Log.i("TIME", "button length: " + btnStrings.length);
String added = "";
resultsLayout.removeAllViews();
for(Integer i=0;i<btnStrings.length;i++) {
try {
String[] tmp = btnStrings[i].split(",");
Button addButton = new Button(this);
Log.i("ARR", Arrays.toString(tmp));
/*
this worked for the most part, save for later in case new method breaks
Location.distanceBetween(
targetLat,
targetLon,
currentLatitude,
currentLongitude,
results);
Log.i("DIST", Integer.toString(Math.round(results[0])));
*/
addButton.setText(tmp[2] + " (" + tmp[3] + " mi)");
addButton.setId(2000 + i);
addButton.setTag(btnStrings[i]);
addButton.setGravity(Gravity.LEFT);
addButton.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
addButton.setOnClickListener(getOnClickDoSomething(addButton));
if(added.indexOf("||" + btnStrings[i]) < 0) {
resultsLayout.addView(addButton);
added += "||" + btnStrings[i] + "||";
}
//btnHolders[Math.round(results[0] * 0.000621371192f)][i] = addButton;
//btnResults[i] = addButton;
Log.i("ADDED", "TMP 2: " + tmp[2]);
} catch (Exception e) {
Log.i("TIME", "EXCEPTION: " + e.getMessage());
}
}
done = true;
return true;
}
public Runnable getTaps = new Runnable() {
public void run() {
try {
URL url = new URL("http://fltapmap.com/search-results.php?loc=" + location[1] + "," + location[0] + "&from=android&s=" + searchBox.getText().toString().replace(" ", "%20"));
Log.i("Time", "Bout to query: http://fltapmap.com/search-results.php?loc=" + location[0] + "," + location[1] + "&from=android&s=" + searchBox.getText().toString().replace(" ", "%20"));
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
in = new BufferedInputStream(urlConnection.getInputStream());
Integer cnt = 0;
try {
BufferedReader r = new BufferedReader(new InputStreamReader(in));
String line;
total = "";
while ((line = r.readLine()) != null) {
Log.i("Bar", "A Line:" + line);
total += line.replaceAll("\\<.*?\\>", "").replaceAll("\n", "");
Log.i("Bar", total);
cnt++;
}
total += "<br /><br /><br /><br />";
urlConnection.disconnect();
} catch (IOException ioe) {
Log.i("Bar", ioe.getMessage());
urlConnection.disconnect();
}
} catch (IOException ioe) {
Log.i("Bar", ioe.getMessage());
urlConnection.disconnect();
}
}
catch(MalformedURLException ioex){
Log.i("Bar", ioex.getMessage());
}
done = true;
}
};
}
<?php
/*
Allow buyers to search material based on fiber type, dimensions and standards.
I do not understand the data at all it was pulled from an MSSQL database and I was asked to replicate the search.
I will do my best to explain the logic below, I wrote this code a while back
*/
global $wpdb;
/* Users have a few options to search, the first option Fiber Type populates a secondary select field Architecture.
Fiber is always required so we start by checking it's set then preppering our variables for output and queries
Architecture is optional so our first search results we may filter later are the fiber ones. I could filter here
but I try to avoid large JOIN sql queries because they can get very complicated and confusing very quick
*/
if( isset( $_GET['byfiber'] ) ) {
//prepare output for cleanup
$allowedhtml = array(
'h1' => array(),
'p' => array(),
'br' => array(),
'span' => array(),
'table' => array(),
'tr' => array(),
'th' => array(
'width' => array(),
'style' => array()
),
'td' => array(),
'a' => array(
'href' => array()
)
);
$sql = '';
$mkey = '';
$wc = array();
$cposts = array();
$sqltable = 'SELECT * FROM $wpdb->postmeta pm WHERE pm.post_id="0"';
//The fiber types were not coded in a way with the select form and database that made sense
//so I had to test each option or combo of options based on original search form I didn't build
if( $_GET['ddFiberTypes'] == 'A' ) {
$cat_id = 33; // The category id to select
$sql = "SELECT p.id, p.post_title, p.comment_count
FROM $wpdb->posts p
JOIN $wpdb->term_relationships tr ON ( p.ID = tr.object_id )
JOIN $wpdb->term_taxonomy tt ON ( tr.term_taxonomy_id = tt.term_taxonomy_id )
JOIN $wpdb->terms t ON ( tt.term_id = t.term_id )
WHERE p.post_type='post'
AND p.post_status = 'publish'
AND tt.taxonomy = 'category'
AND t.term_id = $cat_id";
$wc = $wpdb->get_results( $wpdb->prepare( $sql ) );
}
if( $_GET['ddFiberTypes'] == 'K' || $_GET['ddFiberTypes'] == 'KE' ) {
$cposts = $wpdb->get_results( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta pm WHERE pm.meta_key='Aramid-E-glass' AND pm.meta_value='yes'" ) );
$sql = 'SELECT p.id, p.post_title FROM $wpdb->posts p WHERE p.id=0';
foreach( $cposts as $apost ) {
$sql .= ' OR p.id=' . intval( $apost->post_id );
}
$wc = $wpdb->get_results( $wpdb->prepare( $sql ) );
}
if( $_GET['ddFiberTypes'] == 'KEC' ) {
$sql = "SELECT p.id, p.post_title, p.comment_count
FROM $wpdb->posts p
JOIN $wpdb->postmeta pm ON ( pm.meta_key = 'Aramid-E-glass' AND p.ID = pm.post_id )
JOIN $wpdb->postmeta em ON ( em.meta_key = 'E-Glass' AND p.ID = em.post_id )
JOIN $wpdb->term_relationships tr ON ( p.ID = tr.object_id )
JOIN $wpdb->term_taxonomy tt ON ( tr.term_taxonomy_id = tt.term_taxonomy_id )
JOIN $wpdb->terms t ON ( tt.term_id = t.term_id )
WHERE p.post_type='post'
AND p.post_status = 'publish'
AND tt.taxonomy = 'category'
AND t.term_id = $cat_id
AND ( pm.meta_value='yes'
OR em.meta_value='yes' )";
$wc = $wpdb->get_results( $wpdb->prepare( $sql ) );
}
if( $_GET['ddFiberTypes'] == 'C' ) {
$cposts = $wpdb->get_results( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta pm WHERE pm.meta_key='Carbon' AND pm.meta_value='yes') );
$sql = "SELECT p.id, p.post_title FROM $wpdb->posts p WHERE p.id=0";
foreach( $cposts as $apost ) {
$sql .= ' OR p.id=' . $apost->post_id;
}
$wc = $wpdb->get_results( $wpdb->prepare( $sql ) );
}
if( $_GET['ddFiberTypes'] == 'E' ) {
$cposts = $wpdb->get_results( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta pm WHERE pm.meta_key='E-Glass' AND pm.meta_value='yes'" ) );
$sql = "SELECT p.id, p.post_title FROM $wpdb->posts p WHERE p.id=0";
foreach( $cposts as $apost ) {
$sql .= ' OR p.id=' . $apost->post_id;
}
$wc = $wpdb->get_results( $wpdb->prepare( $sql ) );
}
/* Now we have results in WC of fiber selection and we need to filter based on secondary option
which again had a strange relation from original form input and actual data in database */
$all_architecture = '';
$subcat = explode( '|SP|', $_GET['SubCat'] );
if( $_GET['SubCat'] != '0' ) {
$all_architecture = $wpdb->get_results( $wpdb->prepare( "SELECT pm.post_id, pm.meta_value FROM $wpdb->postmeta pm WHERE pm.meta_key='Architecture'" ) );
foreach( $all_architecture as $apost ) {
if( str_replace( ' ', '', $apost->meta_value ) == str_replace( ' ', '', $subcat[1] ) ) {
$all_architecture .= '||' . $apost->post_id . '||';
}
}
}
//third search option (optional) is the series, form structure strange again so I have to test each option individually
$all_series = '';
$ddSeries = $_GET['ddSeries'];
if( $_GET['ddSeries'] == '1' ) {
$ddSeries = 'LaborSaver';
}
if( $_GET['ddSeries'] == '9' ) {
$ddSeries = 'Vector60';
}
if( $_GET['ddSeries'] == '2' ) {
$ddSeries = 'VectorFusion';
}
if( $_GET['ddSeries'] == '3' ) {
$ddSeries = 'VectorMat';
}
if( $_GET['ddSeries'] == '5' ) {
$ddSeries = 'VectorSports';
}
if( $_GET['ddSeries'] == '4' ) {
$ddSeries = 'VectorUltra';
}
if( $_GET['ddSeries'] == '10' ) {
$ddSeries = 'VectorWind';
}
//ok, they want series option to, let's filter those
if( $ddSeries != '0' ) {
$all_series = $wpdb->get_results( $wpdb->prepare( "SELECT pm.post_id, pm.meta_value FROM $wpdb->postmeta pm WHERE pm.meta_key='$ddSeries'" ) );
foreach( $all_series as $apost ) {
if( $apost->meta_value == 'yes' ) {
//I'm sure there's a better way to do this but was getting overwhelmed, went old fashion for now to get functioning
$all_series .= '||' . $apost->post_id . '||';
}
}
}
//Now we find the posts with the custom fields that were correct for our search
foreach( $wc as $result ) {
$sqltable .= ' OR pm.post_id=' . $result->id ;
}
$all_meta = $wpdb->get_results( $wpdb->prepare( $sqltable ) );
$sort_meta = array();
foreach( $all_meta as $am ) {
$sort_meta[$am->post_id][$am->meta_key] = $am->meta_value;
}
//Results!!
echo wp_kses( '<table><tr><th width="125px" style="width:125px;"></th><th>Total Weight ( OZ )</th><th>Total Weight ( G )</th><th>0&deg; Longitudinal ( OZ )</th><th>0&deg; Longitudinal ( G )</th><th>90&deg; Transverse ( OZ )</th><th>90&deg; Transverse ( G )</th>', $allowedhtml );
echo wp_kses( '<th>+\-45&deg; Double Bias ( OZ ) 60&deg; Fore-TLY & E-TLYA</th><th>+\-45&deg; Double Bias ( G ) 60&deg; Fore-TLY & E-TLYA</th><th>Binderfree Mat ( OZ )</th><th>Continuous Filament Mat ( OZ ) Or Micromesh &trade;</th>', $allowedhtml );
echo wp_kses( '<th>Polyester Veil ( OZ )</th><th>A Glass Veil ( OZ )</th><th>Dry Fiber Thickness ( IN )</th><th>Dry Fiber Thickness ( MM )</th><th>Laminated Thickness ( IN )</th><th>Laminated Thickness ( MM )</th><th>Lloyds Approval</th><th>DNV Approval</th></tr>', $allowedhtml );
foreach( $wc as $result ) {
$addit = true;
if( $subcat == '0' && $ddSeries == '0' && !isset( $_GET['bs'] ) ) {
echo wp_kses( '<tr><td><a href='' . wp_get_attachment_url( $sort_meta[$result->id]['pdf_file'] ) . ''>' . $result->post_title . '</a>', $allowedhtml );
} else {
if( strpos( $all_architecture, '||' . $result->id . '||' ) === false && $_GET['SubCat'] != '0' ) {
$addit = false;
}
if( strpos( $all_series, '||' . $result->id . '||' ) === false && $ddSeries != '0' ) {
$addit = false;
}
if( isset( $_GET['bs'] ) ) {
$typ = explode( ',', $_GET['bs'] );
if( array_search( explode( '-', $result->post_title )[1], $typ ) === false ) {
$addit = false;
}
}
if( $_GET['SubCat'] != '0' ) {
if( strpos( $result->post_title, $subcat[0] . '-' ) === false ) {
$addit = false;
}
}
if( $addit ) {
echo wp_kses( '<tr><td><a href="' . wp_get_attachment_url( $sort_meta[$result->id]['pdf_file'] ) . '">' . $result->post_title . '</a>', $allowedhtml );
}
}
if( $addit ) {
echo wp_kses( '</td><td>' . $sort_meta[$result->id]['total_weight_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . intval( intval( $sort_meta[$result->id]['total_weight_oz'] )*28.3495 ) . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['0_long_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . intval( intval( $sort_meta[$result->id]['0_long_oz'] )*28.3495 ) . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['90_trans_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . intval( intval( $sort_meta[$result->id]['90_trans_oz'] )*28.3495 ) . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['pm_45_double_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . intval( intval( $sort_meta[$result->id]['pm_45_double_oz'] )*28.3495 ) . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['binderfree_mat_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['cont_fil_mat_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['poly_veil_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['a_glass_veil_oz'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['dry_fib_thick_in'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . round( floatval( $sort_meta[$result->id]['dry_fib_thick_in'] )*25.4,3 ) . '</td>', $allowedhtml );
echo wp_kses( '<td>' . $sort_meta[$result->id]['lam_thick_in'] . '</td>', $allowedhtml );
echo wp_kses( '<td>' . round( floatval( $sort_meta[$result->id]['lam_thick_in'] )*25.4,3 ) . '</td>', $allowedhtml );
if( $sort_meta[$result->id]['lloyd'] == '1' ) {
echo wp_kses( '<td>yes</td>', $allowedhtml );
} else {
echo wp_kses( '<td></td>', $allowedhtml );
}
if( $sort_meta[$result->id]['dnv'] == '1' ) {
echo wp_kses( '<td>yes</td>', $allowedhtml );
} else {
echo wp_kses( '<td></td>', $allowedhtml );
}
}
}
echo wp_kses( '</table>', $allowedhtml );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment