SitePoint PHPLaravel and Braintree: Middleware and Other Advanced Concepts (20.1.2017, 17:00 UTC)

Previously, we saw how to configure a Laravel app to handle Braintree subscriptions.

Braintree Logo

This time, we'll talk about how to:

  • Prevent users from signing up to the same plan twice
  • Add basic flash messaging to our application
  • Add the ability to swap plans
  • Create middleware to protect some routes based on the subscription status
  • Restrict users with basic subscriptions from accessing premium content
  • Cancel and resume subscriptions
  • Add Braintree notifications to the application's events via webhooks

Double Subscriptions

As it stands, if we visit the plans index page, we can still see the Choose Plan button for the plan we are currently subscribed to, and this shouldn't be the case. In the plans index view. let's add an if conditional to hide the button based on the user's subscription status:

[...]
@if (!Auth::user()->subscribedToPlan($plan->braintree_plan, 'main'))
    Choose Plan
@endif
[...]

But that's not to say users can't access the plan by typing in the URL pointing to the same plan in the address bar. To counter this, let's update the code in the show action of the PlansController to this:

[...]
public function show(Request $request, Plan $plan)
{
    if ($request->user()->subscribedToPlan($plan->braintree_plan, 'main')) {
        return redirect('home')->with('error', 'Unauthorised operation');
    }

    return view('plans.show')->with(['plan' => $plan]);
}
[...]

Here, we are getting the user from the request object; remember all our routes fall under the auth middleware and thus it's possible to get the authenticated user. Once we get the user, we check if they are already subscribed to the plan. If that's the case, we redirect them to the homepage and display a notification. We will implement basic flash messaging later.

One last precaution is preventing users from submitting the payment form with a different plan ID value. It's possible to inspect the DOM element and change the value for the hidden input. In our SubscriptionsController, let's update the store method to this:

[...]
public function store(Request $request)
{
    $plan = Plan::findOrFail($request->plan);

    if ($request->user()->subscribedToPlan($plan->braintree_plan, 'main')) {
        return redirect('home')->with('error', 'Unauthorised operation');
    }

    $request->user()->newSubscription('main', $plan->braintree_plan)->create($request->payment_method_nonce);

    // redirect to home after a successful subscription
    return redirect('home')->with('success', 'Subscribed to '.$plan->braintree_plan.' successfully');
}
[...]

Flash Messaging

Let's now implement some basic flash messaging to display notifications in the app in response certain operations. In the resources/views/layouts/app.blade.php file, let's insert this block right above our content since flash messages show up at the top before any other content:

Continue reading %Laravel and Braintree: Middleware and Other Advanced Concepts%

Link
SitePoint PHPScrum Rituals: Sprint Demo (20.1.2017, 11:47 UTC)

The following is an extract from our book, Scrum: Novice to Ninja, written by M. David Green. Copies are sold in stores worldwide, or you can buy it in ebook form here. At the end of the sprint, everything that was worked on for the current sprint is demonstrated for the team, the product owner, […]

Continue reading %Scrum Rituals: Sprint Demo%

Link
Nomad PHPDoes Your Code Measure Up? (20.1.2017, 05:01 UTC)

April 2017
Presented By

Adam Culp
April 20, 2017
20:00 CDT

The post Does Your Code Measure Up? appeared first on Nomad PHP.

Link
Nomad PHPSymfony Social Stats (19.1.2017, 19:16 UTC)

Recently my good friend Ryan Weaver of KNPLabs released a very interesting page of statistics for the Symfony framework. The page titled “Symfony Trends” shows pretty graphics of some of the non-traditional statistics. Most of the time when we look at framework stats they are things like page load time and pages per second, the …

The post Symfony Social Stats appeared first on Nomad PHP.

Link
Matthias NobackIntroducing the SymfonyConsoleForm package (19.1.2017, 12:10 UTC)

About 2 years ago I created a package that combines the power of two famous Symfony components: the Form component and the Console component. In short: this package allows you to interactively fill in a form by typing in the answers at the CLI. When I started working on it, this seemed like a pretty far-fetched idea. However, it made a lot of sense to me in terms of a ports & adapters architecture that I was looking for back then (and still always am, by the way). We could (and often should) write the code in our application layer in such a way that it doesn't make a big difference whether we call applications services from a web controller or from a CLI "controller".

As described by Bernhard Schüssek (author of the Symfony Form component) in his article Symfony2 Form Architecture, the Form component strictly separates model and view responsibilities. It also makes a clear distinction between processing a form and rendering it (e.g. in an HTML template). If you're familiar with Symfony forms, you already know this. You first define the structure and behavior of a form, then you convert it to a view (which is basically a DTO). This simple data structure is used to render HTML.

This strict separation of concerns has brought us a well-designed, yet fairly complicated form component. In my quest for "console forms", this was a great gift: it was actually quite easy to render form fields to the terminal output, instead of to an HTTP response.

I decided to rely on the existing Question Helper which allows console commands to ask questions to the user. This basically left me with the need for "bridging the gap" between the Form and Console component. This is a quick list of things I needed to fix:

  • Different form fields require different console question types. A choice type form field matches more or less with a ChoiceQuestion. But since the mapping isn't one-to-one, I introduced the concept of a FormToQuestionResolver which configures a Question object in such a way that the user experience matches to that of a web form field. For example: a password type form field gets transformed into a Question with hidden output.
  • It's relatively easy to ask single questions (e.g. "Your name: "), but it was a bit harder to ask for "collections", like "Phone number 1: ", "Phone number 2: ", etc.). I fixed this by introducing something called a FormInteractor which gets asked to arrange any number of user interactions that are required to fill in the form.
  • CSRF tokens aren't needed for console commands, so CSRF protection will automatically be disabled.
  • In some places this package relies on behaviors of the Form and Console component that are not covered by the Symfony Backwards Compatibility Promise. This means that for every minor release the package is bound to break for some (often obscure) reason. I have kept up with Symfony 2.8, 3.0, 3.1 and 3.2, but if things get too hard to maintain, I will consider dropping some versions.

A short list of changes in external libraries that have been causing trouble so far (I'm by no means criticizing the Symfony development team for this, it just might be interesting to share this with you):

  • The behavior of a ChoiceQuestion changed at some point, switching what was returned as the selected value (instead of the selected "key" at some point it started returning the selected "label" of a choice). See also my custom solution, AlwaysReturnKeyOfChoiceQuestion. Furthermore, around the same time the Form component switched the behavior of its ChoiceType form type, accepting an array of "label" => "data" value pairs, where I was used to providing the exact opposite (an array of "data" => "label" pairs).
  • Of course, there was the major overhaul of the form type system, where form types changed to being fully-qualified class names instead of simple names. I wanted to keep supporting both styles, so this took some time to get right. At some point, t

Truncated by Planet PHP, read more at the original (another 3905 bytes)

Link
Nomad PHPFramework Porn (19.1.2017, 11:00 UTC)

(No, not really porn. Totally SFW)  Today Taylor Ottwell, creator of the Laravel framework, posted the Framework Code Complexity Comparison. For those not familiar with “Cyclomatic Complexity” here’s the Wikipedia page Cyclomatic Complexity. Briefly, “Cyclomatic Complexity is a software metric (measurement), used to indicate the complexity of a program.” While Taylor’s post gives you the …

The post Framework Porn appeared first on Nomad PHP.

Link
PHP: Hypertext PreprocessorPHP 5.6.30 Released (19.1.2017, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 5.6.30. This is a security release. Several security bugs were fixed in this release. All PHP 5.6 users are encouraged to upgrade to this version. According to our release calendar, this PHP 5.6 version is the last planned release that contains regular bugfixes. All the consequent releases will contain only security-relevant fixes, for the term of two years. PHP 5.6 users that need further bugfixes are encouraged to upgrade to PHP 7. For source downloads of PHP 5.6.30 please visit our downloads page, Windows source and binaries can be found on windows.php.net/download/. The list of changes is recorded in the ChangeLog.
Link
PHP: Hypertext PreprocessorPHP 7.1.1 Released (19.1.2017, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.1.1. Several bugs have been fixed. All PHP 7.1 users are encouraged to upgrade to this version. For source downloads of PHP 7.1.1 please visit our downloads page, Windows source and binaries can be found on windows.php.net/download/. The list of changes is recorded in the ChangeLog.
Link
Rob AllenHomestead per-project crib sheet (18.1.2017, 12:33 UTC)

I wanted a drop-dead simple way to try and replicate a problem someone was having on the Slim forums. I couldn't reproduce with php -S which is my go-to for this sort of thing, so I thought I'd try Homestead.

I had recently listend to a Voices of the Elephpant episode with Taylor Otwell & Joe Ferguson where Joe mentioned that Homestead worked on a per-project basis too. I didn't know this, so tried it out. The docs are fine, but there's a lot there that covers the global installation option when I just want to get up and running on a per-project basis.This is my crib sheet:

1. Create project

$ composer create-project slim/slim-skeleton skelly
$ cd skelly

We just need a project that uses Composer. You probably have one already. If not, Slim Framework is a good choice!

2. Add Homestead to the project

$ composer require laravel/homestead --dev
$ php vendor/bin/homestead make

The make command creates VagrantFile and a Homestead.yaml for configuration.

3. Deal with IP address and hostname

By default, the Homestead vagrant box is set up on 192.168.10.10 with the hostname homestead.app. You can change this in Homestead.yaml.

Add the IP address to /etc/hosts. This only needs to be done once if you don't change the defaults.

$ echo "192.168.10.10 homestead.app" | sudo tee -a /etc/hosts

All done

We're all done, so we can use vagrant up to run our new website Go to homestead.app in a browser to see it. To shut down, use vagrant halt or vagrant destroy.

Slim home page

Link
Voices of the ElePHPantInterview with Shawn Mayzes (18.1.2017, 10:00 UTC) Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP