The MVC approach to OO-PHP and WordPress plugins - php

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.

Related

Converting PHP site to Joomla

I have a large complex web site currently implemented using PHP and MySQL.
Some of the pages (about, contact us, etc) are largely static, but need to be updated from time to time. I'd like these updates to be able to be done by non technical admins, so I'm migrating the site to Joomla CMS. I've created a Joomla template to reproduce the banners, styling etc of my existing web site and have successfully reproduced the static pages by cutting and pasting into Joomla articles.
I'm now trying to embed my existing dyanamic php pages into the Joomla framework. I assume that I need to convert them into one or more Joomla components? I realize that I'll need to strip out the php code that currently generates banners, menus, etc, but I don't want to make major changes to these php pages, i.e. I don't want to re-implement them to follow an MVC pattern. I'm looking for a simple Joomla 3.2 hello world component tutorial. The tutorials that I've found are either too complex (i.e. MVC) or they're "too simple". By too simple I mean the component is not listed when I select Menu Item Type within the Menu Manager. Can anyone point me to any documentation that explains the minimal config that I need to include in a custom Joomla 3.2 component in order for the component to be listed when selecting Menu Item Type?
Also, should I create one big custom component to wrap my existing PHP application containing multiple pages("views"?)? Conceptually there the system could be considered as about 3 sub-systems, but there is some overlap between the MySQL tables used in these different sub-systems.
I don't need the implementation to be portable, i.e. I'm not trying to create a reusable component that others could use, I just need it to work on my site, using the least amount of work possible.
Thanks, Wayne.
I hope to clarify a bit and give you way out.
In response to your comment on #user3057084, the power of Joomla and its flexibility comes from it being MVC! If you want to wrap your existing code with little modifications, Wordpress will let you do all kind of nasty things! Nasty in the sense of mixing logic with data, i.e. copying and pasting your code and getting it to work quickly.
Joomla coding standards require that you separate models from views. And that you understand how the Joomla MVC implementation works. It will take longer, but you'll learn a useful skill that can and should be applied if you want to write portable maintainable code following Design Patterns.
Now about the way out.
Nothing keeps you from putting your raw php code in a Joomla view, including the database access. It's really ugly and I feel bad even suggesting this, but if it can be a small step towards using a great framework, then the end justifies the means.
The absolute easiest way for you in Joomla would be to create a template override (which you'll do from the admin with a few clicks in the template manager), then throw your code in, and it will run. Then, a little bit at a time, you might learn to separate the parsing of the input in the controller, store / retrieve the data in a model, and leave just the markup in the view.
But are you absolutely sure you need to code for this? There are thousands of (free) extensions out there that might do the job for you with no coding and little configuration, leaving you just a data migration to handle.
Have you had a look at Wordpress yet? In my experience, non-technical people find it easier to administer a wordpress website in comparison to a Joomla website.
When it comes to the menu structures,themes and contact forms and blogs - Wordpress takes the cake.
It would be worth your while to check it out? It might save you hours of frustration?

How to modularize CodeIgniter?

Well, I have been thinking a lot about the first real CodeIgniter site I am coding. I want to modularize the site in such a way that I have a controller that formats the navbar, one that formats a multipurpose right column, and one that formats the content area.
My idea is to have a controller for each state of any part of the site (an example would be the right column, it would have 3 states; new posts, related posts, and search filters). I would also have the content area be many different states aswell (things like search results, view post, new posts, etc).
The problem is that I can't find a way to take multiple controller outputs and compile it into a single template (notice, I said controllers, not views).
I have seen the HMVC extension, but that is going to far for my first site, and am hoping for a more simplistic solution (unless you can prove me wrong, and show that HMVC is easier than what I've seen).
This seems a little wonky to me in an MVC model.
If you're using a single stateful view for your right panel that might change state based on input (i.e. which page the user is currently on), then I would add a model for the panel. The controller's action would be responsible for setting the correct model state (i.e. "you're in home page state"). The model could be responsible for telling the right panel view which child views to load.
That's how I'd probably implement something like that anyway. HMVC seems overkill and with this example, wouldn't be used as intended.
For what you're trying to accomplish the matchbox module suggested in the comments seems way overkill. I don't think that using controllers to format each of these areas is a very good approach to take.
Usually people who want the type of functionality that you're describing when working with CodeIgniter end up using a template library. There are several open source template libraries for CodeIgniter that can easily be found with a google search for "codeigniter template library".
I've never used any of them so I will not recommend any particular library. However the app that I'm working on has borrowed some ideas from Phil Sturgeon's template library. You may not find an exact match to features that you need but at least you'll be able to draw some inspiration from solutions that others have come up with.

CodeIgniter Team Work

I've been learning CodeIngiter and up till now but can't seem to get a grasp on how CodeIgniter can be used to work as a team. Can someone explain the basic of team work using CodeIgniter?
From what I understand, it's like this so correct me if I'm wrong :
Let's say there is a project with 5 pages, Home, About Us, News, Gallery and Contact Us. Where CodeIgniter can help is let's say I have 2 programmers in my team, so each one of us do a module (for each Controller-View-Model) (for example Programmer A does News module, Programmer B does Gallery module) in different folders (folder news and gallery), etc.
So the end product will be a group of modules in seperate folders. home/ , content/, news/, gallery/, contact/ , etc.
Is that the right flow of teamwork using CI? I read that CI can be used to collaborate between designers (front end CSS) and programmers (database and controller) but I think with this flow, designers will have to wait for programmers to get the variable names to be parsed into the view and that will somehow halt the progress of the work.
I currently work in a team environment with Codeigniter and I'll tell you generally it flows like this.
Designer produces Designs coded out (html/css) with static content. (no variables)
While he is doing that Myself and others are working on the data model we are going to use and writing Model Methods we can forsee needing to interact with the data in a way our application will utilize.
Then the Designer hands off the static layouts, I "cut them up" into header/footer/etc... and replace the static content with the variables by writing the controllers to accomodate.
As a bonus I would highly recommend using some sort of version control with your team, depending on your needs I usually stick with SVN or GIT, GIT is a little more accommodating to distributed teams that are not in a centralized location. This will greatly improve efficiency and prevent ( or mitigate ) situations in which two people end up working on the same file and someones work gets overwritten, and other situations that occur when multiple people are working on the same files.
CodeIgniter is just one way of doing of Model-View-Controller. You probably don't need to divide things up into separate modules or folders; instead, you'll probably want to create files like this:
controllers/gallery.php
controllers/home.php
controllers/news.php
views/gallery_view.php
views/home_view.php
views/news_view.php
models/page.php
models/picture.php
It's perfectly legal for each controller to make use of multiple models and views; in fact, that's the point. A blog controller might use models for user, post, and comments. You can also do sub-views which are used from inside your other views (such as views/header_view.php).
If your project has well-defined specs, you might consider making the team division between one person doing the model and controller logic, and another writing the view output. Or, you could divide the work between different pieces of the site; however, you'll still want to write some shared code that gets used project-wide. That's the biggest principle of MVC: Don't Repeat Yourself.

Creating admin menu items dynamically in joomla

Another day playing around with joomla, and another shortcoming to fix :)
This time it comes in the form of the administration(backend) menu.
To add items/subitems to this menu, people have to write the menu items in an xml file accompanying their components/extension/plugin/whatever.
When the extension is installed, joomla "generates" the menu items and "stores" them in the DB.
Effectively, the real/tangible menu is rendered by reading the DB.
This has several implications:
The menu is not scriptable
The menu is not dynamic; changing the XML file after installation, won't update the menu
Removal of items is not scriptable; joomla takes care of removing any items when you uninstall the extension.
I've got this system which relies on the ability to modify menu items on the fly, but through code.
Simply put, I need to have functionality where I can create a volatile menu item (ie, it gets removed at the end of session).
To do so, I've got a couple of prospective hacks:
Override the joomla global database instance so that I can make it return fake menu items. This is possible since the database object is stored in a public property of JFactory class: JFactory::$database=new MyFakeJDatabase(JFactory::$database);
Intercept the menu code (html) before being output and mess it up according to my needs. This is not template-friendly in that the end result would be injecting html, which might not be what the template was designed for.
Create menu items through javascript. This suffers issues with the template AND the javascript that toggles submenus.
Create menu items in the DB whenever I need them and somehow "tag" my items so that I remove them the next time (or end of session). This sounds like it would work like a charm. Since I can buffer menu items, I could possibly create my menu items in one whole SQL statement. Than I could use another SQL to remove the tagged menu items. 2 SQL statements might not be much of a load on the server.
What do you think?
Edit: I've checked joomla/administrator/modules/mod_menu/helper.php to see if I could find a way to inject my stuff, wishing that maybe joomla used a global variable or something, but to no use - the menu items are creating directly by reading the db and rendering as well.
FYI I've searched a while on Google, to no use.
Interesting. I have worked with Joomla for many years, writing all kinds of extensions for various purposes, including integrating external systems. It has been my experience to approach these types of situations by looking at the basic needs of code execution. And I always seem to start off asking: is it UI driven or system-driven?
First, consider if the code will execute according to user-generated system events. There are a whole bunch of 'em and you can even trigger your own. If this is a requirement, then the solution will need to incorporate a plugin, attached to events.
However, for any kind of dynamic UI content, you will need a module. Modules are all about displaying content. These guys are designed for the user experience. So, consider how access to the UI content will be managed. Which users will comprise the "audience" of this content? This is controlled by user groups and access levels. At some point in your code, preferably early, you will have to check the user's rights and then modify your code execution in response. Thankfully, I find that someone has already done a lot of the work for me. How?
Find an extension that performs the things that your code needs to do, or as close as one might match up. The entire CMS is built with extensions running atop the Joomla! Framework and there are thousands of extensions available for download. Once you've found it, clone the thing. Then edit it so that it does what you need it to do, plus what it did before (if that is a requirement). Install your updated clone, unpublish the original and publish yours. Saves a lot of time.
Looking at your requirements, the code only executes as long as there is a session. I would start with with a 'user' type plugin. When the user triggers a login event the plugin can add the dynamic menu records to a session variable as an array of db records. When the user triggers a logout or the session times-out, the records will go away by themselves. Then I would simply clone "mod_menu" and have read in any records that it finds in the users session. I use this session variable technique all the time, especially when implementing analytic data gathering stuff.
Anyway, I don't post often; but I sure hope this helps. I would love to see this type pf functionality myself. Just haven't the time to code it.
Good luck!
chozyn
The "correct" way would be to write a module which overrides the core menu module to achieve the old functionality with the added feature of dynamic menus from whatever source you have. Not particularly a nice way to go, but that is Joomla's way.
Thanks to #ircmaxell to point this method out.
No hack seems satifactory, safe or maintainable enough to achieve this.
I've aborted the project and instead am putting buttons in the main dashboard through JS.
It's highly inconvenient to end users (they still miss sub-items). But what the hell...it's Joomla's fault.
Oh and for the record, I needed to add my own custom "pages" similar to admin components. Guess what? That failed as well, so it's another hack.
Hope that by version 1.7, they[joomla] trash the initial codebase altogether.

Several copies of a PHP site with tweaks: maximize code reuse and minimize duplication?

Sorry for the confusing title....
We are developing an application to be used by multiple companies. For the most part, the application is the same, your standard sort of database manipulation pages (search pages, edit pages, etc.) customized for the data that it is designed for.
However, each company has a slightly different process, and we will be dealing directly with each company so we'd like to use some sort of system that would allow us to tweak pages depending on which company is viewing the page. For example, one company might want a couple extra fields on a data input page, or another company might want to view a different piece of data on a search results screen, and so on.
I understand this is all hypothetical and I wish I had a concrete example to give you, but honestly the companies haven't even given us very good examples. We just want to be ready.
So my basic question is, what is the most flexible way to allow for these tweaks and customizations on a per-company basis? Obviously, the most flexible but least programmer-friendly way would be to make a complete copy of the app for each company. This obviously isn't an option because we'd need to manage updating code on all the sites, trying to keep them all running and tested and having issues resulting from the customized code.
What are your thoughts on Smarty being a solution to this? Perhaps if we have a master set of templates, but then each company can have a different subfolder with any replacement template files... Of course we'd still need to update a bunch of different template files whenever we change one of them, but it would be a little more localized anyway.
Is there a better way? Some sort of differencing template engine maybe, so that we can still edit the original files and the changes will adapt on top of the originals (kind of like a patch)? Or perhaps we should use the object-oriented features of PHP5 and then use polymorphism? What is your best suggestion, and especially if you've had experience with this sort of thing, what are the options and which have you used and why?
I think the template method pattern will help you out a lot. It's really a great pattern for factoring stuff that is mostly the same but differs in a few places. I'm actually working out a template method hierarchy for my own project right now.
I would suggest you try to create the application either using an mvc framework or using your own implementation of mvc.
In this manner you could create models that could be reused (and also views) for other companies.

Categories