Adding Recaptcha to registration page on Laravel framework

In the app folder, create a Rules folder. Save the following code as GoogleRecaptcha.php:

<?php
namespace App\Rules;
use GuzzleHttp\Client;
use Illuminate\Contracts\Validation\Rule;
class GoogleRecaptcha implements Rule
{

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $url='https://www.google.com/recaptcha/api/siteverify';
	$data = array(
       		'secret' => env('GOOGLE_RECAPTCHA_SECRET'),
		'response' => @$_POST['g-recaptcha-response']
        );
	$ch = curl_init($url);	
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch , CURLOPT_POSTFIELDS, http_build_query($data));
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$json = curl_exec($ch);
	curl_close($ch);
	$response = json_decode($json,true);
	var_dump($response);
	if ($response['success'] != false) {
		return 'success';}
	else{return false;}
	#$response= $obj ->{"success"};
	#var_dump($response[0]);
        #$response = $client->post('https://www.google.com/recaptcha/api/siteverify',
         #   [
          #      'form_params' => [
           #         'secret' => env('RECAPTCHA_SECRET_KEY', false),
            #        'remoteip' => request()->getClientIp(),
             #       'response' => $value
              #  ]
            #]
        #);
        #$body = json_decode((string)$response->getBody());
        #return $body->success;
    }
    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Are you a robot?';
    }
}

In app/Http/Controllers/Auth/RegisterController.php

use App\Rules\GoogleRecaptcha;
/**
 * Get a validator for an incoming registration request.
 *
 * @param  array  $data
 * @return \Illuminate\Contracts\Validation\Validator
 */
protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6|confirmed',
        'g-recaptcha-response' => ['required', new GoogleRecaptcha]
    ]);
}

Original code was with guzzle but it leads to the following issue:

Issue: “cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)”

https://stackoverflow.com/questions/42094842/curl-error-60-ssl-certificate-in-laravel-5-4

in resources/views/auth/register.blade.php

Add in the registration form:

                      @if(env('GOOGLE_RECAPTCHA_KEY'))
                        <div class="form-group row">
                             <div class="g-recaptcha offset-md-4 col-md-6"
                                  data-sitekey="{{env('GOOGLE_RECAPTCHA_KEY')}}">
                             </div>
                         </div>
                       @endif

in the views/layouts/app.blade.php or in the register.blade.php files add the following line:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

In .env

GOOGLE_RECAPTCHA_KEY=site_key
GOOGLE_RECAPTCHA_SECRET=site_secret

to avoid issue with guzzle, let’s consider making the curl REST API call manually: https://weichie.com/blog/curl-api-calls-with-php/

$jsonurl =""
$curl_handle=curl_init();

The CURL manual call worked perfectly

Custom blade directive @isAdmin in Laravel 5.3+

  1. Create a is_admin column in your user database, only admin can register a user. Allow admin to register user as admin or not.
  2. Open user.php in the app folder and add use Illuminate\Support\Facades\Auth;
  3. Add the following function to the user class:
public function isAdmin()
{
    if (Auth::user() &&  Auth::user()->is_admin == 1) {
        return true;
    }
}

From there we can already check if user is admin in our view like this:

@if(Auth::user()->isAdmin())
    Something that should only be visible to admin
@endif

4. We would like to keep our code elegant so let’s add a custom directive to blade. Open AppServiceProviders.php and add the following code in the boot function:

namespace App\Providers;
 use Illuminate\Support\ServiceProvider;
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Support\Facades\Blade;
 use Illuminate\Support\Facades\Auth;
 class AppServiceProvider extends ServiceProvider
 {
     /**
      * Register any application services.
      *
      * @return void
      */
     public function register()
     {
         Blade::if('isAdmin', function(){
             if(Auth::check())
                 return Auth::user()->is_admin===1?true:false;
             else return false;
         });
     }
 /**  * Bootstrap any application services.  *  
* @return void  */ 
public function boot() {
     Schema::defaultStringLength(191);
    // Blade custom directives for isAdmin
     Blade::directive('isAdmin', function() {
         return "<?php if(Auth::user()->isAdmin()): ?>";
     });
     Blade::directive('endisAdmin', function() {
             return "<?php endif; ?>";
     }); }
 }

From there you should be all set to use @isAdmin @endisAdmin in your blade view files.

In case it doesn’t work, make sure to test that @if(Auth::user()->isAdmin()) is working properly and revert back to your custom directive.

Admin only register page in Laravel 5.2

All credits go to : https://stackoverflow.com/questions/36250746/how-to-protect-register-with-auth-midleware-in-laravel-5-2

Solution #1 (any authenticated user)

On file /app/Http/Controllers/Auth/RegisterController.php

simply change from

public function __construct()
{
    $this->middleware('guest');
}

to

public function __construct()
{
    $this->middleware('auth');
}

Solution #2 (only authenticated admin user) a) run

php artisan make:middleware IsAdmin

b) Add to the routeMiddleware array in your kernel file by opening app/Http/Kernel.php:

'admin' => \App\Http\Middleware\IsAdmin::class,

c) edit isAdmin file

public function handle($request, Closure $next)
{
     if (Auth::user() &&  Auth::user()->is_admin == 1) {
            return $next($request);
     }

    return redirect('/');
}

d) On file /app/Http/Controllers/Auth/RegisterController.php, change the constructor from

public function __construct()
{
    $this->middleware('guest');
}

to

public function __construct()
{
    $this->middleware('admin');
}

e) Update user migration to include a boolean field

Schema::create('users', function (Blueprint $table) {
    $table->mediumIncrements('id');
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->boolean('is_admin')->default(false);
    $table->rememberToken();
    $table->timestamps();
});

f) Update User model to allow ‘is_admin’ field

protected $fillable = [
    'name', 'email', 'password', 'is_admin'
];

Materialized: Select value not passed in post body

If you are using the materialize framework, you might have trouble to pass a value when using the select element in a form. Indeed the value is not taken into account. To solve this give an id to the select element and and add an hidden input field with the relevant field name and id as so:

<div class="row">             
<div class="input-field col s12">
<select id="data_select">
<option value="" disabled selected>Data</option> <option value="1">data 1</option>
<option value="2">data 2</option>
<option value="3">data 3</option> <option value="4">data 4</option> </select>
<input type="hidden" name="data_name" id="data_hidden" /> </div>
</div>

and with the associated script:

// Post Materialize select value$(document).ready(function() {
$('#data_select').on('change', function() {
var data_select=document.getElementById("data_select").value;
document.getElementById("data_hidden").value=data_select;

});

[Edit: everything worked fine simply using the following code:

<div class="row">             
<div  class="input-field col s12">                 
<select name="data_name"  id="data_select">                   
<option  value="" disabled selected>Data</option>                   <option  value="1">data 1</option>                   
<option  value="2">data 2</option>                   
<option  value="3">data 3</option>                  
<option  value="4">data 4</option>                 
</select>                 
</div>                       
</div>

]

WAMP Syntax error in INSERT INTO statement

Error : Syntax error in INSERT INTO statement

You might be using some reserved words as the table name.

Based on that article: https://support.microsoft.com/en-gb/help/892608/you-may-receive-a-syntax-error-in-insert-into-statement-error-message.

I tested by changing the name of the table from “orders” to orders_table and it solved the issue. I conclude that orders might be a reserved word.

Solution: change the table name to something else as illustrated above.

Warning: Cannot modify header information – headers already sent by resolved.

Error message: Warning: Cannot modify header information – headers already sent by ….

It might be cause by the encoding of your php file.

Verify that your php file is encoded in UTF-8 without BOM. In Notepad +:

In UTF-8 under  Encoding  choose Convert to UTF-8

The BOM, or Byte Order Mark, cause the header to be sent prematurely.

More info on how to find files encoded in UTF8-BOM.

If it doesn’t work, check that you don’t send anything before session_start()

PHP showing as text after upgrade to Ubuntu 18.04

Description of the issue:

PHP files show as plain text in the web browser using a valid http request.

When the issue occured:

During the upgrade to Ubuntu 18.04, you might have chosen, as I did, to remove outdated packages, which has removed PHP 7.1

Noticing that, you certainly installed PHP 7.2 with the command:

sudo apt install php-pear php-fpm php-dev php-zip php-curl php-xmlrpc php-gd php-mysql php-mbstring php-xml libapache2-mod-php

and restart the apache server:

sudo service apache2 restart

Source: https://howtoubuntu.org/how-to-install-lamp-on-ubuntu

This might have not solved the issue.

If reinstalling PHP is indeed required, what brought back PHP was the following:

sudo a2enmod php7.2
sudo service apache2 restart

Indeed, in addition to reinstalling apache2, you need to re-activate php-mod in apache2. This is the meaning of a2enmod php7.2.

  a2enmod  is  a  script that enables the specified module within the apache2 configuration.

Source:  http://manpages.ubuntu.com/manpages/trusty/man8/a2enmod.8.html

TLDNR / Solution:

sudo apt install php-pear php-fpm php-dev php-zip php-curl php-xmlrpc php-gd php-mysql php-mbstring php-xml libapache2-mod-php
sudo a2enmod php7.2
sudo service apache2 restart

PHP API call. file_get_contents(…) request failed to open stream: HTTP request failed!

Issue:

When making an API call with

$json = file_get_contents($jsonurl);

You get the following error message:

file_get_contents(your.api.call) request failed to open stream: HTTP request failed!

Description:  In my case the above function works perfectly well when the php file is called from a web browser but return most of the time the aforementioned  error message when run through cron.

Solution:

Use curl to call the api.

$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL,$jsonurl);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'YOUR APP NAME');
$json = curl_exec($curl_handle);
curl_close($curl_handle);

Source: https://stackoverflow.com/questions/697472/php-file-get-contents-returns-failed-to-open-stream-http-request-failed

 

Encode special character from php to mysql

Special characters may not be displayed correctly in your mysql data base when you pass php string to mysql statement.

https://github.com/phpmyadmin/phpmyadmin/wiki/Garbled_data

First thing you should do is to make sure that your mysql database encoding is set to utf-8. You can easily do that through phpmyadmin.

Then make sure the string you send are properly encoded in UTF-8 by using the php function http://php.net/manual/en/function.mb-convert-encoding.php

string mb_convert_encoding ( string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ] )

Example:

$name=mb_convert_encoding($response,"UTF-8");

Lastly make sure that the first query you send to you databse is SET NAMES utf8  like in the example below:

$con=mysqli_connect("localhost","my_user","my_password","my_db");
$con->query("SET NAMES utf8");