I am creating a web application in PHP. It is built with multiple independent modules. For the sake of example, let's say there is an email module and file explorer module. Each of them have physically separate folders with different libraries etc. However, in the frontend they both have the same interface (navigation is the same and content in the center is changing).
I want to centralize my interface in the backend. How could I create some kind of two step layout so whatever app is called on the backend, the content of it is merged with outer interface and then sent back.
I want to make this because if there is a change in the outer interface, I have to copy code in all of the modules.
Below is the example mockup to show you what I mean. Content interface is changing and static outer interface is always the same no matter the app that is chosen.
How could I achieve something this elegant?
It could be worthwhile spending some time seeing how likes of Laravel 4 and other similar frameworks achieve this (if you haven't already that is).
For example in Laravel 4 it is reasonably easy to separate an application's business logic into modules, and share certain parts of the views across these modules using layouts, eg. you can create a master layout template that includes the master static outer interface as you show above, and then each of the individual module templates can extend this with a simple
#extends('layouts.master')
at the top of each of the content interface views. More details here - http://laravel.com/docs/templates
I am not suggesting that you use Laravel, but it is likely that you can find the answer to your question in one of the existing php frameworks - even if you copy their solutions rather than adopting the framework it may be quicker than reinventing the wheel :-)
Glen
Related
Background:
I currently have a web application based on MVC Kohana PHP framework, that allows users to sell ebooks to their customers.
The code behind the webapp is all wired together and everything but API-centric.
It is running pure MVC and then using mustache for template system.
What I would like to do:
I would like to integrate various accounting services (from bigger nordic providers like e-conomic.com) but also own integrations that will let users to optimize their selling and so on.
What I would like to archieve is to make something, call it an engine, that allows functionality integrate (flexibely) into parts of the webapplication, whether its in the view-part or controller/logic.
Based on the background and looking at the technical point of view, which ways are there to do this?
My thoughts is that I need some kind of placeholders all over in different areas of the webapplication. Then I need these placeholders to work together with a "engine" that then checks integrations wants to "run" in these areas?
Would that even work? What would you do?
Update trying to make it more clear:
So what I would like to accomplish is to have separate functionality that would integrate into the existing main webapplication.
Let's just say I have a folder called integrations/ and in here there is two different integrations that affect different parts of the system.
The first is a Kashflow (accounting software) integration, that grabs some data from our system and send to Kashflow (API way, fine) but also inside my webapp under "orders" states whether it has synced to Kashflow yet or not. (this is the part the question is about)
Another integration could be a "Featured Ebook" integration. This simply lets you pick what product should be featured and then on the ebook store, the featured product will be highlighted with a orange border around it and some bigger text. (this is the part the question is about)
How are the bold marked working? A webshop provider like Shopify has Apps which does this, and all other SaaS with Apps have this technical solution.
I wonder is it? How can I allow separate functionality affect a base webapp?
I hope it got more clear now.
New update:
What I look for answer is an answer based on the above stated background, how I can implement a solution that would allow this from where I am now.
A good answer would be one that also in text / pseudo way could give a description on how one of the example plugin/integrations i mentioned could be implemented.
So how does the integration communicate with the main application, what does the main application have in order to accept/allow functionality.
Let me start from the very beginning.
What you are looking for is called a service layer which should be implemented in your applcaition. What it does is
Defines an application's boundary with a layer of services that
establishes a set of available operations and coordinates the
application's response in each operation.
Enterprise applications typically require different kinds of
interfaces to the data they store and the logic they implement: data
loaders, user interfaces, integration gateways, and others. Despite
their different purposes, these interfaces often need common
interactions with the application to access and manipulate its data
and invoke its business logic. The interactions may be complex,
involv-ing transactions across multiple resources and the coordination
of several responses to an action. Encoding the logic of the
interactions separately in each interface causes a lot of duplication.
A Service Layer defines an application's boundary [Cockburn PloP] and
its set of available operations from the perspective of interfacing
client layers. It encapsulates the application's business logic,
controlling transactions and coor-dinating responses in the
implementation of its operations.
Let me explain it simple terms so you can understand. What you 1st have to do is define a service layer in your application. Since you are going with MVC, this could be another controllers handling all the requests related to this specific task. You can have separate controllers for each couple of operations. At the end your engine will be these set of controllers.
If you are willing to go to next level you can handle all these integration via an ESB(Enterprise Service Bus).
An enterprise service bus (ESB) is a software architecture model used
for designing and implementing communication between mutually
interacting software applications in a service-oriented architecture
(SOA). As a software architectural model for distributed computing it
is a specialty variant of the more general client server model and
promotes agility and flexibility with regard to communication between
applications. Its primary use is in enterprise application integration
(EAI) of heterogeneous and complex landscapes.
If you need more information let me know.
Update
There are well documented blog posts. Please see the links below.
How essential is it to make a service layer?
Service Layer Guidelines
Based on your update, I think you describe a good case for a web application that needs to become modular. You want to be able to easily add new modules (plugins) that give you different functionalities without having to change the application core each time.
Below is a possible solution to your challenge from conceptual point of view. My intention is to help you grasp on the idea and get you started. Keep in mind that it can be simplified further or become much more complex, depending on your needs.
The theoretical side of things
Plugins/Modules
Each plugin will enable a set of specific features and must be able to work independently from other plugins that are enabled at the moment. All plugins will have to follow a common set of rules and conventions in order to be recognised by your application. This will simplify future maintenance and extension immensely. For example, each plugin should:
Have its own subdirectory under the Plugins/Modules folder that follows a predefined structure (e.g. Backend/Portlets/InstallScripts, etc.)
Use separate storage sandbox in your database, dedicated only to this plugin. Take Kashflow – all tables that are used by the plugin can start with a ksflw_ prefix.
Bring its own partial Frontend view presentation(s) (along with underlying controller logic and model) that implement specific sets of functionality (for example, display pre-selected books in orange border)
Bring its own partial Backend view presentation(s) (along with underlying controller and model) that handle in the site backend (in the case of Kashflow you have portlet visualization that maybe renders a button to manually do synchronization, enables you to schedule one and displays the datetime of the last synchronization made)
Have an installer script, that creates tables, inserts menu items, and initialises hook subscriptions (see next bullet)
Initialize Hooks subscriptions – All subscribed Plugin functions get called whenever a registered event occurs somewhere in the system.
Core functionality changes
You will need new functionality in your existing application in order to start supporting plugins.
Plugin manager – GUI that allows you to install, remove, enable/disable plugins and allow access to them for your clients.
Partial views manager – allows users to select which partial views of which plugins get displayed in what existing placeholders (this will work in conjunction with hooks)
Placeholders for partial views on pages in the places you want to enable your users to display plugin UI and information
Hooks throughout the application – Whenever "interesting" event happens, the system checks if any plugins are currently subscribed to this event and calls/notifies them, then displays the result. Some examples of events that deserve Hooks might be:
Placeholder rendering – this will trigger all subscribed functionalities to display a frontend/backend partial view
Specific business events – e.g. Whenever new book is being added to the catalogue or is being sold
Administration menu rendering – On this event each installed plugin will select all menu items in the PLUGINNAME_AdminPluginMenu table (the plugin should have created this table at install time) and return all them to the hook for displaying.
I'm sure you'll think of other relevant events, as you know your case best of all.
The practical side of things (based on the second update of the question)
1. Leveraging HMVC for visualisation of partial views (widgets) inside of existing views
As I already stated earlier, Kohana supports HMVC or Hierarchical Model View Controller pattern. This means that you can have a hierarchy of controllers like so (already described in the following question):
Now, this enables you to easily call controllers from other controllers and even directly from your views! And it works wonders when you need to embed widgets.
You can make a slight modification to boostrap.ini in order to enable Routes like widget_controller/controller_action/action_parameter (this is described in detail in the tutorial I'm giving you below). Then you can have the following code inside your main view template where you want to render your orange book box:
<div class="widget_sidebar">
<?php echo Request::factory('widget_orangebook/display/3')->execute(); ?>
</div>
When executed, this acts as a hook and will invoke the widget_orangebook controller's action_display method with parameter 3 - e.g. you want to show 3 books.
The controller's action will look something like this:
public function action_display ($number_of_books){...}
As a result inside the <div>, you will see the content of the template set by the widget_orangebook controller after execution of the action.
In a sense it gives the illusion of an AJAX partial rendering, but its being executed on the server without the extra call. It is pretty powerful, and I think this is the way to go for the cases you described.
You can see this tutorial to see a detailed description on all the modifications you need to do. It's a bit fancier - it's about rendering multiple widgets in a widget section, but it follows the same logic.
Note that if you insist on using mustache and logicless templates, you can also do this kind of Request call in the controller, set the result to a variable and then pass that variable to your mustache template.
2. Kohana Modules
Kohana supports modules, that allow you to pack up your plugins in an organized way. As you implement more complex plugins this will become important. You can see more on Kohana Modules here.
I'm starting to look at Object Oriented PHP. To date I've developed a large number of PHP systems with a procedural approach, but I think it's time to move forward.
One of the projects I'm working on at the moment is a Grade and Handicap Calculation plugin for WordPress. In short, the plugin takes table tennis players' results from uploaded CSV files and works out their grading for handicap tournaments.
I'm using WordPress because my table tennis club's website uses WP and if it works for them I can potentially give it to other clubs/leagues and they too will be able to install the plugin and have access to a fully-fledged grade and handicap system.
Outside of WordPress, I'm reasonably confident that I could develop such a system in OO-PHP using the MVC pattern. It would probably look something like this:
Controller
Create an instance of the Model
Deal with "navigation", i.e. GET/POST requests, and work out which page templates to display accordingly
Model
Deal with uploading and storage of files
Update and select information from database
Host mechanism for working out players' grades
View
Admin pages, i.e. settings and uploading files
Grades page, displaying players' grades and handicaps
Results page, where specific users can see individual players' results (mostly for debugging purposes)
Please correct me if I'm wrong, as I've only learnt this pattern in the past 30 minutes or so, but by my logic that is a true MVC approach to creating this system.
However, once I bring WordPress plugins into the equation, I'm starting to struggle with the following questions:
In the non-WP system, CSS styles would simply be included in the View's PHP pages which I'd then include in the Controller. However, in WordPress, it doesn't work like that - I can't use CSS styles in that way, they have to be enqueue'd. Where would I host the function for enqueueing my CSS files?
When someone first activates the plugin, it will need to create the appropriate database table using WordPress functions to do so. This would then have to be run off a hook, i.e. a register_activation_hook. Where would I host these functions? It would seem sensible to put them in the Controller but at the same time I'd imagine that maybe the Controller needs to be kept as clean and simple to read as possible.
Similar to the above question, I also need to create WordPress admin pages using add_menu_page and add_submenu_page commands. Where do I host these functions?
All of these questions probably have the same answer, and I know it's just semantics, but I'm keen to try and get this right early on so I can truly get my head round the MVC pattern of Object Oriented PHP.
Thanks in advance,
If you are looking for a better place for learning MVC, this would be it.
Hope I'm getting this right.
Can't tell you about CSS, as I just keep those defined in my layout files (view).
Heavy logic can be put into services (external Class), and then being ran in controller. You'll keep your controller 'thin'
Similar to previous one. You can have your menu stored as a model (which doesn't have to be strictly DB related, but also XML/JSON/array data), and then call your add/remove actions in controller.
I'm working on a task management application for use at my company. Part of the spec is to create a plugin system that lets users customize and extend the functionality as they need, or as their department requires. I'd love to do this in a really elegant and modularized way, but I'm having a hard time figuring out how.
Consider a view that's a task list: each iteration of the generating loop adds a pre_task() and post_task() call on either end, which builds the interactive pieces on either end of the task title (Complete checkbox, comments link, etc). Now, when the system detects and includes the plugin file plugin_time_tracking.php, the plugin should add functionality to post_task() - adding a "track time" button in addition to everything else.
What I'd like to accomplish is making the plugin "hook" onto pre_task() or post_task() - let it do all the legwork by attaching itself to the proper functions and extending them, instead of having the core sort plugins and herd their functions to the right places. Does PHP offer such functionality? Am I going about this the wrong way? Let me know if I need to clarify at all - thanks for the help!
The boys of Qafoo gave a talk about modularity on the 2012 edition of the PHPBenelux conference. They presented various options to create modular applications such as hooks, patching and inheritance.
You could check out the slides of that presentation here.
I think you should really use a framework that has a built in plugin infrastructure with capabilities to override/inherit. As an example, let's say Symfony2: in sf2 you could create FormType classes that build the form objects (which then pass certain data tot he view). So in this case to add fields another team would simply need to extend your FormType and modify the build to add new fields. Further the Form Api supports embedding subforms so if they want time track then then just need to embed that in the task form or "turn it on" through whatever configuration facilities you supply.
Similarly with render things, you can define override the view template simply by providing at a different level or referencing a different Bundle (a plugin of sorts).
Now Symfony2 is very complex and it has a high learning curve so it may or my not be the framework you should choose, but something along these lines would be more than appropriate. The WP/Drupal pattern of "hook" functions is incredibly annoying to work with, especially if they are building HTML strings on a deeper layer and not giving you the raw data to output as you see fit.
I'm relatively new to design patterns but I feel that I've got a good understanding of the MVC pattern and the advantages that this separation of code brings.
However, both times I've seen the MVC pattern in action (Magento and Joomla!), there is further specialization, with the view consisting of both a view class (Magento block) and a PHP template file. I would appreciate it if someone could explain the benefit of this split.
I'm also at a loss as to how to split my code between the view class and the template file. Sometimes I find myself writing what seems to be a redundant view class (in Joomla!) which simply accesses the model and then just makes the data available for the template. What code should appear in the template and what code should appear in the view class?
View, in MVC-inspired design patterns, are responsible for all of you UI logic. They should be requesting information from model layer and, based on what they receive, choosing which templates should be used for creation of the response. Or even if any rendering is required (view can just as well just send a HTTP header).
You could say that in classical MVC and Model2 MVC patterns, the view only reads from model layer, but controller only writes to it.
If you receive some error state from model layer, the view takes the main layout template and supplements it template, which is contains HTML fragment for error messages. Then it assembles the whole thing an shows to the user (which, in case of web applications is the browser).
Templates, in your basic web application, are just simple files with a mix of tags and php variables.
You can consider the view as the what and the template as the how.
The view prepares the data by using the model and makes this data available to the template.
The template, in turn, is usually called (in Joomla!, at least) in the view's scope.
This may seem kind of redundant at first, but the power of this approach is revealed when using template overrides. Then, the view can be left alone, and only the template (or sub-templates, for this matter), be overridden.
Even using the same main (Joomla!) template, you may specify a different view template as a parameter, in case you need some specialization of presentation. This also eliminates code repetition.
For example, say you create a new main template. You can override some of the default views/templates and leave some others untouched. Then, you can create a new view, say, blog view, and also 2 templates for it, light spaced and dark dense, to be used in 2 different scenarios. This way, you only have one view to prepare all of the what and several different templates to take care of the how.
In the general case, the split between a 'View' and a 'Template' is so that if you are going to present the view data via different methods [ie. HTML, XML, JSON, etc.] then you do not need to keep rewriting the 'View' class, only create new 'Template' classes. This is useful if you want to incorporate AJAX calls into your front-end, or make calls from other applications like a smartphone app for instance.
Read this http://www.codinghorror.com/blog/2008/05/understanding-model-view-controller.html. To me MVC means registering a function to an array and loop through that array and eventually call a function in the main program. But for many people it seems to separate the model (database) from the view(html template) and the controller (the main application). But that's not what I would think is special about a program. When you develop web application naturally you have all this backends like database, browser, backend and frontend, html, css, image files, video files and php language etc. Why this is put into complicated words confusing the developement? I think MVC is to general to be useful. Learn the decorator pattern it's much more useful.
To be honest...the best option for performance is to create web services in the backend and use a javascript library to talk to the server. joomla and other cms distributions try to abstract both of these design patterns into the MVC causing a hybrid of MVC and web services/ client-side code. such a hybrid nature allows for extensions to be extended into the javascript landscape which seems to be the direction the web is headed.
I have a pretty large site, and I am looking for the most time efficient way to manage it (I am the sole coder).
I am trying to devise a very simple MVC structure (i don't want to use a framework) to help keep all my code in order.
For a huge site, is it better to have only one controller to handle all the pages, or is it better and easier to split them up?
If just one, what is a good example of a non-framework controller?
I would split any logical divisions into different controllers - if it's all static pages, then serve it up with all the same 'static page' controller.
If you have some static pages, a FAQ page (or section), a product list - use a controller for each different section. So the static pages would be pulled from flat files or a database by one controller, the FAQ pages would be generated from a FAQ table by another controller, the products and info would be generated by whatever the source for that is.
Every time the way a page is generated or the data is accessed, use a different controller.
Of course, class inheritance can be used to create the base class with the code needed by any controller.
Not sure what you mean by a non-framework controller - I'd checkout the Zend (gasp) 'Framework', the MVC pattern, and even the controller itself, can be used apart from the rest of the framework.
I tend to split the controllers up based on their responsibility to a specific section of a site/application. This makes maintaining the code so much easier. Furthermore, I group controllers (and views, models) within modules (folders). Here's an example from a current project I'm working on:
Blog
Posts
Comments
Categories
Settings
Posts
Users
The more complex a site, the more modules I use. Although most of my modules only contain one 'Index' controller, I do like the organization they provide.
Then I use a router (front controller) that maps a REST style URI to the proper module / controller / action. Ex: mysite.com/blog/posts/view/7 would call Controller_Posts::view(7) from the "blog" module. An added benefit of using modules is I can have more specific URIs than if I didn't have modules. Although I suppose that could be remedied by using a router that supports defining custom routes, but I'm not too fond of that.
As many other things, it boils down to what you're comfortable with as a developer, but we can probably agree that more organization you have, the better off you are, so long as you don't over complicate things.
As a quick aside, I would recommend you look into using a framework. I understand if you don't want to use one of the ones out there already, as I avoided those too. I ended up writing my own which for the past year has served me very well. It was a great learning experience and it only contains what I want / need. That being said, you might want to look into Kohana and CakePHP - they're not overly bloated IMO and they will definitely save you time should you decide not to write your own.
Typically people split up controllers into controllers focused on specific areas of functionality.
Then they stick a "front-controller" in front of it all, so there's only one entry point to the application. The front-controller's only job is to route incoming requests to the appropriate controller.
Look at the way the Zend_Controller component is set up. It may provide everything you need, and you're free to use it without buying into the complete Zend Framework.
It depends how you other parts will work. If you only have one model file then it's probably not worth splitting up the controller. If you can split up the model into sections as well as the controller, then do that.
However, I often find that there's too much overlap between models to separate them. You might have a model for articles, but if you want to display the top 20 articles in a sidebar on other pages, that code should be in the article model - and you're going to need that on every page.
Honestly though, the only way to do it is try it and see. Start with a single entry point, and if it gets too, unwieldy, refactor it into smaller chunks.
One router/dispatcher, many controllers would be my advice. Controllers ought to map to URLs, which means differing functionality. A controller will collaborate with different services to accomplish each use case, so one controller for your entire app would become too unwieldy if your app has more than a handful of use cases.