Posted on 4 Comments

Writing A Real Time Location Service – Routes and Controller Logic

Routes and Controllers

If you are following along from the previous tutorial then you should have the following page implemented on the front end:

Home screen
Your screen should look like this

In this part of the tutorial I will show you how to implement the routes and the back-end controller logic. The application has two main controllers that I will be implementing:

  • ActivationController for registering and activating new devices
  • LocationController for storing and broadcasting GPS locations

but before we get into that let’s first create our routes, open up the routes/web.php file and replace the contents with this:


<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index');
/* Commands */
Route::group(['prefix' => 'command','middleware' => 'auth'], function(){
Route::get('start-gps', 'LocationController@startGps');
Route::get('stop-gps','LocationController@stopGps');
});
/* Activation */
Route::group(['prefix' => 'activation','middleware' => 'auth'], function(){
Route::get('/','ActivationController@getView');
Route::post('/','ActivationController@activateDevice');
Route::post('/register','ActivationController@registerDevice');
});ro

 
and open up routes/api.php and replace the contents with this:


<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::resource('location','LocationController')

 
You may be wondering why I am editing two separate route files and the reason being is becasue the routes/api.php file is what the Android application will be interacting with and it’s just good practice to keep API code separate from main code. As you can see there are two route groups one for activation and one for commands. In the commands group I have a start-gps and a stop-gps route. These are going to do what their name implies and instruct the Android device to either start sending GPS data to the server, or to stop it. Next in the activation group there is a get route / to return the activation view, and a post route  / to activate the device, lastly there is a post route to register a new device. Basically the Android device will call register when the app opens for the first time, this will generate a code that the user has to enter at the activation screen to give the web app permission to start collecting data anonymously. The routes/api.php file has a resourceful route called location that will call the CRUD functions on the LocationController, although right now I am only implementing the store() function (gotta give you guys SOME homework). If you run php artisan route:list in your terminal you should see the following routes:

 +--------+-----------+------------------------------+------------------+------------------------------------------------------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+------------------------------+------------------+------------------------------------------------------------------------+------------+ | | GET|HEAD | / | | Closure | web | | | POST | activation | | App\Http\Controllers\ActivationController@activateDevice | web,auth | | | GET|HEAD | activation | | App\Http\Controllers\ActivationController@getView | web,auth | | | POST | activation/register | | App\Http\Controllers\ActivationController@registerDevice | web,auth | | | GET|HEAD | api/location | location.index | App\Http\Controllers\LocationController@index | api | | | POST | api/location | location.store | App\Http\Controllers\LocationController@store | api | | | GET|HEAD | api/location/create | location.create | App\Http\Controllers\LocationController@create | api | | | PUT|PATCH | api/location/{location} | location.update | App\Http\Controllers\LocationController@update | api | | | GET|HEAD | api/location/{location} | location.show | App\Http\Controllers\LocationController@show | api | | | DELETE | api/location/{location} | location.destroy | App\Http\Controllers\LocationController@destroy | api | | | GET|HEAD | api/location/{location}/edit | location.edit | App\Http\Controllers\LocationController@edit | api | | | GET|HEAD | command/start-gps/{id} | | App\Http\Controllers\LocationController@startGps | web,auth | | | GET|HEAD | command/stop-gps/{id}| | App\Http\Controllers\LocationController@stopGps | web,auth | | | GET|HEAD | home | | App\Http\Controllers\HomeController@index | web,auth | | | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest | | | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest | | | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web | | | POST | password/email | | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web,guest | | | POST | password/reset | | App\Http\Controllers\Auth\ResetPasswordController@reset | web,guest | | | GET|HEAD | password/reset | | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest | | | GET|HEAD | password/reset/{token} | | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web,guest | | | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest | | | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest | +--------+-----------+------------------------------+------------------+------------------------------------------------------------------------+------------+

Implementing The Controller

If you haven’t already created the controllers, please do so with the following commands:
php artisan make:controller LocationController
php artisan make:controller ActivationController
Let’s start with the ActivationController, open up app/Http/Controllers/ActivationController.php. This controller only has three functions getView(), activateDevice(), and registerDevice(), I described their functions above so instead of repeating myself I will post the code:

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\ActivationCode; use App\Device; class ActivationController extends Controller {  //  public function getView(){  return view('activation');  } public function activateDevice(Request $request){  $code = ActivationCode::where('code', $request->code)->first();  if ($code != null){  $device = Device::create([  'user_id' => $request->user()->id,  'uuid' => $code->uuid  ]);  }  return redirect('/home');y  } public function registerDevice(Request $request){  $code = ActivationCode::Create([  'uuid' => $request->uuid,  'code' => $request->code  ]);  } }

You may be wondering where the uuid and code is coming from. This uuid and the code are generated on the Android device when the app is opened for the first time. This uuid is what maps the app to each device, while the code is shown to the user on the android device they then have to enter that code on the activation page to activate the device and start collecting data. The devices also listens on a Socket.IO channel that corresponds to their uuid so this is how we will talk to the Android devices. Next open up the LocationController and enter the following contents:

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Location; use App\Device; class LocationController extends Controller {  // public function startGps($id){  $device = Device::findOrFail($id);  event(new \App\Events\SendCommand($device,'start-gps'));  } public function stopGps($id){  $device = Device::findOrFail($id);  event(new \App\Events\SendCommand($device,'stop-gps'));  }ns  public function store(Request $request){  $device = Device::where('uuid', $request->uuid)->first();  $location = Location::Create([  'long' => $request->long,  'lat' => $request->lat,  'device_id' => $device->id  ]);  event(new \App\Events\LocationCreated($location));  } }be i

All three of these functions are relying on Laravel events because they will be interacting with sockets, however we will actually be implementing the event logic in the next tutorial. Right now just understand that the sendCommand event will be responsible for telling the Android device to start or stop the GPS transponder and the LocationCreated event will tell the web browser the GPS coordinates in real time.
 

Conclusion

At this stage of the application you should have your front end logic complete and the controllers that power the back end. The last thing that has to be completed on the web end is the event and socket logic. If you haven’t already please subscribe not only to this blog but also my Youtube page (links to both on the right sidebar). Please leave any questions in the comment section below, and be sure to check the source code here.

Posted on Leave a comment

Jyrone Parker Live – Intro To Databases

[info]Check out the shop! [/info]

Intro To Databases

This live stream focuses on databases. A database is a container of imformation of sorts. It is what allows websites to be dynamic instead of static. Learn how to create a database, how to add tables to the database, how to update data in the database and how to delete data out of the database.
This stream is significant because it signifies the last beginner PHP live stream. Going forward we are creating PHP projects and building upon our knowledge set. Then I will go on and teach you guys some HTML/CSS/Javascript and move on to the Laravel framework.
As always if you haven’t yet subscribe to this blog using the widget on the right (bottom if on mobile) to get the latest updates from me.

Posted on Leave a comment

Jyrone Parker Live – Exceptions/Error Handling

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]
 

Exceptions and Error Handling

Continuing in the PHP tutorials I am showing you how to throw exceptions and handle errors in PHP. Often times when you are building software you have to account for when things go wrong. To ensure the best experience for your user, you want the application to gracefully handle those errors instead of crashing and leaving the user quizzically stumped. This is where exceptions come in. If you account for the cases where things might break and throw an exception then you can use the try/catch  control structure to catch said exceptions and handle them accordingly. A quick example is such:


<?php
function getRandomRange($min,$max){
if($min < 0){
throw new Exception("Min must be greater than 0");
}
if($max > 10000){
throw new Exception("Max must be less than 10000");
}
return rand($min,$max);
}
try{
/*
php exceptions.php $mix $max
*/
echo getRandomRange($argv[1],$argv[2]) . "\n";
}
catch(Exception $e){
echo $e->getMessage()."\n";
}
?>

Exceptions are part of the global PHP namespace and you can even create your own version on an exception that extends from the Exception class. If you didn’t get a chance to watch my live stream on the subject I talk about it more in depth, you can find it below
[youtube width=”100%” height=”100%” autoplay=”false”]https://www.youtube.com/embed/IkWK3qZ5Ix4[/youtube]

Posted on 3 Comments

Writing A Real Time Location Service – Views and Front End Logic

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Views

Thanks to the scaffolding done in the initial project setup, our login and registration views are already created, we just need to modify the home page and add a new page for device registration. Le’t create the activation view first, copy the home.blade.php file and name it activation.blade.php. This view will only have one form for taking in an activation code from an Android device replace the current contents with the following:


@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Activate Device</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/activate') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Code</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="code" value="{{ old('code') }}" required autofocus>
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('activate') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Activate
</button>
</div>
</div>
</form>.
</div>
</div>
</div>
</div>
</div>
@endsection

Don’t worry that the route hasn’t been created yet, we will get to that in a bit. In the mean time open up the home.blade.php file, this file is where the majority of the seen action is going to happen.  In this view the user will see a list of their devices with options to either start tracking GPS, stop tracking GPS, or delete the device. There is a Google map that will be used to show the position of the device and it will be updated in real time.


@extends('layouts.app')
@section('content')
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
#map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
<table class="table">
<tbody>
@foreach(auth()->user()->devices as $device)
<tr>
<td>{{$device->uuid}}</td>
<td>
<button data-id="{{$device->id}}" class="btn btn-sm btn-default action-start-gps" id="start-gps"><i class="fa fa-map-marker" aria-hidden="true"></i></button>
<button data-id="{{$device->id}}" class="btn btn-sm btn-warning action-stop-gps" id="stop-gps"><i class="fa fa-map-marker" aria-hidden="true"></i></button>
<form method="post" action="/device/{{$device->id}}">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<button data-id="{{$device->id}}" type="submit" class="btn btn-sm btn-danger" id="delete"><i class="fa fa-close" aria-hidden="true"></i></button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Map</div>
<div class="panel-body">
<div id="map"></div>
</div>
</div>
</div>
</div>
</div>
<script>
var startGps = document.getElementsByClassName("action-start-gps");
var stopGps = document.getElementsByClassName("action-stop-gps");
for (var i = 0; i < startGps.length; i++) {
startGps[i].addEventListener('click', function(){
$.get("http://gps.app/command/start-gps/" + $(this).data('id'), function(data, status){
}, false);
});
}
for (var i = 0; i < stopGps.length; i++) {
stopGps[i].addEventListener('click', function(){
$.get("http://gps.app/command/stop-gps/" + $(this).data('id'), function(data, status){
}, false);
});
}
function initMap(lat,long) {
var uluru = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 20,
center: uluru,
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
var socket = io.connect('http://gps.app:6001');
socket.on('gps', function (data) {
var center = {lat:Number(data.data.gps.lat),lng:Number(data.data.gps.long)};
@foreach(auth()->user()->devices as $device)
socket.on({{$device->id}}, function(data){
console.log(data);
});
@endforeach
marker.setPosition(center);
// using global variable:
map.panTo(center);
})
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBCDNt1biVyfA8h-eCZyZ69CKS6NNBCeEQ&callback=initMap">
</script>
@endsection

Home screen
Your screen should look like this

This is where the majority of the magic happens in the home view there are two divs. In the first div all of the associate devices will be shown in a tabular format with options to start GPS tracking, stop GPS tracking, and deleting the associated device. In the second div there is a Google map that will be used to visualize our devices (in order to use Google map services you must register for a key). The javascript code calls the routes needed to start and stop GPS tracking, as well as the Socket.IO code needed to update the Google map in real time ( for those who don’t know Socket.IO please refer here). Let’s take a closer look at the Socket.IO code and understand what is going on. When new data comes through the websocket channel, the marker’s latitude and longitude are updated and the map is recentered all without a page reload. With this bagged up the next step is to set up the routes and controller logic!

Posted on Leave a comment

Jyrone Parker Live – More Data Types, Flow Control Logic, File I/O

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Three Days In!

Three days in three live streams! In today’s live stream I go over the last couple data types, arrays and closures. Array hold a collection of items such as an array of grocery prices, or an array of color codes. They can be either single dimensional or multi dimensional and they can also be associative. Some examples of arrays include:


$x = [1,2,3,4,5];
$y = [
"favorite_food" => "Fried Chicken",
"favorite_spice" => "Hot Sauce"
];
$z = [
"data" => [
"result" => 1,
"error_code" => 502
],
"message" => "Hello"
];
// Access arrays
echo $x[0]; // first element in array
echo $y["favorite_food"];//access by name
echo $z["data"]["result"]; // accessing multidimensional array elements

Flow Control Logic

I also went over control flow logic. Many times in your application you are going to need to take certain actions based on certain actions the three basic flow control structures are: if/else statements, loops, and switch statements, some examples are as follows.


//if/else statment
if($x[0] % 2){
echo "Even";
}
else{
echo "Odd";
}
//while loop
while($x == true){
echo "Running....";
}
for($i = 0; $i<count($x); ++$i){
echo $x[$i];
}
foreach($x as $key=>$value){
echo $value;
}
 
switch($car->getMake()){
case 'Hyundai':
echo "Hyundai";
break;
case "Ford":
echo "Ford";
break;
default:
echo "IdK";
break;
 
}

 

File I/O

Lastly I went over file input/output including opening files and closing files:


$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
$txt = "Jane Doe\n";
fwrite($myfile, $txt);
fclose($myfile);

Don’t forget to subscribe to my YouTube channel and to subscribe to this blog to learn more!

Posted on Leave a comment

Jyrone Parker Live – Setting Up Homestead, Basic Linux Commands, Intro To PHP

The Time Has Finally Come

In my last video I gave a general overview of what coding is, its pitfalls as well as its rewards. Today I am briskly walking you guys through installing Laravel Homestead, the environment that all of our web development is going to be done on. I am also going over some basic Linux commands as well. Lastly I walk you guys through the basics of PHP, the backend language that will be powering our web applications. Don’t forget that I live stream everyday Mon – Fri @ 6 PM EST, you can join the conversation and ask me questions in real time! If you enjoy my content please subscribe to my blog and to my YouTube channel to stay up to date on my content.

Posted on 3 Comments

Jyrone Parker Live – What Is Coding

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Today Marks An Historic Moment

Today I started my daily live stream on YouTube every day @ 6 PM EST I will spend an hour doing a live talk show. Every day will  be a different focus, some days I will do interviews with tech professionals, somedays I will do live coding sessions so you guys can see what apps I am working on (games too), the rest of the time will be spent doing programming video tutorials. This is not a replacement of my blog, but an extension of it. In today’s episode I went over what it means to code, some of the challenges to being a software developer, some of the rewards of being a software developer, a little about me and what I have going on. No actual coding during this initial pilot episode, that’s all going to change tomorrow, as I go into the basics of web development, setting up the virtual machine environment, learning some basic Linux commands and writing our first PHP program.

From N00b To Artisan

I have been working on my first eBook titled “From N00b To Artisan: Learning Laravel 5.4 With 5 projects” this is a guide for anyone who is new to Laravel (and web development in general) and gets them up to speed. While I am still pursuing this I have decided to give away the video series away for free on my YouTube channel. If you don’t want to miss out on this incredible opportunity please subscribe to my YouTube channel. I plan on having the eBook finished by the summer.

Conclusion

Not going to lie, this live streaming thing is going to take a minute to get used to! I hope this content helps those who need it the most! Remember your participation during live streams are vital to the content that’s provided tune in EVERY MON-FRI @ 6 PM EST. Please subscribe to my YouTube channel, subscribe to my newsletter, and please share it with your friends, family, and colleagues who could use this valuable and free information!

Posted on Leave a comment

Create A URL Shortener In Laravel 5.4

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Laravel 5.4 Is Out!

To commemorate such I am rewriting old tutorials in Laravel 5.4. I also signified this release as the time to start my live stream (subscribe to my channel here). I created a live coding video and uploaded it to my channel, but you can watch it here.

What’s Does The App Do?

This is a simple URL shortener. Paste the URL you want to shorten into the generator and it spits out a shortened URL that maps to the longer one. This app is similar to bit.ly

Posted on Leave a comment

All Around Politics

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

First App 2017

This last presidential election was something else wasn’t it? Besides the #noChill memes and jaw dropping comments, I noticed a good deal of people spewed their opinions without any substantial evidence to back up their claims! Now the old me would normally not care, but my wife has a political science degree and has sparked a hidden love of politics in me. One night after the election her and I were having a talk about this when she inspired me to create my first app of 2017, All Around Politics. All Around Politics in a news aggregator that only focuses on one thing, political news articles. The platform gathers political news article from left, center, and right wing sources, to give users and fair , balanced, and reliable political news. It also features push notifications for breaking news articles. Currently there is a web app and an android app, the iOS version will be finished soon and this article will be updated to reflect the link. If you sign up for an account on the web site then you will get daily emails with the latest headlines where as if you download the Android (soon iOS as well) app then you will get push notifications with the latest headlines. This app is perfect for those who would like to stay in the know in American and world politics, but doesn’t want to search multiple sources independently. The app is robust and directly links to original sources so there is no miscommunication of information. My hope is that you guys will check it out either via the web address or the mobile app. Please leave comments letting me know your thoughts on the app, and if you can spare the time please write a review on the Google play store, that will help promote the app.