I have recently look into observable pattern and I understand how things work and the concept. I also played with it in my application but I want to find out how to use it when you want to make a plugin in a php application, because that was my main purpose.
I haven't found any decent example until now. I want to understand the concept of making plugin with observable and also a good and easy example would be nice.
By making a plugin I mean to have a standard application and want to do some particular stuff for every client, because not all the clients ask the same things I can't give them all the same application, so the ideas so to make a standard application and configure it for every client and I understand that something like that is called to make a plugin and It can be done with observer.
Observer/Observable pattern would be a good fit if you want to implement some kind of custom triggers/actions based on user or application/service actions.
For example, an identity/authentication service might implement a pluggable architecture using some kind of observer to let third-party plug-ins do something when some user authenticates, or some user is registered...
Also it should work in the UI, because you might be able to show a menu or add some visual component based on user interaction.
If you want to make a very free plugin based application, you might want to do a slightly different version of this.
Implement a centralized event control.
Each Plugin (serving as your controllers) registers there to be notified for certain events.
Now if you want to access some functionality, just dispatch a specific event through that central event control. You no longer need to know what plugin will respond to your event, you only need to know the interface of said event and the form of response you will get.
Now multiple plugins can register on a event, overriding or extending the results of other plugins. Or just allow completely new events.
This application structure takes a bit of patience to properly create all needed classes, but the end product is extremely decoupled -> flexible. Think of it as a form of MVC where the controller(s) dont need to know each other, they just know where to ask in a very generic form.
(I heard Zend2 tries a similar approach?)
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 am developing modules in socialengine4. Now I need to change the core functionality of the application. I need to make some changes in user signup process by adding some core features like proving auto complete fields.
I know this is a core feature of User module of SocialEngine. But This is not a good practice because any update of socialengine will override my changes.
I have searched the solution but couldn't be able to find any thing. I know if you want to change any thing in core modules of magento, it directs us specific way to do that. Similarly I want to know the process, how can I change in socialengine?
Regards
It depends on what you want to change on SocialEngine core.
To change the signup process (for example add a new step), you have to add a new row in this table engine4_user_signup and implement your new step.
If you just want to add some actions after a user signup successfully, you can add a Hook in your custom module.
To implement a hook in Socialengine, following these steps:
Define hook in manifest file, will be something like below
'hooks' => array(
array(
'event' => 'onUserCreateAfter',
'resource' => 'YourPluginName_Plugin_Signup',
),
),
In the plugin class YourPluginName_Plugin_Signup, add this method onUserCreateAfter
public function onUserCreateAfter($payload)
{
$user = $payload->getPayload();
//Do whatever you want
}
Hope this can help you.
I'm not the slightest bit familiar with Social Engine, but seeing that it offers plugins:
http://www.socialengine.com/customize/se4/plugins
… I feel rather safe to suggest that there's some kind of API that allows you to hook into, and probably override, whatever core functionality you're not entirely happy with.
If it's anything like Symfony, Drupal or WordPress, there more often than not is some kind of event, hook, action, filter, whatever, at a key step in the process. It should allow you to catch whatever core has come up with to that point, trash it, and entirely override and "redo" it. The key here is to have a thorough understanding of the APIs involved — no amount of asking SO questions will spare you from reading the docs.
What occasionally happens, that being said, is that the only plausible candidate event is uncooperative, in the sense that it comes too late and only allows you to "add" something extra to what has been done already. In this case, you can take the higher ground and fight back by finding an earlier event. Start an output buffer on it, and trash this buffer in the uncooperative event. Now, you redo things as the way you want them, without losing your changes during upgrades.
Note that doing the latter is not risk-free, though. If anything, it adds a huge burden on you: if core changes anything in this area that you've redone from the ground up, you need to make sure that your overriding it doesn't break when you upgrade the application.
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.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have been given a new task from the client which is basically creating a CMS for actors/singers and the like that client will be selling out to them.
It will basically be a package and would work out-of-box pretty much similar to WordPress, you just hand over to whoever buys it but of course this is not going to be a blogging platform. It will allow developers to:
Add plugins/widgets
Add templates/themes
I thought the Observer Pattern may be useful but I am not that sure about it. What you guys could suggest to create such flexible/extensible CMS in terms of:
Ability to add plugins (for example like WordPress)
Ability to add themes/templates (for example like WordPress)
Design Pattern
Any other things
Observer's fine, but you're going to have to consider going beyond the basic pattern. The canonical Observer/Subject pattern only sends the Subject object to the Observer, nothing else, not even why it's being notified.
Initially, the solution might seem like also including the reason for the notification to the Observer, but then you might end up notifying Observers that don't care about certain notifications. A better solution might be requiring Observers to also ask for a list of notifications they'd like to receive.
But that also presents a problem. In order for the Observers to actually attach themselves to Subjects, they have to be instantiated. Every single time. Even if they'd never be needed. That's silly.
So, we've quickly reached one of the canonical PHP implementations of plugins: "hooks". Hooks use the same concept as Observer/Subject, but the implementation is different in a very important way: the actual Observers aren't instantiated in order to Observe Subjects. Instead, Subjects send a notification to some variety of central repository. This repository is configured with a list of all installed and activated plugins (Observers), and contains a list of all of the events that each plugin wants to receive. Each plugin and notified only when the event takes place, often through a static method rather than by creating an instance of the plugin and notifying it. call_user_func_array and a good autoloader makes this incredibly trivial.
You can therefore create a simple Interface for all plugins to implement. Methods that you'll need include but are not limited to:
Something to fetch data about the plugin, such as it's name, author, official website, version, etc. Human-consumable information.
A method returning the events that the plugin wants to subscribe to.
An installation method, for things the plugin needs to do in order to install itself, such as manipulating the database.
An uninstallation method might be handy as well.
The (probably static) method that will receive event notifications and return whatever data is needed.
Depending on how far you take the plugin concept, you could end up with plugins that have user configurable options. You might need to take that into account. Down that road lies madness and configuration systems.
In order to make plugins effective, you're going to need to place hooks everywhere, and frequently work with end-users to add new hooks where they are needed.
Widgets can easily work in a similar way, as plugins that get called prior to page rendering.
Themes/templates, oh my. You probably have two big options.
Smarty, or a similar template engine. Or your own not-PHP template engine.
PHP templates.
This decision will be driven by your end users. Smarty is incredibly limiting, but if you want to make sure that only approved code runs in a template, it might be a viable option. Furthermore, it's not unsafe to allow editing of Smarty templates right in the application itself.
On the other hand, one of the reason Wordpress templates work so well is that they're pure PHP. They can call any method exposed in the Wordpress API, and even do their own interesting logic. If you expect your end users to be technically minded, or at least technically competent, then PHP templates are the way to go. On the other hand, allowing editing of PHP templates within the application can open up a huge potential security hole if a malicious user gets into the admin bits. You probably want to restrict editing to the filesystem.
While this covers HTML creation, you should also take CSS into consideration. Will your end-users be able to manipulate CSS directly? Will they want to? If your default templates include enough semantic classes, they can probably do a great deal of styling with not a lot of effort, if they know what they're doing. On the other hand, your end-users might not know what CSS is, so they might want, oh, say, color pickers and pre-built color schemes, and a color scheme chooser, and other such annoying things to build. It's probably best to think about those horrors now.
Miscellaneous things.
No CMS would be complete without the concept of drafts and publish states. I don't have any advice for you here, other than code this first. If your customer or the end-users want any sort of historical archiving, managerial approval mechanism, or anything else that makes draft/published anything but a simple state field, you need to know very soon. (I've been bitten horribly by this one. We'd designed the entire system around a simple published/not-published model, and got about 9/10ths through spec building and related prototype code when we realized it wouldn't work and we'd have to do something far, far more complex to actually meet customer requirements. Rebuilding the rough plan was the single largest time-sink we encountered so far.)
Will you use an ORM? If not, be sure to use a proper database interface library. PDO, or maybe something from PEAR, or maybe Zend_Db. You'll inevitably have a customer that will insist that the code runs on Oracle or MSSQL. Or SQLite. It'll be nice to tell them it can be done (with some effort). Plugin authors will thank you for the sanity as well. Don't roll your own.
(Then again, with your rep level, I expect that you're already familiar with pretty much everything I've said. Ah, the things I do to distract myself while thinking about my own set of coding problems...)
I'm working on a custom CMS for my own use and was thinking about implementing a plugin system so I could extend the code a little easier. I'm having trouble conceptualizing the architecture and layout though.
I know I could go through a few open source programs that implement similar features but this is really just academic at this point so I really don't want to spend too much time digging through foreign code.
Does anyone have any good ideas of how to proceed? If someone could outline how some of the more popular programs do it that'd be perfect.
Define the functionality you want the plugins to plug into (ie, what will they do and over what)
Define a class hierarchy on which plugins fit, like, all article mangling plugins should inherit from ArticleMangler
Define a physical location for plugins, like /plugins
Import all plugins present in the location
Use either Decorator or Observer patterns to inject the plugin's behavior or to notify the plugins of events occurence. Strategy might be applicable in some cases as well.
PHP makes this fairly easy at a potential cost of making a mess if you're not careful. I like the Observer method where plugins register themselves to a plugin manager which notify them of what happened and wait for their action to happen.
If you don't trust plugins then you'd have to put add controls over which events you are going to allow any plugin to register for.