Symfony 4 get all POST data

“How do get all the submitted form data?” When I was learning Symfony this was something I couldn’t find a noob-level answer to. All the tutorials want to introduce you to the Symfony form module right away. But if you’re like me and want to understand how things fit together before using some overly complicated object to build a simple form then the below information may be useful.

How to get all values from a form submit in Symfony 4.

/**
* @Route("/", name="form_submit",methods={"POST"})
*/
public function my_form_action(Request $request)
$everything = $request->request->all()
;

Pear's mail_mine not working with Outlook

In a WordPress plugin I am developing, I am using Pear’s mail_mime to generate an HTML email and send it with an attachment. This worked fine for me during testing with my gmail account. However once I started using the plugin to send emails to others, Outlook users were getting a garbled mess. Outlook could not properly understand the generated multipart/mixed message and was showing the raw text. It took a bit of digging to discover the solution, but the root of the issue goes back to an age-old C.S. problem.

Windows uses ‘rn’ to define a line break, while Unix-like systems use ‘n’ to define a line break. Gmail doesn’t care which kind of line break you use, but Outlook requires line breaks to be in the ‘rn’ format.

Mail_mime allows you to pass the default for line breaks as a constructor argument. However, this didn’t work correctly for me. The Mail_mime code uses the End-Of-Line constant (PHP_EOL) and passing the EOL value in was not enough to change the value in all places.

What I had to do to finally get Outlook emails to display correctly was to first define the PHP_EOL constant and then pass it in as well.

// define the PHP_EOL constant
if (!defined('PHP_EOL')) define ('PHP_EOL',"rn");
// pass in the value on create
$mime = new Mail_mime(PHP_EOL);

I had to define the constant AND pass in the value to catch all the places the linebreak characters were used. This seems like a bug in Mail_mime.

I used the comments on this bug report to solve this issue. Unfortunately since this work-around was discovered, the maintainers don’t seem willing to fix this issue.

PointClickPress and The Great Underground Adventure Postmortem

In the Beginning

Before I launch into my next programming adventure I should figure out what went wrong and what went right with the development of both the PointClickPress engine and with The Great Underground Adventure game. Its important to learn from your mistakes, so here we go.

I started this project because I wanted to learn a PHP framework and I thought it would be straight forward (and fun) to make an in-browser point-and-click style game. Maybe that could’ve been true but, between major life changes outside of this project and getting bogged down in game-engine hell, it ended up taking two years.  I think that is way to much time for the small game that was ultimately the result of the project, but then again, its not like I was working on it full time. Sometimes maybe I got an hour a week between changing dirty diapers.  I think other people would’ve (wisely?) abandoned this project when so little progress was being made for such little results, but for better or worse I stubbornly stuck with it.

What went right?

1. Choosing the Kohana Framework

I spent a lot of time researching and testing frameworks before I selected one to learn.  I’ve touched on this subject before.  Kohana made the development of the PointClickPress game engine very straight forward. The framework allowed me to stay organized, leverage existing libraries, and be productive very quickly without getting bogged down in framework guts or configuration.  I was even able to find a Kohaha module that came with fully developed user registration, authorization, and admin sections which allowed me to focus on building the game engine and not go through the dry exercise of user management again.  Of course, I had spent a weekend building the user admin already by the time I found that nice module.

2. Breaking the project into phases

I broke PCP development into manageable chunks that would be functional and releasable when completed.  Software development is an iterative process and you can’t plan for everything along the way.  Marking out stopping points in the development allowed me to make sure that I’d get something released. Nothing keeps up my motivation like releasing something playable for people to try.

3. Mobile & desktop support

Right from the start I made sure that PointClickPress was going to work as well as in a mobile browser as it did on a desktop. Every design decision considered mobile.  I think it would have been very difficult to ignore mobile and then try to shoehorn the site into a mobile browser after the desktop was done.   Everything works equally well on large and small screens. I did go overboard keeping by javascript to a minimum however.

4. Using photos for game art

I really like how the photos came out for The Great Underground Adventure. I think they look great and since you are (for the most part) exploring real locations it adds an extra level of interest to the  game.  Scouting and taking the photos was also an adventure that lead me to all sorts of interesting places.

What went wrong?

1. Getting lost in game engine hell

Despite choosing a light framework that had many built in libraries I still over engineered the PCP game engine and administration area way beyond what was needed to make a straightforward point-and-click adventure game.  If I had just kept my head out of the clouds and built only what I needed to get my game working I’d have finished a year earlier. I kept wanting the engine and admin to be “perfect” before I started building the game. I was re-architecting things constantly and still finding ways to refactor and abstract.  Eventually I just had to stop!

I also stubbornly refused to use ORM, so as my database model evolved I was constantly tinkering with the SQL. Later on I was constantly fixing SQL bugs rather than just loading the ORM library at the start and being done with it.

I greatly admired how WordPress allows a user to add additional functionality easily. I wanted the engine to have plugins, to be extensible, so that end users could easily add features that I hadn’t thought of.  I spent way to much time thinking of how to de-couple functionality from the engine “core” than was healthy.  Depending on the ability for users to extend the existing functionality by adding their own clickable actions was also a trap that eventually doomed the idea of a public PointClickPress portal game website due to security issues.

2. User-created extension security issues derail game creation

I consider this the biggest problem with the current version of PointClickPress.com. This is not an issue for the stand-alone version however.

The first iteration of PointClickPRess was as single-user, multi-story creator.  The use-case was that an author could self-host an installation of PCP and build “stories” (aka games) with it. In this use-case PCP supported only a few out-of-the box clickable actions such as linking two locations together.  The plan was that an author could easily write any intermediate to advanced click actions directly in PHP and connect to the PCP API. It is very straight forward to create a small action file and place it in the action directory. Then it was available to use.  Alternately there was an out-of-the-box clickable action that was simply a PHP eval() call. This allowed the user to type PHP in from the admin area without needing to create a file.  This ability to create new actions easily allowed PCP to support whatever an author would want.

Of course neither of these options is viable on a multi-user public installation such as PointClickPress.com.  The authors no longer have access to the filesystem, and allowing the use of eval() is also out of the question for security reasons.  This loss of extensibility severely hinders game development.  The built-in clickable actions by themselves don’t do much. They were only meant to be shortcuts for simple tasks.  Now an author on PointClickPress.com must chain many simple actions together to equal what one action on a self-hosted version of PCP could do. This is what I have done for The Great Underground Adventure. Often there is a cascade of three or four clickable actions that are called behind the scenes as the result of one click. Chaining actions together is a fairly arduous task. And I don’t expect anybody to enjoy using the public site for this reason.

3. Using photos for game art

Using photos for game art was a million times harder than I thought it was going to be. I talked about this already in a blog post here.  I estimate I took around 3000 photos over the course of two years. Many I got on vacations, but also I scouted locations around me. Probably about 400 of these photos made it into the game either by themselves or as part of a composition.  I’m not a strong “Photoshopper”, so creating the composite photos, such as the views surrounding the cable car area. Took many evenings to get right.

 

Conclusion

In the journey from the start to the end of this project the game felt as if it became an after-thought unfortunately and the PCP admin seemed to be the central focus. Maybe I’m just born to be a back-end programmer. I certainly accomplish my goal of learning a PHP framework from this project.  I did plan on making other games using this engine, but now that I am finished I find myself brainstorming the next project around learning new technologies. I’d like to play with the canvas and try designing a multiplayer game. Maybe learning Python and Tornado, or Node.js, at the same time.   I’m not sure many people but me will enjoy playing The Great Underground Adventure, but I’m proud of it. I think its charming in its own decidedly low-tech way. The same goes for the PointClickPress engine.

If anyone wants to try their hand at building a game you are welcome to give it a try at PointClickPress.com or you can download and host your own copy. PointClickPress  is open sourced under the BSD license and is available for download at SourceForge.net.

The Great Underground Adventure

So I’ve been working on building my first game as a way to test everything out now that PointClickPress.com is up and running. I wanted to create something like all the adventure games I played growing up. My game is called “The Great Underground Adventure” and is a Zork-esque story which takes place underneath an abandoned white house. The similarities end there though as my story features a talking cat in need of some help. You must journey to the world below in order to gather ingredients that will lift the curse that has been cast on the poor feline.

I’m a developer, not an artist, but I needed artwork for the game. I decided to go with photos thinking that it would be easier than drawing all the locations myself. I hunted around, snapped some photos, and have begun placing the photos in scenes and connecting the locations together. Choosing this path for the artwork has unforeseen concequences.

Where original artwork could have allowed for simplification of each scene, I now have hundreds and hundreds of photos in order to allow the player to navigate each location in a way that makes sense. The house I took photos of had five upstairs rooms; My plot only called for two, but a player would expect to be able to navigate through all displayed doorways, so I made sure each room was available and began expanding the story to fit the locations. There also accidental things in each photo. Sorry you can’t pick up the bucket that just happened to be in the foreground when the photo was taken. I’ve also had to re-shoot every location in the game as each time no matter how many photos I took I would miss a few images that would be needed to stitch the scenes together.

On one hand, I think the photos look amazing. On the other hand this is way more complicated than original artwork would be. I hope to finish “The Great Underground Adventure” by the end of July so I can show it off to everyone, but first I gotta go take some more pictures…

The Kohana 3 Framework

For a year now I’ve been working on a hobby opensource PHP project (PointClickPress) using the Kohana framework.

After grappling with the beast that is the Zend Framework and others I eventually settled on Kohana because of its simplicity and speed. Kohana was originally a community developed branch of the popular CodeIgniter framework, but with the release of version 3 it has taken on a life of its own.

My previous framework experience has been with the two big Coldfusion frameworks Mach-II and ModelGlue; and while both of these frameworks are excellent at organizing large Coldfusion projects, the XML config file(s) in both frameworks have always been a pain point for me. It was great to work with a framework that doesn’t require endless tinkering with XML.

I’ve really enjoyed working with Kohana. It is unobtrusive in your code and provides a straightforward platform to build your application on. You can use as much or as little of the functionality it provides as you need. Its allowed me to focus on building the app logic and not creating low-level functionality.

If you are about to start building a new PHP app I recommend you give it a try.

Using Prepared Statements With Kohana 3

I just discovered this tonight. (It wasn’t hard, I just had to RTFM).
In Kohana 3 you can query using prepared statements very easily. Prepared statements are important to protect against SQL injection attacks.

Below is a simple example:

$q = 'SELECT * FROM myTable WHERE id = :someId';

$results = DB::query(Database::SELECT,$q,TRUE)
                       ->param(':someId',$MyId)
                       ->execute();
  1. The first step here is to set a string in the query that is a place holder for the value that will be passed in seperately. In this case the placeholder is “:someId”
  2. Next, when calling DB::query, the first argument must be the object that Kohana will use to hold the results. In this case that object is Database::SELECT
  3. Then you pass in the information to the query using “->param(‘:someId’,$MyId)” This says that the value for ‘:someId’ is $MyId.
  4. Finally you can execute the query.

For those of you who are familiar with Coldfusion this is exactly how cfqueryparam works behind the scenes; it creates placeholders and then passes the data in seperately. Cfquery then returns a cfquery object just like how Kohana is returning a DB::SELECT object.