https://laravel.com/

Laravel 4

Add custom helper functions with some helper files

1
2
3
4
5
# create a helpers folder
$ mkdir /path/to/laravel/app/helpers

# create a helper file
$ touch /path/to/laravel/app/helpers/debug.php

Edit /path/to/laravel/app/start/global.php, and add this to the end of file. This is to include it so you can use it anywhere

1
2
3
4
5
6
7
8
9
10
<?php
...

/*
|--------------------------------------------------------------------------
| Require Helper Files
|--------------------------------------------------------------------------
|
*/
foreach(glob(app_path().'/helpers/*.php') as $h_file) require $h_file;

In /path/to/laravel/app/helpers/debug.php

1
2
3
4
5
6
7
if (!function_exists('my_debug')) {
function my_debug($obj) {
echo '<pre>';
print_r($obj);
echo '</pre>';
}
}
Reference:

Add custom config file

Some time we have use a lot of third party API which need to keep the API key. So we can create a custom config file to store that.

1
$ touch /path/to/laravel/app/config/custom.php

Put content to the file. i.e.

1
2
3
4
5
6
7
8
9
<?php
return array(
'api' => array(
'google_map' => array(
'key' => '98fgy8sy3SDF8f37*#7f',
'other_param' => 'foobar',
),
),
);

Can retrieve it by

1
2
3
$google_config = \Config::get('custom.api.google_map');
echo 'KEY: ' . $google_config['key'];
echo 'Other: ' . $google_config['other_param'];
Reference:

Specify alias on JOIN

On SQL

1
2
3
4
SELECT table.title, table.desc, cu.first_name, mu.first_name
FROM table
LEFT JOIN user cu ON cu.id = table.created_by // user who create
LEFT JOIN user mu ON mu.id = table.modified_by // user who modify

Laravel Query Builder

1
2
3
4
5
6
7
8
9
10
DB::table('table')
->leftJoin('user AS cu', 'cu.id', '=', 'table.created_by')
->leftJoin('user AS mu', 'mu.id', '=', 'table.modified_by')
->select(
'table.title'
, 'table.desc'
, 'cu.first_name'
, 'mu.first_name'
)
->get();
Reference:

Check is POST request

1
2
3
if (\Request::isMethod('POST')) {
// confirmed this is POST request
}

Filter csrf for few functions only

1
$this->beforeFilter('csrf', array('on' => 'post', 'only' => array('func1', 'func2')));

Show the last executed query

1
2
$queries = DB::getQueryLog();
$last_query = end($queries);

OR a better way

1
$query->toSql();
References:

Pagination check has page

Check whether the pagination has other pages

1
2
3
4
5
6
7
8
<?php if ($obj_list->getTotal() > $obj_list->count(): ?>
<div class="pagination-wrapper">
<?php echo $obj_list->appends(array(
'param1' => 'value1',
'param2' => 'value2',
))->links(); ?>
</div>
<?php endif; ?>

If the total objects is more than retrieved objects, that mean it has other pages.


Query builder multiple ORDER BY

1
2
3
\DB::table('tablename')
->orderBy('col_1', 'desc')
->orderBy('col_2', 'asc');

Just have to invoke multiple times

Reference:

Eloquent get pivot/bridge table attributes

In model class

1
2
3
4
5
6
7
return $this->belongsToMany('Bar', 'pivot_table')->withPivot(array(
'pivot_attr_1',
'pivot_attr_2',
'pivot_attr_3',
'pivot_attr_4',
'pivot_attr_5',
));

Usage:

1
2
3
foreach ($foo->bars as $bar) {
echo $bar->pivot->pivot_attr_1;
}
Reference:

Save pivot table data

1
2
3
4
5
foreach ($foo->bars as $bar) {
$bar->pivot->pivot_attr_1 = 'new value';
$bar->pivot->pivot_attr_2 = 'special value';
$bar->pivot->save();
}
Reference:

Eloquent: Sort in child table

Example

user

1
2
3
4
5
6
7
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(128) | NO | | NULL | |
| email | varchar(128) | NO | | NULL | |
+-------------------+------------------+------+-----+---------+----------------+

post

1
2
3
4
5
6
7
8
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(128) | NO | | NULL | |
| user_id | int(10) unsigned | NO | | 0 | |
| published_date | datetime | YES | | NULL | |
+-------------------+------------------+------+-----+---------+----------------+

In this case we want to sort posts belongs to the user

1
$posts = $user->posts->sortBy('published_date');
Reference:

hasMany for long table name

Example

table

1
2
3
4
5
6
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(128) | NO | | NULL | |
+-------------------+------------------+------+-----+---------+----------------+

table_foo

1
2
3
4
5
6
7
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(128) | NO | | NULL | |
| table_id | int(10) unsigned | NO | | 0 | |
+-------------------+------------------+------+-----+---------+----------------+

In Table.php, use camel-case instead of underscore, e.g.

1
2
3
public function tableFoos() {
return $this->hasMany('TableFoo');
}

otherwise it won’t works.

Reference:

Outer .htaccess for shared hosting

In shared hosting, usually we can’t configure the virtual host, one of the way is to create another .htaccess in the project root

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
project
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── composer.phar
├── phpunit.xml
├── public
│   ├── favicon.ico
│   ├── index.php
│   ├── packages
│   ├── robots.txt
│   └── .htaccess # original
├── server.php
├── vendor
└── .htaccess # Add this

Add the content below to project/.htaccess

1
2
3
4
5
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

To redirect all request to public directory

Reference:

Redirect to external URL

1
return Redirect::away('https://www.facebook.com');
Reference:

Eloquent filter joined table

1
2
3
4
5
6
7
8
9
10
11
12
13
Transaction table
+----+-------------+---------+
| id | borrower_id | book_id |
+----+-------------+---------+
| 1 | 1 | 1 |
+----+-------------+---------+

Book table
+----+----------+
| id | owner_id |
+----+----------+
| 1 | 1 |
+----+----------+

Let say want to retrieve those transation that related to a particular
user, regardless he/she is owner or borrower

1
2
3
4
$query
->where('borrower_id', '=', $user_id)
->book()->where('owner_id', '=', $user_id)
;

Laravel 5

MassAssignmentException exception in seeder

1
2
3
4
5
6
public function run()
{
Eloquent::unguard(); // <----- Add this

// ...
}
Reference:

Get remote IP address

1
2
<?php
$request->server->get('HTTP_X_FORWARDED_FOR', $request->ip())

Get database table last insert ID without insert record

1
2
3
4
5
6
<?php
$table_status = \DB::select('SHOW TABLE STATUS FROM ' . env('DB_DATABASE') . ' WHERE Name = "table_name"');
if (empty($table_status)) {
throw new \Exception('Table not found');
}
$last_id = $table_status[0]->Auto_increment;

COUNT aggregated values with multiple conditions

Example, get the book borrowed for today, this week, this month, etc. in 1 query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$today = Carbon::now()->toDateString();
$week_start = Carbon::now()->startOfWeek()->toDateString();
$week_end = Carbon::now()->endOfWeek()->toDateString();
$month_start = Carbon::now()->startOfMonth()->toDateString();
$month_end = Carbon::now()->endOfMonth()->toDateString();

$books = Book::select([
'books.*',
\DB::raw('COUNT(DISTINCT user_books.id) AS total_borrows'),
\DB::raw('COUNT(DISTINCT IF(user_books.date = "' . $today . '", user_books.id, NULL)) AS today_borrows'),
\DB::raw('COUNT(DISTINCT IF(user_books.date >= "' . $week_start . '" AND user_books.date <= "' . $week_end . '", user_books.id, NULL)) AS week_borrows'),
\DB::raw('COUNT(DISTINCT IF(user_books.date >= "' . $month_start . '" AND user_books.date <= "' . $month_end . '", user_books.id, NULL)) AS month_borrows'),
])->join('user_books', 'user_books.book_id', '=', 'books.id')
->groupBy('books.id')
->get();

Laravel 6

Get total count from a GROUP BY query

1
2
3
4
<?php
\DB::query()->fromSub(function ($query) {
$query->from('table_child')->groupBy('col_id');
}, 'sq')->count();
Reference:

Set cache-control to S3

Update config/filesystems.php

1
2
3
4
5
6
7
8
9
10
's3' => [
'driver' => 's3',
'key' => env('AMAZON_S3_KEY'),
'secret' => env('AMAZON_S3_SECRET'),
'region' => env('AMAZON_S3_REGION'),
'bucket' => env('AMAZON_S3_BUCKET'),
'options' => [
'CacheControl' => 'max-age=2592000', // 2592000 seconds = 30 days
]
],
Reference:

Generate dummy data

1
$ php artisan make:factory ProductFactory --model="App\\Models\\Product"

Edit the factory file database/factories/ProductFactory.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
use App\Models\Product;
use Faker\Generator as Faker;

$factory->define(Product::class, function (Faker $faker) {
$user_id = random_int(1, 100);
return [
'description' => $faker->text,
'price' => random_int(1, 10) * 100,
'user_id' => $user_id,
'created_by' => $user_id,
];
});

Trigger the php code with tinker

1
$ php artisan tinker

Generate data

1
2
Psy Shell v0.9.9 (PHP 7.3.6cli) by Justin Hileman
>>> factory(App\Models\Product::class, 100)->create();
Reference: