Android – Get current location of user by using LocationManager API

Sometimes we need to get user current location from Android device. Its very simple while we use LocationManager API of Android. We just need a custom location manager and a location listener with  necessary permission in Manifest.xml file.  lets see how to do it.

Step-1: Follow the code in manifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.previewtechs.bornolipi">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-feature android:name="android.hardware.location.gps" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme.NoActionBar">
        <activity android:name=".MainActivity" />

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

  
        <activity android:name=".HomeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
</manifest>

Step-2: Follow these code for TestLocationManager.Java

public class TestLocationManager {

private int minDistanceForUpdateLocation;
private int minTimeForUpdateLocastion;
LocationManager locationManager;
TestLocationListener locationListener;
Context ctx;
private boolean isGPSProviderEnable, isNetworkProviderEnable;

//COnstructor
public TestLocationManager(Context ctx){
this.ctx = ctx;
}

public TestLocationManager(Context ctx, int minTimeForUpdateLocastion, int minDistanceForUpdateLocation ){
this.minDistanceForUpdateLocation =minDistanceForUpdateLocation;
this.minTimeForUpdateLocastion= minTimeForUpdateLocastion;
this.ctx = ctx;
}

//Set Location Manager and Listener
public void setLocationManagerAndListener(){
this.locationListener = new TestSendLocationListener(this.ctx);
this.locationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);

isGPSProviderEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkProviderEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

if(isGPSProviderEnable){
this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTimeForUpdateLocastion, minDistanceForUpdateLocation, locationListener);
}else if(isNetworkProviderEnable){
this.locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTimeForUpdateLocastion, minDistanceForUpdateLocation, locationListener);
}

}

//Get Minimum Distance for updating location
public int getMinDistanceForUpdateLocation() {
return minDistanceForUpdateLocation;
}
//Set Minimum Distance for updating location
public void setMinDistanceForUpdateLocation(int minDistanceForUpdateLocation) {
this.minDistanceForUpdateLocation = minDistanceForUpdateLocation;
}

//Get Minimum Time for updating location
public int getMinTimeForUpdateLocastion() {
return minTimeForUpdateLocastion;
}

//Set Minimum Time for updating location
public void setMinTimeForUpdateLocastion(int minTimeForUpdateLocastion) {
this.minTimeForUpdateLocastion = minTimeForUpdateLocastion;
}
}

Step:3- Follow these code for TestLocationListener.java

public class TestLocationListener implements LocationListener {

private double lat, lng, alt, acc, time;
Context ctx;
ConnectivityDetector connectivityDetector;

public TestLocationListener(Context ctx){
this.ctx = ctx;
}

@Override
public void onLocationChanged(Location location) {
this.lat = location.getLatitude();
this.lng = location.getLongitude();
this.alt = location.getAltitude();
this.acc = location.getAccuracy();
this.time = location.getTime();

Toast.makeText(ctx, “Lat : “+this.lat+” \n Lng : “+this.lng+” \nAlt : “+this.alt+” \n Acc : “+this.acc+” \n Time : “+this.time, Toast.LENGTH_LONG).show();

//to whatever you want with location

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}
}

Step:4 – There is the code for MainActivity.java . where we will implement our TesetLocationManager and TestLocationListener .

public class MainActivity extends AppCompatActivity{

    private Toolbar toolbar;
    private Location mLastLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

 // setup toolbar
 toolbar = (Toolbar) findViewById(R.id.toolbar);
 setSupportActionBar(toolbar);


 navigationView = (NavigationView) findViewById(R.id.menu_main);
 navigationView.setNavigationItemSelectedListener(this);
 //Set default item selected on nivigation
 navigationView.getMenu().performIdentifierAction(R.id.menu_home, 0);
 setTitle("");

 //get real time permission for location
 getPermissionForLocation();
 }

 protected void onStart() {
 super.onStart();
 }

 protected void onStop() {
 super.onStop();
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 switch (requestCode) {
 case ConstantCollection.PERMISSION_REQUEST_LOCATION_COARSE: {
 // If request is cancelled, the result arrays are empty.
 if (grantResults.length > 0
 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
 Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_LONG).show();

 //setup location manager and listener
 setupLocationManagerAndListener();

 //get last known location
 //mLastLocation = getUserLocation();
 //storeUserLocation(mLastLocation);


 } else {
 MainActivity.this.finish();
 Toast.makeText(getApplicationContext(), "Permission denied! You must have to allow this permission", Toast.LENGTH_LONG).show();
 }
 return;
 }
 }
 }


 //Check Permission and get call log list
 private void getPermissionForLocation() {
 // Here, thisActivity is the current activity
 if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)
 != PackageManager.PERMISSION_GRANTED
 && ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
 != PackageManager.PERMISSION_GRANTED) {

 // Should we show an explanation?
 if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
 Manifest.permission.ACCESS_COARSE_LOCATION) ||
 ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
 Manifest.permission.ACCESS_FINE_LOCATION)) {

 // Show an expanation to the user *asynchronously* -- don't block
 // this thread waiting for the user's response! After the user
 // sees the explanation, try again to request the permission.

 ActivityCompat.requestPermissions(MainActivity.this,
 new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
 ConstantCollection.PERMISSION_REQUEST_LOCATION_COARSE);

 } else {
 // No explanation needed, we can request the permission.
 ActivityCompat.requestPermissions(MainActivity.this,
 new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
 ConstantCollection.PERMISSION_REQUEST_LOCATION_COARSE);

 }
 } else {
 //Check permission for location
 setupLocationManagerAndListener();
 
 }
 }

 //setup location location manager and listener
 private void setupLocationManagerAndListener(){
 TestLocationManager locationManager = new TestLocationManager(MainActivity.this, 10000, 10);
 TestLocationListener locationListener = new TestLocationListener(getApplicationContext());
 locationManager.setLocationManagerAndListener();
 }

}

We can find our expected location on onLocationChanged() method of TestLocationListener.java file. So i think you got your expected result. If you have any question then put it on comment box. Thanks.

RedBeanPHP (The Power ORM)

RedBeanPHP is an easy to use ORM for PHP. It’s a Zero Config ORM lib that ‘automagically’ builds your database schema.

Welcome

RedBeanPHP is an easy to use ORM for PHP. It’s a Zero Config ORM lib that ‘automagically’ builds your database schema.

IMPORTANT! RedBeanPHP 3.5 is approaching EOL status!

After 1 October, RedBeanPHP 3.5 will no longer be supported nor maintained !
If you want to continue to use a maintained version of RedBeanPHP, upgrade to version 4.3!
UPDATE: Due to popular demand, support has been extended until December 2016

News

2016-10-25: RedBeanPHP 4.3.3 has been released !
2016-10-02: RB 3.5 support has been extended until December 2016
2016-05-01: RedBeanPHP 4.3.2 has arrived !
2016-01-09: RedBeanPHP 4.3.1 has been released!
2015-10-01: RedBeanPHP 4.3 has been released!
2015-09-11: RedBeanPHP 4.3 beta 2 has been released!
2015-09-02: RedBeanPHP 4.3 Beta 1 has been released!
2015-07-29: RedBeanPHP 4.2.5 has been released!

 

Code Example

This is how you do CRUD in RedBeanPHP:

    require 'rb.php';
R::setup();
R::setAutoResolve( TRUE );        //Recommended as of version 4.2
$post = R::dispense( 'post' );
$post->text = 'Hello World';
$id = R::store( $post );          //Create or Update
$post = R::load( ‘post’, $id );   //Retrieve
R::trash( $post );                //Delete

This automatically generates the database, tables and columns… on-the-fly. It infers relations based on naming conventions. RedBeanPHP is written by BDFL Gabor de Mooij and the RedBeanPHP community.

Zero Config

No verbose XML files, no annoying annotations, no YAML or INI. Zero Config. Just start coding.

Fluid Schema

During development, RedBeanPHP will adapt the database schema to fit your needs, giving you the NoSQL experience. When deploying to production servers, you can freeze the schema and benefit from performance gains and referential integrity.
RedBeanPHP offers the best of both worlds!

Powerful

RedBeanPHP is a compact library yet packed with features: auto-discovery of models, deep copying and smart import features will boost your productivity!
Write less, do more!

Compatible

RedBeanPHP strives to support all ALL Free, Open Source databases.
Currently, RedBeanPHP supports: MySQL, MariaDB, SQLite, PostgreSQL and CUBRID.

Download

Download the easy-to-use one-in-all package, one single file containing the entire RedBeanPHP library! No composer, no auto-loaders, no configuration, just download and run! Go to the download page and download to latest version of RedBeanPHP!

 

CRUD

CRUD stands for Create, Update, Retrieve and Delete. CRUD operations are the core of many web applications.

Working with beans

RedBeanPHP works with beans. Most interactions with the database are accomplished using beans. Beans are used to carry data from and to the database.

Every bean has a type and an ID. The type of a bean tells you which table in the database is used to store the bean. Every type maps to a corresponding table. The ID of a bean is the primary key of the corresponding record.
You can create a new bean by dispensing one.

Create

To create a new bean (of type ‘book’) use:

    $book = R::dispense( 'book' );

You can now add properties:

    $book->title = 'Learn to Program';
$book->rating = 10;

You can also use array notation if you like:

    $book['price'] = 29.99; //you can use array notation as well

and store the bean in the database:

    $id = R::store( $book );

At this point, the bean will be stored in the database and all tables and columns have been created.
The bean will now have an ID, which is also returned for your convenience.

RedBeanPHP will build all the necessary structures to store your data. However custom indexes and constraints have to be added manually (after freezing your web application).

Conventions

You can dispense any type of bean you like, as long as the type name consists of lowercase alphabetical characters:

    $page = R::dispense('page'); //valid

$page = R::dispense( ‘Page’ ); //invalid: uppercase
$page = R::dispense( ‘cms_page’ ); //invalid: _
$page = R::dispense( ‘@#!’ ); //invalid

However dispense also offers some shortcuts:

    $twoBooks = R::dispense( 'book', 2 );

list($book, $page) = R::dispenseAll( ‘book,page’ );
list($book, $pages) = R::dispenseAll( ‘book,page*2’ );

Properties of beans may contain alphanumeric characters and underscores. Camelcased properties will automatically convert to snake_case:

    $book->isSoldOut = TRUE; //is_sold_out
$book->hasISBNCode = TRUE; //has_isbn_code

Retrieve

To load a bean, simply pass the type and ID of the bean you’re looking for:

    $book = R::load( 'book', $id ); //reloads our book

If the bean does not exist an empty bean with ID 0 will be returned.

Update

To update a bean in the database, add or change properties:

    $book->title = 'Learn to fly';
$book->rating = 'good';
$book->published = '2015-02-15';
R::store( $book );

Note that we added a new property ‘published’, RedBeanPHP will add a new column of type ‘date’ for this property. Also, it will widen the ‘rating’ from INTEGER to VARCHAR to support text as well as numbers.

    //Examples of other data types
$meeting->when = '19:00:00'; //Time
$meeting->when = '1995-12-05'; //Date
$photo->created = '1995-12-05 19:00:00'; //Date time
$meeting->place = '(1,2)'; //SPATIAL only works in postgreSQL
$price->amount = '12.37'; //FIXED POINT NUMERIC - MySQL and Postgres
$price->amount = '$25.00'; //MONEY TYPE - Postgres only

If you want a suitable data type of monetary values, use the ‘XX.XX’ format and you’ll get a fixed precision number data field. To make use of Postgres special purpose, currency-aware money data type, prefix the value with a common currency symbol.

You can use R::isoDate() and R::isoDateTime() to generate the current date(time) if you like.

As of RedBeanPHP 4.1 you can also use spatial columns for MySQL, learn more.

RedBeanPHP will dynamically add new columns to your database. It determines the column type to use by looking at the value you are trying to store. For instance, a short text might be stored as a VARCHAR while a large text might be stored as TEXT. Similarly, a boolean value will probably get stored as TINYINT but when you put a float in that property the column will probably be changed to FLOAT or DOUBLE (depending on your database).
Some column types behave differently, for instance if you store a valid ISO formatted date (i.e. 2015-01-01) RedBeanPHP builds a DATE column, but this column will not change. In general, RedBeanPHP tries to adapt the database to your application. If you’re done developing, you can freeze the database using the freeze() function. After that, the database schema will no longer change (because it is very unlikely you want to store something other than a date in a column you filled with perfectly formatted date in the first place).
Note that RedBeanPHP will never throw away columns or ‘shrink’ columns (from TEXT to VARCHAR) to avoid data loss. RedBeanPHP also only manipulates column types it recognizes, so if you change a VARCHAR(255) to a VARCHAR(254) it will leave that column alone, since it no longer recognizes the type. This means that if you customize columns, RedBeanPHP leaves them alone from that point on.
If RedBeanPHP alters the database in a way you don’t like, don’t worry, you can always tune the schema to your liking (just use your database management tool or phpmyadmin), you can even freeze certain tables only.

Delete

To delete a bean:

    R::trash( $book ); //for one bean
R::trashAll( $books ); //for multiple beans

To delete all beans of a certain type:

    R::wipe( 'book' ); //burns all the books!

To destroy the entire database simply invoke the nuclear method (be careful!):

    R::nuke();

Batch

To load a series of beans use:

    $books = R::loadAll( 'book', $ids );

Reload

To quickly reload a bean:

    $bean = $bean->fresh();

Finding Beans

Instead of loading beans, you can also use the find() method to search for beans using certain criteria. Learn how to query beans in RedBeanPHP.

Finding

If you do not know the ID of a bean, you can search for beans using the find method:

    $book  = R::find( 'book', ' rating > 4 ');

The find() method uses good old SQL. No fancy, custom query language — just plain old SQL.

The find operation in this example returns all beans of type book having a rating of four stars or more.

Find and SQL

The following example demonstrates how to use find() with bindings.

    $books = R::find( 'book', ' title LIKE ? ', [ 'Learn to%' ] );

This find operation will return all beans of type ‘book’ having a title that begins with the phrase: ‘Learn to’.

If find() has no results it will return an empty array.

There is no need to use mysql_real_escape. Always use the bindings.
Never use PHP variables in your query!

IN-queries

To use a ‘SELECT-IN’ style query use the R::genSlots function to generate the correct number of ‘?’ slots:

    $promotions = R::find( 'person',
' contract_id IN ('.R::genSlots( $contractIDs ).')',
$contractIDs );

Find One

If you want a single bean instead of an array, use:

    $book  = R::findOne( 'book', ' title = ? ', [ 'SQL Dreams' ] );

If no beans match the criteria, this function will return NULL.

Find All

Use findAll if you don’t want to add any conditions (but you want to order or limit… )

    $books = R::findAll( 'book' );
$books = R::findAll( 'book' , ' ORDER BY title DESC LIMIT 10 ' );

If no beans match your criteria, this function returns an empty array.

Named slots

All find methods: find, findOne and findAll also accept named slots:

    $books  = R::find( 'book', ' rating < :rating ', [ ':rating' => 2 ] );

Besides querying beans, you can also use regular SQL queries.

Cursors (4.2+)

You can also use find with cursors:

    $collection = R::findCollection( 'page', ' ORDER BY content ASC LIMIT 5 ' );
while( $item = $collection->next() ) {
...
}

The advantage of using a cursor is that the entire collection will not be loaded into memory all at once. This is handy for dealing with large bean collections.

Find like (4.2+)

To find a bean matching certain criteria, you can use R::findLike(). The following code returns all flowers that are either yellow OR blue:

    R::findLike( 'flower', [
'color' => ['yellow', 'blue']
], ' ORDER BY color ASC ' );

Note that you can append some SQL here along with bindings.

Find or create (4.2+)

This works like R::findLike() but also creates (and stores) the bean if it does not exist yet…

    $book = R::findOrCreate( 'book', [
'title' => 'my book',
'price' => 50] );

Find Multiple (4.2+)

findMulti() takes a query and turns the result into several bean collections having different types:

    $beans = R::findMulti( 'book,page', '
SELECT book.*, page.* FROM book
INNER JOIN page.book_id = book.id
WHERE book.category = ?
', [ $cat] );

The first parameter of this function lists the types to load, the second parameter is the query, then come the optional query parameter bindings. The result of this operation will be something like:

    array(
'book' => book beans...
'page' => page beans...
)

Besides loading various bean types at once from a query, this method can also restructure them, for instance to ‘put the pages in the book’ use (example of 4th parameter):

    array(array(
'a'       => 'book'
'b'       => 'page'
'matcher' =>  function( $a, $b ) {
return ( $b->book_id == $a->id );
}
'do'      => function( $a, $b ) {
$a->noLoad()->ownPageList[] = $b;
}
));

The fourth parameter of findMulti takes an array containing arrays like the one above. The array in the example tells findMulti how to restructure the pages and the books. First it defines two variables ‘a’ and ‘b’ it then defines a matcher function, telling RedBeanPHP to execute the ‘do’ clause if the book_id of a page matches the id of a page. The ‘do’ clause then puts the page in the pageList of the selected book. While you can specify mappings like this, a better idea might be to write your own set of mapping functions returning structures like this.

Querying

Querying the database manually is also possible with RedBeanPHP. You can use the SQL query functions provided by RedBeanPHP. To execute a query:

    R::exec( 'UPDATE page SET title="test" WHERE id = 1' );

To get a multidimensional array:

    R::getAll( 'SELECT * FROM page' );

The result of such a query will be a multidimensional array:

    Array
(
[0] => Array
(
[id] => 1
[title] => frontpage
[text] => hello
)
...
)

Note that you can use parameter bindings as well:

    R::getAll( 'SELECT * FROM page WHERE title = :title',
[':title' => 'home']
);

To fetch a single row:

    R::getRow( 'SELECT * FROM page WHERE title LIKE ? LIMIT 1',
[ '%Jazz%' ]
);

To fetch a single column:

    R::getCol( 'SELECT title FROM page' );

And finally, a single cell

    R::getCell( 'SELECT title FROM page LIMIT 1' );

To get an associative array with a specified key and value column use:

    R::getAssoc( 'SELECT id, title FROM page' );

In this case, the keys will be the IDs and the values will be the titles. getAssocRow will return complete rows.

In my examples, I like to use the short array notation.
In PHP < 5.4 you’ll have to use the classic array notation:

array( ‘key’ => ‘value’ ).

Get the insert ID (4.2+)

To get the ID after an insert in MySQL/MariaDB compatible databases use:

    R::exec( 'INSERT INTO ... ' );
$id = R::getInsertID();

Converting records to beans

You can convert rows to beans using the convertToBeans() function:

    $sql = 'SELECT author.* FROM author
JOIN club WHERE club.id = 7 ';
$rows = R::getAll( $sql );
$authors = R::convertToBeans( 'author', $rows );

As of version 4.3.2 you can also use: R::convertToBean, without the s, for single rows.

Remember:
There is no need to use mysql_real_escape as long as you use parameter binding.

Besides querying you can also use other database functionality (like transactions) in RedBeanPHP. Learn more about database functions.

How to use queries

Sometimes using a plain query is more efficient than using beans. For instance, consider the following example:

    $books = R::findAll( 'book' );
foreach( $books as $book ) {
echo $book->title;
echo $book->author->name;
foreach( $book->sharedCategoryList as $cat ) {
echo $cat->name;
}
}

Using a plain query this task could be accomplished far more efficiently:

    $books = R::getAll( 'SELECT
book.title AS title,
author.name AS author,
GROUP_CONCAT(category.name) AS categories FROM book
JOIN author ON author.id = book.author_id
LEFT JOIN book_category ON book_category.book_id = book.id
LEFT JOIN category ON book_category.category_id = category.id
GROUP BY book.id
' );
foreach( $books as $book ) {
echo $book['title'];
echo $book['author'];
echo $book['categories'];
}

One of the biggest mistakes people make with ORM tools is to try to accomplish everything with objects (or beans). They forget SQL is a very powerful tool as well. Use SQL if you are merely interested in generating reports or lists.

Insert data from CSV file in PHP with PDO

<?php

// Database Connection
$hostname = "localhost";
$username = "root";
$password = "mf2312";

try {
    $db = new PDO("mysql:host=$servername;dbname=csvtest", $username, $password);
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}




// Create  CSV to Array function

function csvToArray($filename = '', $delimiter = ',')
{
    if (!file_exists($filename) || !is_readable($filename)) {
        return false;
    }

    $header = NULL;
    $result = array();
    if (($handle = fopen($filename, 'r')) !== FALSE) {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
            if (!$header)
                $header = $row;
            else

                $result[] = array_combine($header, $row);
        }
        fclose($handle);
    }


    return $result;
}




// Insert data into database   

    $all_data = csvToArray('files/testcsv.csv');
    foreach ($all_data as $data) {

        $sql = $db->prepare("INSERT INTO students (name, roll, department) 
        VALUES (:name, :roll, :department)");
        $sql->bindParam(':name', $data['name']);
        $sql->bindParam(':roll', $data['roll']);
        $sql->bindParam(':department', $data['department']);
        $sql->execute();

    }

Slim is a micro framework for PHP

Slim is a micro framework for PHP . We can build quickly powerful web applications and APIs. Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response.

Slim is an ideal tool to create APIs that consume, repurpose, or publish data. Slim is also a great tool for rapid prototyping. Heck, we can even build full-featured web applications with user interfaces. More importantly, Slim is super fast and has very little code. In fact, we can read and understand its source code in only an afternoon!

 

First, we need a web server like Apache. We should configure our web server  so that it sends all appropriate requests to one “front-controller” PHP file. We instantiate and run our Slim app in this PHP file.

A Slim app contains routes that respond to specific HTTP requests. Each route invokes a callback and returns an HTTP response. To get started, we first instantiate and configure the Slim application. Next, we define our application routes. Finally, we run the Slim application. It’s that easy. Here’s an example application:

<?php
// Create and configure Slim app
$config = ['settings' => [
    'addContentLengthHeader' => false,
]];
$app = new \Slim\App($config);

// Define app routes
$app->get('/hello/{name}', function ($request, $response, $args) {
    return $response->write("Hello " . $args['name']);
});

// Run app
$app->run();

When we build a Slim app, we are often working directly with Request and Response objects. These objects represent the actual HTTP request received by the web server and the eventual HTTP response returned to the client.

Every Slim app route is given the current Request and Response objects as arguments to its callback routine. These objects implement the popular PSR7  interfaces. The Slim app route can inspect or manipulate these objects as necessary. Ultimately, each Slim app route must return a PSR7  Response object.

Slim is designed to play well with other PHP components, too. We can register additional first-party components  that build upon Slim’s default functionality. It’s also easy to integrate third-party components found on Packagist.

If anyone is new to Slim, I recommend to read this documentation from start to finish. If anyone is already familiar with Slim, she/he can instead jump straight to the appropriate section.

This documentation begins by explaining Slim’s concepts and architecture before venturing into specific topics like request and response handling, routing, and error handling.

Installing slim:
We recommend to install Slim with Composer. Navigate into project’s root directory 
and execute the bash command shown below. This command downloads the Slim Framework and its 
third-party dependencies into your project’s vendor/ directory. 
composer require slim/slim "^3.0"
Require the Composer autoloader into your PHP script, and you are ready to start using Slim.
<?php
require 'vendor/autoload.php';

Don’t have Composer? It’s easy to install by following the instructions on their download page.
If one is upgrading from version 2 to version 3, these are the significant changes that need to be aware of.
Slim 3 requires PHP 5.5 or latest version.

New Route Function Signature
$app->get('/', function (Request $req,  Response $res, $args = []) {
    return $res->withStatus(400)->write('Bad Request');
});

Getting _GET and __POST variables
$app->get('/', function (Request $req,  Response $res, $args = []) {
    $myvar1 = $req->getParam('myvar'); //checks both _GET and _POST [NOT PSR-7 Compliant]
    $myvar2 = $req->getParsedBody()['myvar']; //checks _POST  [IS PSR-7 compliant]
    $myvar3 = $req->getQueryParams()['myvar']; //checks _GET [IS PSR-7 compliant]
});
Hooks are no longer part of Slim as of v3. You should consider reimplementing any functionality associated with the default hooks in Slim v2 as middleware instead.
If you need the ability to apply custom hooks at arbitrary points in your code (for example, within a route), you should consider a third-party package 
such as Symfony’s EventDispatcher or Zend Framework’s EventManager.

Remova;l HTTP Cache

In Slim v3 we have removed the HTTP-Caching into its own module Slim\Http\Cache.

Removal of Stop/Halt

Slim Core has removed Stop/Halt. In your applications, you should transition to using the withStatus() and withBody() methods.

Removal of autoloader

Slim::registerAutoloader() have been removed, we have fully moved to composer.

Changes to container

$app->container->singleton(...) is now $app['...'] = function () {}; Please read Pimple docs for more info

Removal of configureModel()

$app->configureMode(...) has been removed in v3.

 

Removal of PrettyExceptions

PrettyExceptions cause lots of issues for many people, so this have been removed.

ROute::setDefaultConditions(…) has been removed

We have switched routers which enable you to keep the default conditions regex inside of the route pattern.

Changes to redirect

In Slim v2.x one would use the helper function $app->redirect(); to trigger a redirect request. In Slim v3.x one can do the same with using the Response class like so.

Example:

$app->get('/', function ($req, $res, $args) {
  return $res->withStatus(302)->withHeader('Location', 'your-new-uri');
});

Middleware Signa

The middleware signature has changed from a class to a function.

New signature:

use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

$app->add(function (Request $req,  Response $res, callable $next) {
    // Do stuff before passing along
    $newResponse = $next($req, $res);
    // Do stuff after route is rendered
    return $newResponse; // continue
});

You can still use a class:

namespace My;

use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

class Middleware
{
    function __invoke(Request $req,  Response $res, callable $next) {
        // Do stuff before passing along
        $newResponse = $next($req, $res);
        // Do stuff after route is rendered
        return $newResponse; // continue
    }
}


// Register
$app->add(new My\Middleware());
// or
$app->add(My\Middleware::class);

Middleware Execution

Application middleware is executed as Last In First Executed (LIFE).

Flash Message

Flash messages are no longer a part of the Slim v3 core but instead have been moved to seperate Slim Flash package.


In v3.0 cookies has been removed from core. See FIG Cookies for a PSR-7 compatible cookie component.

Removal of Crypto

In v3.0 we have removed the dependency for crypto in core.

New Router

Slim now utilizes FastRoute, a new, more powerful router!

This means that the specification of route patterns has changed with named parameters now in braces and square brackets used for optional segments:

// named parameter:
$app->get('/hello/{name}', /*...*/);

// optional segment:
$app->get('/news[/{year}]', /*...*/);

Route Middleware

The syntax for adding route middleware has changed slightly. In v3.0:

$app->get()->add($mw2)->add($mw1);

Getting the current route

The route is an attribute of the Request object in v3.0:

$request->getAttribute('route');

When getting the current route in middleware, the value for determineRouteBeforeAppMiddleware must be set to true in the Application configuration, otherwise the getAttribute call returns null.

urlFor() is now pathFor in the router

urlFor() has been renamed pathFor() and can be found in the router object:

$app->get('/', function ($request, $response, $args) {
    $url = $this->router->pathFor('home');
    $response->write("<a href='$url'>Home</a>");
    return $response;
})->setName('home');

Also, pathFor() is base path aware.

Container and DI  ….. Constractiing

Slim uses Pimple as a Dependency Injection Container.

// index.php
$app = new Slim\App(
    new \Slim\Container(
        include '../config/container.config.php'
    )
);

// Slim will grab the Home class from the container defined below and execute its index method.
// If the class is not defined in the container Slim will still contruct it and pass the container as the first arugment to the constructor!
$app->get('/', Home::class . ':index');


// In container.config.php
// We are using the SlimTwig here
return [
    'settings' => [
        'viewTemplatesDirectory' => '../templates',
    ],
    'twig' => [
        'title' => '',
        'description' => '',
        'author' => ''
    ],
    'view' => function ($c) {
        $view = new Twig(
            $c['settings']['viewTemplatesDirectory'],
            [
                'cache' => false // '../cache'
            ]
        );

        // Instantiate and add Slim specific extension
        $view->addExtension(
            new TwigExtension(
                $c['router'],
                $c['request']->getUri()
            )
        );

        foreach ($c['twig'] as $name => $value) {
            $view->getEnvironment()->addGlobal($name, $value);
        }

        return $view;
    },
    Home::class => function ($c) {
        return new Home($c['view']);
    }
];

PSR7-7 objects

Request, Response, Uri & UploadFile are immutable.

This means that when you change one of these objects, the old instance is not updated.

// This is WRONG. The change will not pass through.
$app->add(function (Request $request, Response $response, $next) {
    $request->withAttribute('abc', 'def');
    return $next($request, $response);
});

// This is correct.
$app->add(function (Request $request, Response $response, $next) {
    $request = $request->withAttribute('abc', 'def');
    return $next($request, $response);
});

Message bodies are streams

// ...
$image = __DIR__ . '/huge_photo.jpg';
$body = new Stream($image);
$response = (new Response())
     ->withStatus(200, 'OK')
     ->withHeader('Content-Type', 'image/jpeg')
     ->withHeader('Content-Length', filesize($image))
     ->withBody($body);
// ...

For text:

// ...
$response = (new Response())->getBody()->write('Hello world!')

// Or Slim specific: Not PSR-7 compliant.
$response = (new Response())->write('Hello world!');


The end

 
 

Save Submitted Messages in Contact Form 7 with Flamingo

Why You Might Want to save the messages?

In my opinion, the one major downside to using contact form 7 is that it sends all submissions to email addresses by default and does not store the messages within WordPress. I want the messages sent via contact form 7 to be stored within WordPres. So I can easily access them and I don’t have to worry about email breaking down. Another benefit here is, you don’t have to share email credentials with your staffs to make them able to access the email.(You might also accomplish this by sending email from CF7 to multiple email address simultaneously but this will use up your valuable disk space). Finally, storing contact mail on database gives easy to import feature for a wide range of format.

Fortunately, the developer has created a separate plug-in called Flamingo that can be integrated automatically with contact form 7 and collects all inbound messages.

 

Use Flamingo on WordPress

Go to Plugins > Add New, then search for Flamingo and install the Flamingo Plugin in your website. Once activated, Flamingo will appear on my admin main menu directly above contact. Now you can see that Flamingo provides two things, address book, and inbound messages.

Flamingo is actually a very rudimentary CRM system, that stores information on the people who contact you in an address book and then link those people to the messages they send.