vendredi 15 juillet 2016

Recurly PHP 2.5.* in Laravel 5.1 getting 'Call to private method' error

I'm currently in the process of developing a heavily Recurly integrated platform that Users constantly have the option of adding/editing/removing features that will immediately be reflected in their subscription pricing.

The environment for this project is Laravel 5.1 and attempting to use Recurly's PHP Client to simplify the API integration. In order to get a lot of the Recurly stuff to work, I had to add namespacing to the Recurly PHP Files in order to have them successfully referenced and reference one another inside Laravels Framework. i.e.

<?php

namespace App\Libraries\Recurly;

use DateTime;
use DOMDocument;

abstract class Recurly_Base
{

to all 44 or so class files involved in the 2.5.* version of the Recurly PHP library.

I can successfully use the library to generate subscriptions, but any time I try to update those subscriptions, I get this FatalErrorException thrown by PHP, and thrown by the same class I exampled above.

Call to private method Recurly_Base::addLink() from context 'App\Libraries\Recurly\Recurly_Base'

This error is thrown during this block of code

        $user = $request->user();

        $subscription = Recurly_Subscription::get($user->recurly_subscription_code);
        $subscription->plan_code = '<plan_code>';

        $user->subscription_pricing = $user->subscription_pricing + $newItemPrice;
        $user->updated_at = $user->freshTimestamp();


        $subscription->unit_amount_in_cents =  $user->subscription_pricing;

        $subscription->updateImmediately(); // <- The offending line

        $user->save();

It seems that for some reason, the Recurly_Base class cannot access it's own private method addLink.

I attempted to resolve the issue by weakening the Visibility of all Recurly_Base methods and values so that the 'private'-ness of addLink wouldn't matter, but the FatalErrorException was still thrown.



via Chebli Mohamed

Configuration for Redis cluster

I'm running Laravel in a GlusterFS cluster and I want to setup a redis cluster too, but I'm not able to find out how should I configure Laravel.

This is the example config file:

'redis' => [
        'cluster' => false,
        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],
    ],

How can I add multiple servers?



via Chebli Mohamed

Laravel 5.1 Mockery expectation ignored while testing controller

I have a Controller depending on a UserManager. This is the controller constructor:

public function __construct(UserManager $manager) {
    $this->manager = $manager;
}

This is the test code.

public function test_something() {
    $this->withoutMiddleware();

    // Setup Input.
    $user = ['email' => 'foo@bar.baz', 'password' => 'pass', 'accessLevel' => 'admin'];

    // Setup expectations.
    $mock = \Mockery::mock("Users\UserManager")->shouldReceive('foo');

    // Bind to container... not sure whether this is needed.
    $this->app->instance("Users\UserManager", $mock);

    // Call action.
    $this->call('POST', 'api/v1/temp/users', ['user' => $user]);
}

I set the expectation on the foo method, which doesn't exists and therefore is not invoked anywhere, however my test won't fail.

Why?



via Chebli Mohamed

Joining two models to obtain data

I query my model like so

$projects = Project::where('status', '!=', 'Completed')->get();

This will return me something like this

#attributes: array:16 [▼
    "id" => "7"
    "user_id" => "32"
    "contactEmail" => "sdfsdf@dsfsdf.com"
    "deploymentDate" => "2016-07-29"
    "status" => "Starting"
    "deleted_at" => null
    "created_at" => "2016-07-12 14:12:32"
    "updated_at" => "2016-07-15 09:47:34"
]

I then pass this model to generate an Excel file

Excel::create('projects', function($excel) use($projects) {
    $excel->sheet('Sheet 1', function($sheet) use($projects) {
        $sheet->fromArray($projects);
    });
})->export('xls');

Everything works fine, and the Excel is generated. One problem I have though is that the excel file shows user_id being 32. Instead of displaying the user_id, I want to display the userName which is part of my Users table.

How can I join these two tables to get the name instead of the id? All relationships are set up correctly.

Thanks



via Chebli Mohamed

Undefined variable: stations in view

I have undefined variable and it doesn't call variable.

I get missing argument 1 error when I try accessing a page. This is my code.

Part of the view:

@foreach($stations as $station)
    <span>  </span>
@endforeach

Controller:

public function show($id)
{
    $stations = DB::table('stations')->pluck('station');
    return view('configuration.configuration', $stations);
}

Route:

Route::get('configuration/', 'ConfigurationController@show');



via Chebli Mohamed

Missing argument 1 for App\Http\Controllers\ConfigurationController::show()

I get missing argument 1 error when i try access page this is my code. Part of the view

        @foreach($stations as $station)

                    <span> </span>

        @endforeach

Controller

public function show($id)
{ 

    $stations = DB::table('stations')->pluck('station');

    return view('configuration.configuration', $stations);

}

route

Route::get('configuration/', 'ConfigurationController@show');



via Chebli Mohamed

jeudi 14 juillet 2016

Validate Authorization in Laravel 5.2

My roles are dynamic and their User's permission are also dynamic. I have two approaches to validate if the user is authorized to access the particular page.

Approach 1

class BaseController extends Controller
{
    public function __construct() {
        if(!\Auth::user()->IsPredefined) {
            $result = $this->ValidateAuthorization();
            if(!$result) {
                \Auth::logout();
                return redirect()->route("login");
            }
        }
    }

    private function ValidateAuthorization() {
        $ActionName = \Route::getCurrentRoute()->getPath();
        switch ($ActionName) {
            case "ChangePassword":
                $ModuleID = ModuleEnum::AccountManagemenet;
                $ActionID = AccountActionEnum::ChangePassword;
                return CheckUsePermissions($ModuleID, $ActionID);            
        }
    }

    private function CheckUsePermissions($ModuleID, $ActionID) {
        $User = MySession::UserPermissions();
        foreach($User->UserRolePermissions as $UserRolePermission) {
            $CurrentActionID = $UserRolePermission->RolePermission->Permission->ActionID;
            $CurrentModuleID = $UserRolePermission->RolePermission->Permission->ModuleID;
            if($CurrentActionID == $ActionID && $CurrentModuleID == $ModuleID && 
                    $UserRolePermission->IsActive == true) {
                return true;
            }
        }
        return false;
    }
}

Approach 2

Use Authorize method in Request class

public function authorize()
{
    return true;
}

Confusion

  1. If Approach 2 is good, should I create Request class for each Get, Put, Delete and POST?
  2. Is there any better approach to validate authorization?


via Chebli Mohamed