Saturday, March 26, 2016

Sencha Touch 2.2 Scrolling Issue in Android 5.1

Hello,

If your application is created with Sencha Touch 2.2 it must be having scroll issue for forms, list and carousels in android 5.1 on words.

The reason is some chrome updates have broken Sencha Touch scrolling logic and that's why it's not working so what is the solution, well the simple solution is to update your sencha touch version in the app. But what if the app is not created with Sencha CMD. Yes in my case previous developer have created app with loading sencha-touch-all,js and css. So I can not simply modify it with new version y sencha cmd and there were lots of CSS overrides. So what to do. In this blog I am going to explain.

First of all create folder with name util in your app folder. Now create new JS file in util folder and name it "PaintMonitor.js" and add following code to it.

/**
 * Created by hirendave on 3/7/16.
 */
Ext.define('SEOshop.util.PaintMonitor', {
    override: 'Ext.util.PaintMonitor',

    uses: [
        'Ext.env.Browser',
        'Ext.env.OS',
        'Ext.util.paintmonitor.CssAnimation',
        'Ext.util.paintmonitor.OverflowChange'
    ],

    constructor: function(config) {
        return new Ext.util.paintmonitor.CssAnimation(config);
    }

}, function () {
    //
    console.info("Ext.util.PaintMonitor temp. fix is active");
    //
});

Crete one more file with name "SizeMonitor.js" and add following code to it.

/**
 * Created by hirendave on 3/7/16.
 */
Ext.define('SEOshop.util.SizeMonitor', {
    override: 'Ext.util.SizeMonitor',

    uses: [
        'Ext.env.Browser',
        'Ext.util.sizemonitor.Default',
        'Ext.util.sizemonitor.Scroll',
        'Ext.util.sizemonitor.OverflowChange'
    ],
    constructor: function (config) {
        var namespace = Ext.util.sizemonitor;

        if (Ext.browser.is.Firefox) {
            return new namespace.OverflowChange(config);
        } else if (Ext.browser.is.WebKit) {
            if (!Ext.browser.is.Silk && Ext.browser.engineVersion.gtEq('535') && !Ext.browser.engineVersion.ltEq('537.36')) {
                return new namespace.OverflowChange(config);
            } else {
                return new namespace.Scroll(config);
            }
        } else if (Ext.browser.is.IE11) {
            return new namespace.Scroll(config);
        } else {
            return new namespace.Scroll(config);
        }
    }
}, function () {
    //
    console.info("Ext.util.SizeMonitor temp. fix is active");
    //
});

Now go to your app.js file and add following code to your application object.

requires: [
        'YOUR_APP.util.SizeMonitor',
        'YOUR_APP.util.PaintMonitor'
    ]

That's it and it should solve all the scrolling and rendering issue in Android 5.1 and above version.

Hope this helps you.

Laravel LinkedIn Verification - Laravel LinkedIn Login

Recently in one of the laravel project we have to add LinkedIn verification. It's like we have to auto check if user is signing up on our app should have LinkedIn profile with same name and email. In this blog I am going to explain how to do this. First of all we will need one LinkedIn application. Go to following URL to create new LinkedIn application.

https://www.linkedin.com/developer/apps/

Once you create application it should look like below screenshot.


Now you have to copy client Id and client secret to your laravel app, that you can do in env file.

LINKEDIN_CLIENT_ID = your_client_id
LINKEDIN_CLIENT_SECRET = your_client_secret

Now in your laravel view you have to add a link, so user can click on it and go to LinkedIn for authentication.

Add following to your routes.

    Route::get('/user/linkedin-verification','AdminController@viewLinkedinVerification');

Following should be function of your controller.

        $user_id = Auth::user()->id;
        $user = User::find($user_id);
        $redirect_uri = env('LINKEDIN_REDIRECT_URL', '');
        $client_id = env('LINKEDIN_CLIENT_ID', '');
        $client_secret = env('LINKEDIN_CLIENT_SECRETE', '');
        return view('linkedinverification.index')-              >with(['user'=>$user,'redirect_uri'=>$redirect_uri,'client_id'=>$client_id,'client_secret'=>$client_secret]);

Where user is currently logged in user and redirect URL is the URL that will be invoked on successful LinkedIn verification,

Your view should have a link like below.

                        <p>Please verify your LinkedIn account. <a href="https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id={{$client_id}}&redirect_uri={{$redirect_uri}}&state=ab234aatdssda">Click Here</a></p>

When user click on this link they will see below screen of your LinkedIn application.


Once you are logged in with your LinkedIn account it will redirect back you website with specified redirect url with access code.

Add following to your laravel route.

Route::get('/user-dashboard/linkedin-response','AdminController@linkedinVerification');

In my case I used above URL, you can have different URL as per your requirement.

Now in linkedinVerification function first we will get access code which is generated by LinkedIn and get oAuth access token first. following is the code to get access token.

            $redirect_uri = env('LINKEDIN_REDIRECT_URL', '');
            $client_id = env('LINKEDIN_CLIENT_ID', '');
            $client_secret = env('LINKEDIN_CLIENT_SECRET', '');

            $code = Input::get('code');
            
            /// for get accesstoken
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL,"https://www.linkedin.com/uas/oauth2/accessToken");
            curl_setopt($ch, CURLOPT_POST, 5); // number of post parameters
            curl_setopt($ch, CURLOPT_POSTFIELDS,
                        "code=".$code."&client_id=".$client_id."&redirect_uri=".$redirect_uri."&grant_type=authorization_code&client_secret=".$client_secret);
            
            // receive server response ...
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            
            $server_output = curl_exec ($ch);
            curl_close ($ch);

Now you get access token, use that to get user profile information.

                $result = json_decode($server_output, true);
                
                $access_token = $result['access_token'];
                
                if($access_token != '')
                {
                    // for get customer email
                    $datach = curl_init();  
                    $authorization = 'Authorization: Bearer '.$access_token;
                    curl_setopt($datach,CURLOPT_URL,'https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name)?format=json');
                    curl_setopt($datach,CURLOPT_RETURNTRANSFER,true);
                    curl_setopt($datach, CURLOPT_HTTPHEADER, array($authorization));
                 
                    $output=curl_exec($datach);
                 
                    curl_close($datach);
              }

Above call will give you basic user profile, now we just get email and name from it and compare it with credentials registered with us.

Hope this helps you.

Saturday, March 19, 2016

Undefined Variable: Errors in Laravel 5.2 Application

Recently in one of my Laravel 5.2 project we were using Laravel model validations on server side, where we faced an issue that on failed validation it goes back to previous view but we did not get any errors as it was giving error undefined variable $errors.

This is a breaking problem with the 5.2 upgrade. What's happening is the middleware which is responsible for making that errors variable available to all your views is not being utilized because it was moved from the global middleware to the web middleware group. So to fix this issue you have to do following.

Wrap all your web routes with a route group and apply the web middleware to them

Route::group(['middleware' => 'web'], function() {
    // all routes.
});

That's it and now it should work.

Laravel App Not Working in Iframe in Internent Explorer

Recently in one of my project we faced strange issue. We have one application running from one domain. This application has an iFrame which is loading laravel app from other domain. This laravel app has certain ajax requests. The issue was this laravel app and ajax requests were working fine in Chrome and other webkit browser however it was not working in Internet Explorer.

After few ours of struggle we found a solution. Actually it was an issue of cookies being blocked by Internet Explorer. We all know that laravel app creates certain cookies on the front end. This was blocked by Internet Explorer hence Ajax requests were not working as it was unable to find cookies. First of let me explain what exactly was the issue and then we will look for solution.

Internet Explorer gives lower level of trust to IFRAME pages (IE calls this "third-party" content). If the page inside the IFRAME doesn't have a Privacy Policy, its cookies are blocked (which is indicated by the eye icon in status bar, when you click on it, it shows you a list of blocked URLs).

In this case, when cookies are blocked, session identifier is not sent, and the target script throws a 'session not found' error.

So to solve this problem, it is possible to make the page inside the IFRAME more trusted: if the inner page sends a P3P header with a privacy policy that is acceptable to IE, the cookies will be accepted. So here is how to do this in Laravel app. Add this header in your laravel controller.

header('P3P: CP="This site does not have a p3p policy."');

And that's it it will solve the problem.

You can get more information about P3P policy from below link.

https://www.w3.org/P3P/details.html


Hope this helps you.