Autogenerate CMS crud forms with Laravel 4 - php

My company recently started working with Laravel 4. I'm now in the process of building a basic CMS. I've already found out that there are many ways to reach any goal you can think of and I'm greatly in love with composer and packagist ;) For most anything I would normally build myself I've found an existing package. Just not for this one thing:
What I'm looking for at the moment is a good way to define or generate the basic crud views for any cms controller. For example, image a list of products to be sold and each product has properties ( a few of which are 1-n or 1-1 relationships ). In this case I would either need to build a massive form view to be able to manage all these variables manually, or I would find someway to generate it. If it was just this one time, I'd simply build the form. But because there will be many more similar modules I'd like an easier and DRY method.
I've considered making a artisan generator for this purpose, wich uses the model to figure out all fields and relations. That is great for the first setup, but still requires manual work for special cases or changes afterwards.
So I thought defining the form in a multidimensional array and then using that to generate the nescesary formfields, even with support for Form::macro expressions in the view for very specific needs.
This works fine and I've got it working fairly easily but after adding many whishes ( like nesting of form items in groups etc ) it slowly became more cumbersome to manage.
I've been searching for packages or smart solutions for this problem but so far haven't found anything usable. Hence my posting of this question.
I'd love to hear your thoughts on the subject.
Thanks!

Related

Joomla: What is a good technical approach for data entry?

I have a background in .NET and Perl, but have found myself working on a project where the customer is mandating Joomla. They would like me to setup a web site that will allow them to enter rental properties, which would likely include a large description field and a number of smaller metadata fields. What is a good way to approach this problem using Joomla? Would I somehow add metadata fields to articles for entry of rental properties? Would I need to create something outside the realm of an article (I'm thinking maybe a component, based on some intro training videos that I have watched on Joomla)?
My HTML and CSS skills are pretty solid, and I have a little bit of experience with PHP, so I don't mind getting my hands dirty. However, I'd like to get an idea of how a Joomla veteran would approach the problem.
Trying to tack meta information on to the articles is almost certainly not the way to go - for a ton of reasons. You are on the right track with a component. Consider designing a component with a back-end database, admin capability and a few front-end data-entry/information screens. The Joomla framework is a little cumbersome to begin with, but ultimately the MVC implementation makes sense and is quite powerful.
This tutorial at the Joomla documentation wiki runs through pretty much everything you need to know from a basic "hello world" to databases and more complex implementations. It sounds like the basic database-enabled example would get you really close to your objective. The example application builds on itself from one tutorial to the next, so it is not at all a waste to start at the beginning and work through it.
And a couple random bits of advice for a Joomla component development beginner:
One thing you may want to research related to data-entry is the JHTML class (the JHTML::_() function in particular). IMO the approach is less than intuitive, but using it is required to leverage built-in widget classes defined for the standard form fields in more advanced applications. It is also important for working with customized form field types and handlers.
Also, the objects returned by JFactory::getApplication() and JFactory::getDocument() have a ton of useful/important functionality when it comes to manipulating the Joomla application (like access to the JInput object). Get familiar with what they can do and remember how to retrieve them.
Good luck.
While building a component from scratch is the most flexible the initial learning curve might be too expensive (time wise) if you're not experienced with PHP and the Joomla framework.
Generally, if we're asked to do something outside our normal areas in Joomla the first place I look is the Joomla Extension Directory (JED).
From that I can usually find a very good solution or a very near match. If it's not a perfect match I can easily extend it (e.g. adding a plugin for a local payment gateway) or work with the developer to add the features we need to the extensions core). Which is probably a good way to start with Joomla, i.e. modifying or extending an existing extension.
You're lucky though, the area you're interested in has it's own category on the JED — the Real Estate section has 15 items listed and most them seem to have good ratings and reviews.
So, I'd start there.
You could make a form plugin for articles to add the extra field or to divide the body field into sections with json or using the profile plugin as a model you could add fields and store them in a separate table.
YOu could repurpose the contact component and use its many fields, or just clone it and change the names.
You could also use an advanced form extension.

What should a bundle in Symfony2 represent

This might be an obvious thing to you but - even after reading through a lot of manuals and blogs - I'm still not sure what exactly should a bundle in Symfony2 represent in a webpage. And it's hard to guess it from the simple demo applications.
For example: I have a site which is divided into two parts (one is just a 2nd level domain like example.com and another is dom2.example.com). Each of these two parts has some sections of it's own - sometimes the same (like news) sometimes different.
What would the correct representation of this in symfony2? Should I have
a MySite\site1 and MySite\site2 bundle and do the different sections via different controllers, or
bundles Site1\News and Site2\News, or
bundles MySite\Site1News and MySite\Site2News etc.
...or am I getting all wrong at this?
I am also new to Symfony and will follow the results of this question with interest, but for what it's worth, my take on it is:
A bundle is just that: a group of files, assets, PHP classes and methods, tests, etc. The logic of the grouping can be anything you like. In some cases, it's really obvious what the grouping is and why it's been done -- for instance, if I wrote a blog system for Symfony2 and wanted to release it, I'd make it into a bundle. That's the sort of example used most in the documentation.
But you'd also use bundles for anything you wanted to release as one little feature. Say for instance, this bundle which creates default routes for all your controllers. It's not a fully developed plugin/feature like a blog or forum, but it's a bit of code that I can easily import into my project, it stays totally separate from everything else, it's a bundle.
Finally, you'd also use bundles internally to your project, in absolutely any way which makes sense to you.
My take on your specific situation:
Quick and easy:
MySite\MyCode -- gets the job done, and maybe you don't have any logical way to break up the code you're going to write.
If there's some more unique features between the two sites and you want to separate them out for clarity:
MySite\SharedFeatures
MySite\Site1Features
MySite\Site2Features
If you really like everything in its place, or if you have a complex project, maybe:
MySite\MySiteMain (shared features and catch-all miscellany that doesn't deserve its own bundle)
MySite\News
MySite\Site1FeatureSomethingOrOther
MySite\Site2FeatureSomethingOrOther
I definitely think you want to stick to logical groups of code -- so I think your example "bundles Site1\News and Site2\News" and "MySite\Site1News and MySite\Site2News" wouldn't be the best way to go. Site1 and Site2 are implementations, so making a separate bundle for each site's news page would seem to be counterproductive to me; you'd want to make one news component and build it to be used in two different ways.
As for your two-domains question, you can either point both domains at the same code, and test within your code for what domain is being requested, or you can check out two copies of the same code and change the configuration files slightly (this doesn't necessarily violate the idea of DRY because you'd still edit the code in one place, then update both copies.)
The way I understand a bundle is that it is similar to what CMS like e.g. Typo3 or Drupal call a "plugin". So it should be ideally self-contained and written in a way that it can be used on other projects too.
E.g. in your case I'd create a "staticHtmlBundle" that contains all the static pages of your website, divided within by site.com and dom2.site.com.
Then I would create a "newsBundle" that contains all the news-articles, maybe even database-driven with a little admin-section where you can edit them and assign them to different channels (in your case that is site.com, dom2.site.com). A static page from within staticHtmlBundle would call newsBundle and display its data (like e.g. a listView of the news or a detailView and so on).
If you keep everything as abstract and reusable as possible then you could even publish the newsBunde in the Symfony 2 Bundle repository and share it with the community!
The way I perceive Symfony2 bundles is that they are provide a modular system which allows you to not only extend and override the php code, but also any resources they may or may not include.
Having said that, consider you have an API and you would like to transfer an object.
How would you do that?
Of course, you can do that manually, but wouldn't it be nice if Symfony can do it for you?
My way of doing this would include 3 bundles, JMSSerializerBundle and FosRestBundle.
One bundle for the client side - MyCompany/ClientBundle
One bundle for the server side - MyCompany/ServerBundle
One bundle housing all the data transfer objects I would like to be able to transfer - MyCompany/CommonBundle.
Inside my MyCompany/CommonBundle I would have the classes I would use for my data transfer objects along with the serialization rules I would have to provide the JMSSerializerBundle with. They may be in the form of xml, yml or php annotations.
Once you have an object filled up with the data, you can just use return and FosRestBundle would serialize it for you. Serialization would depend on the routing, so you can have the object serialized in XML for one system and in JSON for another. Key point is you have different serialization formats and versioning you can utilise at later point.
On the client side, you can use simple param converter to convert the received JSON or XML to an object right in the controller with no additional hassle. You can also type in some validation rules, so you can verify if the object is populated as you expect it to be.
In my example, the MyCompany/CommonBundle has objects that would be used by multiple applications and would be identical. Having that as a separate bundle helps you avoid code duplication and makes long term maintenance a lot easier.
I hope I managed to explain this. Any questions?
Ask in the comments. Will update the answer accordingly.

CakePHP for big projects

We are evaluating some PHP Frameworks for a productive website. CakePHP looks pretty interesting but we have no clue if it fits our needs.
Basically when you check the documentation and the tutorials for CakePHP it looks really promising. Nevertheless there were always some things that bugged me with frameworks so far, maybe someone who already used CakePHP in a productive project could answer this questions for me?
Writing/Reading data for single records looks pretty neat in CakePHP. What happens if you want to read data from multiple tables with complex conditions, group by, where clauses? How does CakePHP handle it?
Scaffolding looks pretty nice for basic administration interfaces. How easy is it to customize this stuff. Let's say I have a foreign key on one of my tables. When I create a scaffolding page, does CakePHP automatically create a dropdown list for me with all the possible items? What if I want to filter the possible items? Let's say I want to combine two fields into one field in the view part, but when I edit it, I should be able to edit both of those fields individually. Does this work?
Do you think you were faster in development with CakePHP than with let's say plain PHP?
I've used CakePHP, Zend Framework and I've also written applications "from the ground up" with nothing more than homegrown classes and such. To that I'd like to mention that I use CakePHP regularly so, take that as you will.
(Writing/reading data, complex conditions) You can certainly do everything you mentioned. Others are correct in that it attempts to abstract away SQL operations for you. I've yet to have a query that I couldn't translate into Cake's "parlance"; complex geospatial queries, joins, etc.
(Scaffolding, complex conditions) The scaffolding is really only meant to serve as a "jump start" of sorts to help make sure your model associations and such are setup correctly and should not be used as a permanent solution. To that end, yes it will do a fairly good job at introspecting your relationships and providing relevant markup.
(Faster development) Of course. There is a large community with a vast number of plugins or examples out there to help get you started. Regardless of what you pick, choosing a framework will almost certainly make you "faster" if only for handling the minutiae that comes with setting up an application.
It really depends on your definition of "large". Are you referring to big datasets? A very complex domain model? Or just lots and lots of different controllers/actions?
Writing/Reading data.
Anything you can do with plain SQL you can do in CakePHP. It may not always be very nice to do, but at it's worst it's no worse than straight SQL.
But you really shouldn't be thinking about queries. You should be thinking about your domain model. CakePHP implements the active record pattern. It works very well if your domain model maps nicely to an active record pattern. But if it does not, then I would not recommend CakePHP. If your domain model doesn't map to Active Record then you will spend a lot of time fighting the Cake way of doing things. And that's no fun. You would be much better off with a framework that implements a Data Mapper pattern (e.g. Zend).
Scaffolding
Scaffolding is temporary. It does handle foreign keys (if you define them in the model as well as in the database) but that's it. You can't modify the scaffolding. But, you can bake them!
When you bake a controller or view then you're basically writing the scaffold to a file as a jump-off point for your own implementation. After baking, you can do anything that you want. The downside of baking is that it doesn't update anymore when the models or database changes. So, if you bake a controller and views and you add fields to your model, then you need to add those fields manually to your controller and view code.
speed of development
In my case, I'm a lot faster developing a website in CakePHP then in plain code. But only if Active Record suits the application! See my first point. Even then, Cake is probably still faster, but I would be faster still with a better suiting framework.
Some other thoughts
large datasets
If you have very large datasets and big query results then Cake can be a problem. A find() operation wants to return an associative array, so all the rows are read, parsed and converted to arrays. If your result set is too large you will run out of memory. CakePHP does not implement ResultSet objects like many other Active Record implementations and that is a definite downside. You end up manually paging through your own data with subqueries. Yuck. Wich brings me to my next point:
arrays
Learn to love them because CakePHP does. Everything is an array and often they are large, complex and deep. It gets really annoying after a while. You can't add functions to arrays so your code is more messy than if CakePHP would have used nested object instances. The functions you can add to those objects can help keep your code clean.
oddities and inconsistencies
CakePHP has some real nasty stinkers hidden deep within. If Active Record suits your application then you will probably never run into them, but if you try to mold CakePHP into something more complex, then you will have to fight these. Some examples:
HABTM through a custom model uses the definition from the other side of the relationship that you're working on.
Some really odd places where your before/after triggers aren't called (e.g. not from an updateAll)
odd Model->field() behavior. It always queries from the database. So, be careful about updating model data without immediately saving it to the database. Some CakePHP functions fetch data from Model->$_data and some use Model->field(). The result may be entirely different resulting in some very hard to track down bugs.
In short
I would highly recommend CakePHP even for "large" sites, as long as your domain model fits nicely on top of Active Record. If not, pick a different framework.
Since you are asking for opinions, then I have to say that I advise AGAINST CakePHP.
My biggest gripe with it, is that it's still using PHP4 (written in and code generated). So, why go backwards? It is compatible for PHP5, but the framework itself revolves around PHP4.
I would recommend taking a look at Symfony or Zend. Symfony being the best if you want more structure in place - it forces you to adhere to the MVC structure that it has established.
The alternative is Zend, but it's more of a 'do-it-yourself' framework, or rather more of a set of libraries. You need to put it all together yourself, and it doesn't have any strict structure like Symfony.
There are obviously other frameworks, but I recommend the fore-said. Another one that you may want to look at is Codeigniter.
CakePHP tries to abstract away the database, so you write very little SQL (however, you write a lot of SQL snippets).
The basic process is to define your models, then define the relationship between models (hasOne, belongsTo, hasMany, hasAndBelongsToMany). You can put any conditions or default ordering on these associations you like. Then, whenever you fetch a row from the database, any associated rows are automatically fetched with it. It's very easy and powerful.
Everything comes with a bunch of configuration options, giving further flexibility. For example, when fetching data there is a recursion option which takes an integer. This value is how many associations deep Cake should fetch data. So if you wanted to fetch a user with all their associated data, and all the joined data to THAT, it's trivial.
Pretty much anything can be overridden on defined on the fly, and you can always fall back to writing your own SQL, so there's nothing Cake prevents you from doing...
I've not found much use for scaffolding. The answer to your question is yes, it'll auto populate joined dropdowns, etc. But I've never used it as a basis to build an interface. I tend to use a database tool to populate data early on rather than scaffolding.
I've built and also maintain several web-apps on CakePHP, and it is without question faster than 'rolling your own'. But I think that's true of any decent framework!
Unfortunately one of the weaker points is the documentation. Often you need to Google for answers as the official documentation is a bit hit-and-miss at times.
Just go with Yii framework, it's the best in this category.
(Note: This is a subjective question. You are asking for opinions. So I hope you don't mind if I give mine.)
(Edit: Ops. I mixed Cake with CI)
I used Code Igniter a while back. It did everything it should and was fairly easy to understand. However, for big projects, it lacked features. Many CI proponents say that this is it's strength as it keeps it fast and can make little RAM. This is true.
However, after developing one application with it, I found myself looking elsewhere so I would not have to write code that must have been written before. I looked at CakePHP and found it too restrictive and automagical. In particular, I needed some kind of ACL functionality. This lead me to Zend Framework. I learned that it is loosely coupled. I can include only the files I need. I can also make use of Zend_Application for large projects. It's object oriented design is a must when developing and maintaining large projects.
Yes, CI and CakePHP helped me to develop faster than with plain PHP. However, there are much more powerful frameworks. I hear and see good things about Symphony. There are quite a few more. I'm sure others will point them out.

Handling complex data collection with a CMS

I do web work for a group at the university I attend. We’re having a design company redo our site and will be coding the site ourselves. We’d like to build the new site on top of a CMS so that people can easily add content. So far I’ve been looking into using Drupal. The problem I’m running into while thinking through how well Drupal will work for us is in regards to data collection. We’re overhauling our database to keep data centralized. For example, rather than create a table for every form with fields for First Name and Last Name (common fields for a lot of the forms we do) and all other fields, we’re pulling the common fields out to tables like a user table. This will help us track people’s involvement with our group much better and make our data far more useful. Is there any easy way to do this with Drupal modules? I’ve looked into CCK a bit but it doesn’t look like it’s useful for more than simple data that doesn’t have “complex” relationships between tables.
What are your recommendations? Are there some good modules I could use; do you recommend a different CMS (NOTE: needs to be php) that would better suite my needs?
I have the same exact question as you -- so far the best CMS I've come across for data collection from forms is Concrete5 (http://concrete5.org). Any time you use their "form" block, the submissions are sent to the "Reports" section on the back end of the dashboard. I don't love their organization method, but it's the best I've seen so far, and it also lets you dump to a file.
I think you want Drupal with Views and Organic Groups.
What kind of forms do you have?
You shouldn't use Drupal if you care about database structure. CCK is the method of defining content types, used on 60% of all Drupal sites and the basis of fields in Drupal 7 core.
That said, you may want to question a few of your assumptions. First, there are a lot of modules that add new field types to CCK, e.g. FileField, so it may not be as simple as you think. Second, do you really need to worry about how the database is organized, or is that just a means to some other end, e.g. reporting. If it's reporting you're after, you can generally handle that with Views, the only module used more than CCK.
If you really do need to worry about the database structure and really do need more complex relations than CCK can handle, I'd suggest you're not looking for a CMS so much as a framework. Those kinds of details are generally handled automatically in a CMS.

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