Matthias NobackExposing resources: from Symfony bundles to packages (25.9.2014, 22:00 UTC)

Syfony bundles: providing services and exposing resources

When you look at the source code of the Symfony framework, it becomes clear that bundles play two distinct and very different roles: in the first place a bundle is a service container extension: it offers ways to add, modify or remove service definitions and parameters, optionally by means of bundle configuration. This role is represented by the following methods of BundleInterface:

namespace Symfony\Component\HttpKernel\Bundle;

interface BundleInterface extends ContainerAwareInterface
{
    /** Boots the Bundle. */
    public function boot();

    /** Shutdowns the Bundle. */
    public function shutdown();

    /** Builds the bundle. */
    public function build(ContainerBuilder $container);

    /** Returns the container extension that should be implicitly loaded. */
    public function getContainerExtension();

    ...
}

The second role of a bundle is that of a resource provider. When a bundle is registered in the application kernel, it automatically starts to expose all kinds of resources to the application. Think of routing files, controllers, entities, templates, translation files, etc.

The "resource-providing" role of bundles is represented by the following methods of BundleInterface:

interface BundleInterface extends ContainerAwareInterface
{
    ...

    /** Returns the bundle name that this bundle overrides. */
    public function getParent();

    /** Returns the bundle name (the class short name). */
    public function getName();

    /** Gets the Bundle namespace. */
    public function getNamespace();

    /** Gets the Bundle directory path. */
    public function getPath();
}

As far as I know, only getName() serves both purposes, since it is also used to calculate the configuration key that is used for the bundle's configuration (e.g. the configuration for the DoctrineBundle is to be found under the doctrine key in config.yml).

There are several framework classes that use the bundle name and its root directory (which is returned by the bundle's getPath() method) to locate resources in a bundle. For instance the ControllerResolver from the FrameworkBundle allows you to use the Bundle:Controller:action notation to point to methods of controller classes in the Controller directory of your bundle. And the TemplateNameParser from the FrameworkBundle resolves shorthand notation of templates (e.g. Bundle:Controller:action.html.twig) to their actual locations.

It's actually quite a clever idea to use the location of the bundle class as the root directory for the resources which a bundle exposes. By doing so, it doesn't matter anymore whether a bundle is part of a package that is installed in the vendor directory using Composer, or if it's part of your project's source code in the src directory; the actual location of resources is always derived based on the location of the bundle class itself.

Towards a better situation for resources

Let me first say, I think the BundleInterface ought to be separated in two different "role interfaces", based on the different roles they play. I was thinking of ProvidesServices and a ExposesResources interface. That would clearly communicate the two different things that a bundle can do for you.

Puli: uniform resource location

Much more important than splitting the BundleInterface is to have a better way of exposing resources located inside a library (or bundle, it wouldn't make a difference actually). This is something Bernhard Schüssek has been working on. He has created a nice library called Puli. It basically provides a way to locate and discover resources from all parts of the application, be it your own project or a package that you pulled in using Composer.

The core class of Puli is the ResourceRepository. It works like a registry of resource locations. For every resource or collection of resources that you want to expose, you call the add() method and provide as a first argument a prefix, and as a second argument an absolute path to a directory:

use Webmozart\Puli\Repository\ResourceRepository;

$repo = new ResourceRepository();
$repo->add('/matthias/package-name/templates', '/path/to/Resources/views');

Now if you ask the repository to get the absolute path of a particular resource, you can do it by using the prefix you just

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

Link
Matthias NobackSemantic versioning for bundles (25.9.2014, 22:00 UTC)

A short introduction to semantic versioning

Semantic versioning is an agreement between the user of a package and its maintainer. The maintainer should be able to fix bugs, add new features or completely change the API of the software they provide. At the same time, the user of the package should not be forced to make changes to their own project whenever a package maintainer decides to release a new version.

The most extreme solution to this problem is: the package should never change, the user should never need to upgrade. But this is totally useless, since the user wants new features too, they just shouldn't jeopardize their existing, functioning code. At the same time the package maintainer wants to release new features too, and they may even want to redo things completely every once in a while.

Semantic versioning assumes a package to have a version number that consists of three numbers, separated by dots, like 2.5.1. The first number is called the "major version", the second number is called the "minor version", the last number is called the "patch version". The semantic versioning agreement in short tells the package maintainer to increment the:

MAJOR version when you make incompatible API changes,

MINOR version when you add functionality in a backwards-compatible manner, and

PATCH version when you make backwards-compatible bug fixes.

You can read the full explanation of the concept and what you are agreeing upon if you say that your package "follows semantic versioning" on semver.org.

Symfony and semver

As of version 2.3 the Symfony framework officially uses semver. They also apply some extra rules for parts of the code (classes, interfaces, methods) which they label as being part of the official Symfony API by adding an @api annotation to the respective doc comments. Semantic versioning and public API labeling together this consistutes Symfony's backwards compatibility promise.

In short, Semantic Versioning means that only major releases (such as 2.0, 3.0 etc.) are allowed to break backwards compatibility. Minor releases (such as 2.5, 2.6 etc.) may introduce new features, but must do so without breaking the existing API of that release branch (2.x in the previous example).

Bundles and semver

I was asked by Paul Rogers from the Symfony Live London crew:

How should you version a bundle? Should it be related to the library version, like ElasticBundle does?

As a matter of fact, I had already spent some toughts on this issue. The answer to the first question is: apply semver, just like any package should do. And the answer to the second is: no. It should not per se be related to the library version for which the bundle provides a framework-specific integration layer. I think this second answer requires some more detailed reasoning from my side.

Bundles expose an API themselves

The code in a library package exposes an API. People are going to use that API in a particular way. They are going to instantiate some of the classes from the package with a particular set of constructor arguments. They are going to call some of its methods with a particular set of arguments. This is the reason why semantic versioning should be applied to such packages in the first place: the maintainer should not be allowed to change any of the things the user relies on, like class names, method names, required parameters, etc.

A bundle mostly doesn't expose an API consisting of classes and methods. The API of a bundle consists of *services, or service definitions, and parameters. These are different types of entities. Yet they share some characteristics: service definitions often provide constructor arguments in a particular order, they sometimes contain method calls used for setter injection, they are public or private, abstract or concrete, have a certain name, etc.

Some changes, like making a private service public won't make a difference for an existing user.

services:
    formerly_a_private_service:
        public: true

If a service was formerly a private service, the user could not have relied on it in any way that a public service doesn't support. So that kind of a change should not to be considered a backward compatibility (BC) break.

The other way around - making a public service private - on the contrary should be considered a BC break.

services:
    formerly_a_public_service:
        public: false

Some users may rely on it being public. For example they may call

$container->

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

Link
SitePoint PHPEssentials of LDAP with PHP (25.9.2014, 16:00 UTC)

Ever wanted a simple way to store address book style information and network information actually next to any kind of ordered information?

If so, then there’s a technology which has been around since 1993, one which despite not having the cool factor of such technologies as Node.js and Go, allows you to do exactly this. It’s called LDAP!

What is LDAP?

LDAP is short for Lightweight Directory Access Protocol and was developed at the University of Michigan around 1993, by Tim Howes, Steve Kille, Colin Robbins, and Wengyik Yeong.

In short, LDAP is an internet-ready version of an earlier protocol called X.500, which was developed back in the 80’s by the International Telecommunications Union (ITU) for managing telephone directories and directory services.

Whilst LDAP technically refers to the protocol, the name is often applied to the client and server as well. If it helps, you can think of it like SQL is for database servers; it’s the language used to interact with LDAP-enabled servers.

There are a number of LDAP-enabled servers around, the most common of which is Microsoft’s ActiveDirectory; which has been pervasive throughout their product lineup since the release of Windows 2000.

There’s an open source choice as well, one which we’ll be using throughout this article series, called OpenLDAP. It makes no assumptions as to the schema you’re using or the information you’re storing.

Here in part one of the series, I’m going to:

  1. Take you through the basics of setting up an OpenLDAP
  2. Show you how to load up a set of records
  3. Show you how to connect to it and perform some basic operations

Terminology

Before we do that, we need to look at a bit of the terminology. Continuing with the SQL analogy, there are a couple of terms which you’ll need to know, and which I’ll be using throughout the series, which you can find in the table below.

Continue reading %Essentials of LDAP with PHP%

Link
Lorna MitchellJoind.in at PHPNW's Hackathon (25.9.2014, 08:32 UTC)

With a week to go, everyone attending PHPNW is starting to get excited. One of my highlights of the weekend is always the hackathon; as an open source project lead it's fantastic to meet new contributors and get a chance to hack in person with them and the more established people from the project.

This year will be no exception: PHPNW's Hackathon is on the Friday evening - you need a conference ticket, and you need to tick the "hackathon ticket" box. Joind.in will be there and we've got a very big todo list so if you are looking for something to hack on, then look no further!

  • The original joind.in site is maintenance mode only. We'll accept bug fixes for that but new features should be added to http://m.joind.in instead.
  • The new http://m.joind.in is our main focus, there's plenty to do so just show up and we'll find something that's a good fit for your skill set.
  • The android app is under active development - if you have these skills (or want to acquire them!) then Rich will be hacking away on that. I suspect that there are some new features that might be available first on android, which would be fabulous :)
  • The iphone app has been somewhat abandoned but we have everything we need to help you to pick it back up again. If you're an iphone app user and you'd like to keep up with the new features added in the other platforms, then you probably want to hack on this for your own interests.
  • The API powers the new website, the android app, and countless other integrations with conference sites etc. This holds the business logic and database, so we'll be hacking on this whatever happens!
  • Also on our wishlist: more javascript widgets for speakers and events to use on their own sites, tool for importing talks, integration with OpenCfP ... really anything else you can dream up :)

How To Get Involved

Come and say "hello, I'd like to get involved" :) If you're super keen, then feel free to grab the development platform beforehand (it saves a lot of time on the night), by following the installation instructions here: https://github.com/joindin/joindin-vm. This will set up a virtual machine with all the various bits of database, API and website all configured correctly so you can start developing.

Are you coming along to the hackathon? Do you already know what you want to hack on? Leave a comment and we'll see you there!

Lorna is an independent web development consultant, author and trainer, available for work (interesting projects only). This post was originally published at LornaJane

Link
Hasin HayderHow to enqueue javascript files properly in the WordPress admin panel (24.9.2014, 21:04 UTC)
Link
thePHP.ccBrno PHP Conference (24.9.2014, 07:00 UTC)
Link
Nomad PHPHTTP with GuzzlePHP (23.9.2014, 21:06 UTC)

Presented by Jeremy Lindblom @jeremeamia Guzzle is both an HTTP client and a framework for building web service clients. It gives you all the power of cURL, but is really easy to use. With a sleek, event-driven request system and the ability to make requests in parallel, Guzzle should be a permanent part of your …

The post HTTP with GuzzlePHP appeared first on Nomad PHP.

Link
Nomad PHPLicensing and You (23.9.2014, 21:02 UTC)

Presented by Chris Tankdersley @dragonmantank No matter how much work developers do in the open source world, they are confronted by a myriad of different licenses for things they want to use. GPL, MIT, BSD, Apache… these are just a few of the different licenses PHP devs deal with. What is the difference, and if …

The post Licensing and You appeared first on Nomad PHP.

Link
Brandon SavageMaking your development process suck less (23.9.2014, 14:00 UTC)
One of the easiest ways to start an argument in developer circles is to propose making a change to the development process. The means of developing applications is so crucial to the process of developing software that everybody has an opinion, and they’re convinced that their right. One company I worked for had a terribly […]
Link
Hasin HayderFetch WordPress media files using BackboneJS (23.9.2014, 06:56 UTC)
Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP