Download the PHP package redgem/servicesio-bundle without Composer
On this page you can find all versions of the php package redgem/servicesio-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download redgem/servicesio-bundle
More information about redgem/servicesio-bundle
Files in redgem/servicesio-bundle
Package servicesio-bundle
Short Description ServicesIO is a Symfony bundle that provides a way to easily build a services provider
License MIT
Informations about the package servicesio-bundle
ServicesIOBundle
ServicesIOBundle is a Symfony bundle that provides a way to easily build a services provider.
ServicesIO basically introduces two components :
-
a reader. the reader build for you a model that wrap the input data.
- from the standart input (i.e Request object).
- from a third party service you want to request.
- a view layer to scaffold an object tree view of the reponse. The view layer is called by your controller, build the tree you want to render, and actually render it (json only so far).
Install the bundle
First of all, add and enable ServicesIOBundle in your project.
Add it in composer :
composer require redgem/servicesio-bundle:1.0.*
All set.
ServicesIO Model
The model will help you to read and decode trees structures (such as json) passed, for instance, as requests to your controllers.
documentation of the Model component to come later
ServicesIO View
You are probably used to Twig to build and render your HTML views on your projects.
The aim of ServicesIO is to be able to get something as powerful and efficient for data trees that Twig could be for HTML.
Overview
ServicesIO view provide you the ability to create :
- re-usable view components callable by path configuration.
- extensible view components, with datas placeholders and smart way to fill them.
- integration with bundles extension, to override view components by extending bundles.
Here is what you need to know before starting :
-
The view rendering system runs by a two-steps system :
1 - you will build a tree in your view on a language agnostic datastructure by creating connected nodes. a node is composed of 3 available elements :
- a Collection, than handle a list of others nodes.
- an Item, than handle named fields with nodes attached.
- a scalar, that will be the piece of data to render (i.e string, int, float).
2 - the rendering of the tree. Once it's fully build, we will be able to turn it into a data langage (only json so far) and send it to output.
The basics : create your View
Now, let's see that in action with a short example.
To make it easy to read, I will remove all code that is not related to our topic.
Let's create a small example project : 2 entities and 2 controllers.
The Doctrine entities :
I assume to have 2 users : author and visitor and 3 entries for messages : message1, message2, message3.
Here are the controllers (without their return calls) :
Based on that, we now have to create the View elements for decorators and entities, and call the rendering from the controllers.
Let's complete first the messageAction's View, with a ServicesIO view class.
A basic View
class has to :
- extends
Redgem\ServicesIOBundle\Lib\View\View
- location is up to you, we recommend using
<APP_OR_YOUR_BUNDLE>\View namespace
(and therefore in the<APP_OR_YOUR_BUNDLE>/View
directory) to make a clear organisation. - implements the
content()
that is the place to build the view tree. - class name is also up to you, we recommend to name it
<NAME>View
.
We are here creating a simple tree with an Item object that containt 3 childrens : id, title, description to display our 3 corresponding message fields.
Finally, let's make the controller calling and rendering it :
The rendering service to call in ServicesIOBundle is called Redgem\ServicesIOBundle\Lib\View\Service
.
The call takes 2 arguments :
- the viewpath. the view class name.
- an array of parameters to send.
The single variable sent as a parameter in the controller is accessible as $this->params['single'] in the view class.
Let's call it for the first message for example !
Nice, we now have the json representation of the MessageView class tree !
We can now replicate it for the listing action :
Let's call it, and :
Excellent !
Partials views and fragment controllers
We have a problem. We did repeat ourselves between the 2 classes to create the partial view of a message.
Fortunately, there is a solution, : to create a reusable element.
As yu can see, a reusable element is a totaly regular View class. That mean, you may use it to render directly a controller if you want to.
Finally, we use it on our SingleView and ListingView :
When calling the partial()
method to get the subtree from there, it will pass for you the current context (i.e params you sent from the controller) merged with the params you add in the second method argument.
Of course, the json final rendering is still exactly the same.
Let's now enrich the data response everywhere with a new UserView :
and
A single request will now display :
In addition to to partial()
method, a controller()
method is available. Instead of calling just a view, it will call a whole Symfony controller as a fragment.
Its prototype is :
function controller($controller, $params = array())
with :
$controller
: a regular Symfony controller name (as a string, with full class name)$params
: an array, that will be merged with current params context and passed to the new controller.
The response will be handle on that way :
- If this new controller return a ServicesIO view response, the fragment tree will be merged on the main tree at the right place.
- Otherwise, the response will be threated as a string and merged on the main tree at the right place.
And one more thing :
get($service)
- string $service : a Symfony service name.getParameter($parameter)
- string $parameter : a parameter name.
methods are available as well. They just use the container to call a Symfony service or a parameter.
View extensions
We now want to decorate our response with the connected user on the top of it. It's easy to do with this controller()
method.
I assume that the user is correctly authenticated by the Security component :
And I add that to my views :
A single request will now display :
And my problem of repeating myself is back... on the global decorator. I have created twice the main object with visitor and response.
We can solve it by changing our way of thinking. Instead of having only one class to build the tree, let's split it into 2 elements :
- a class to build the main decorator node (i.e, with visitor and response)
- filling the fields of the response node by each view classes.
First of all, let's create the decorator thing. It's still a regular View class :
There is a new third argument on the set()
method. This third argument is a string, and set up a name for the placeholder option. The placeholder is an entry on the tree that can be replaced later by an another value.
In case of placeholder, the second value (null here) is a default value that will be displayed if the placeholder is not filled.
We can now transform our SingleView and ListingView to use this decorator :
We can see two differences :
- a new
getParent()
method appeared : that means that the root node will be deported in this view class. All the context is passed to this object, and obviously, this is a standard View class you can reuse where you want. - the
content()
method is replaced by the blockFullResponse(). Thecontent()
method is the method that create the root node of the tree. It's therefore not compatible with thegetParent() method. A class with a getParent()
method will only fill the placeholders defined above it. This is the purpose ofblockXXX()
where XXX is the placeholder name in CamelCase. methods (i.e blockFullResponse here).
You can of course chain how many levels oh hierarchy you want with getParent()
and define placeholders into all of them.
getParent()
usually return a string. It can also return an array :
In this case, the first actually implemented View class will be chosen.
Why all those fancy stuffs ?
Why doing that ? You may say it would be easier to use the regular extends PHP word for classes, and avoiding using viewpath, and you would be right. But ServicesIO view do provides you an easy, flexible, and clear way to build some view reusables pieces.
So Finally, we can call our controllers :