New engine, new URL
I know I know. URLs shouldn't change. Well, I don't care in the case of my blog ;) At least almost all content is still there ...
What happened? I made the switch to Wordpress. No more fiddling around and solving problems that don’t need to be solved.
The new blog is located at michaelsauter.net/blog and the RSS feed is now at michaelsauter.net/blog/feeds/rss. Update your bookmarks, and I'm looking forward to your comments!
Learning JavaScript
Okay, I give in. I'm going to learn JavaScript now.
Once again I realised I'm spending a lot of time of a project (and it's only getting more and more) on the JavaScript part and don't feel very comfortable with it. Yes, I've used JavaScript (more to the point, jQuery) for many years now, but I use it like PHP without the dollar sign. Which sucks ...
So, what am I going to do?
First, I'm going to listen to Douglas Crockford:
- Crockford on JavaScript - Chapter 2: And Then There Was JavaScript
- Crockford on JavaScript - Chapter 3: Function the Ultimate
- Crockford on JavaScript - Chapter 4: The Metamorphosis of Ajax
Second, I'll have a look at another JavaScript framework: ExtJS. I chose ExtJS because it is focused more on web applications than jQuery (which I still love!), and TYPO3 v5 will use it. I haven't decided yet which book to read, but am determined to pick one after I got the basics right.
FLOW3: Updating entities inside an aggregate
The manual explains how to update entities that are accessible via a repository, but it does not say explicitly how to update an entity within an aggregate. In this post, I'll show which steps need to be taken to do that.
Assume you have the following to models: Foo and Bar, and Foo contains an SplObjectStorage of Bars. Foo is the aggregate root and has its own FooRepository. Bar should not be accessible from the outside but only through traversal via Foo. Now, how to update a Bar object? Obviously, you can't do $this->barRepository->update($bar); because there is no bar repository!
So, let's start by looking at the controller and the views. Create basic index, new, create, edit and save actions. All of these need a $foo as an argument (additonally to the $bar that you want to create/edit/update). So you need to give all links (or forms) in the views arguments={foo: foo}.
The controller then needs to set the $bar in the $foo. When creating, this could be $foo->addBar($bar). For updating, I suggest calling $foo->updateBar($bar).
Of course you need to implement these to methods in the model Foo. addBar() is easy, just attach the given $bar to the SplObjectStorage of Bars. updateBar() is a little more complicated, because you first need to find out which of the items in the SplObjectStorage needs to be replaced. This can be done with the following code:
$editedBarIdentifier = $this->persistenceManager->getIdentifierByObject($editedBar);
$originalBar = $this->persistenceManager->getObjectByIdentifier($editedBarIdentifier);
$this->bars->detach($originalBar);
$this->bars->attach($editedBar);
As you can see, that requires a persistence manager object, which can be injec ted via dependency injection in the model. Make sure to set the @transient annotation to tell the persistence framework that you don't want it to track the persistence manager object (of course!).
That's it. Happy updating!
Programmatic ViewHelpers for FLOW3
In the current version of FLOW3 (1.0.0 alpha7), there is no way to create Fluid ViewHelpers programmatically. But there is a workaround which is not that bad either. I got the inspiration from the admin package, so all kudos goes to the creator ;)
First off, why would you want something like this? I wanted to accomplish the following: I have a page entity which contains several page items. Every page item shares the same interface, e.g. all have a display method. Of course I don't want to generate HTML code directly in there, but have Fluid ViewHelpers based on the properties of the page item.
The soultion is rather simple: Instead of generating Fluid ViewHelpers in the code, render a view! So for every page item, create a Fluid template, and the display method of the page item makes sure all necessary view variables are set.
Here is the code needed in the page item's display method:
$view = $objectFactory->create('F3\Fluid\View\TemplateView');
$view->setControllerContext($controllerContext);
$view->setTemplatePathAndFilename('package://Your-Package-Name/Private/Templates/PageItemName.html');
$view->assign('varName', $var);
return $view->render();
That's it. Of course, you need to make sure you have an objectFactory at that place, as well as the controllerContext which you can get from the current controller via getControllerContext().
Templater
Everytime I start a new template, I look up some old files and copy stuff from there. And everytime I think I should finally generate a zip file containing all basic files and folders (HTML, CSS, JavaScript).
This time I did, and the result is Templater, which even allows some customization based on the current project. Check it out!
Mac, Apache and Virtual Hosts
And another round of setting up a development environment on Mac OS X 10.5 or 10.6 ...
You can think of Virtual hosts as of domains on your machine.
First, open /private/etc/hosts (yes, with no file ending). In there, add the following line at the very end: 127.0.0.1/[name-of-your-virtual-host]. You can choose any name you like (and which is a URI), though I would recommend using something like myproject.local.
Then, open /private/etc/apache2/extra/httpd-vhosts.conf. At the end, insert:
<VirtualHost *:80>
DocumentRoot "/Users/[your-username]/Sites/[your-folder]"
ServerName [name-of-your-virtual-host]
</VirtualHost>
Make sure [name-of-your-host] is the same as the one you entered in the hosts-file.
Finally, open /private/etc/apache2/httpd.conf and uncomment the following line:
#Include /private/etc/apache2/extra/httpd-vhosts.conf
sudo apachectl restart and you're done.
Mac, Apache and PHP 5.3
Okay, I should have written this post before writing about the symlinks problem, but anyway ... Here is how to use PHP 5.3 on Mac OS X 10.5 or 10.6 with the default Apache.
First, check if Web Sharing is enabled in System Preferences. If it is, Apache should be running and accessing http://127.0.0.1/~[your-username]/ should give you Apples default index.html, located in /Users/[your-username]/Sites.
So far so good, let's turn on PHP 5.3.
If you are on Leopard (10.5), you need to get PHP 5.3 first. I recommend downloading http://www.entropy.ch/software/macosx/php/, because it's really easy to install.
If you are on Snow Leopad (10.6), you already have PHP 5.3! But, you need to enable it. Open /private/etc/apache2/httpd.conf and uncomment the line #LoadModule php5_module libexec/apache2/libphp5.so.
Now, restart Apache with sudo apachectl restart, and all PHP files in your Sites-folder should be processed by Apache!
Mac, Apache and Symlinks
Recently, TYPO3 caught my attention again. I thought I would abandon this CMS forever, but there seems to be amazing stuff going on behind the scenes at the moment. Especially FLOW3, the new underlying framework sounds really interesting and I'm looking forward to work with it!
As part of this, I also wanted to try out TYPO3 4.3RC1 which was released the other day. After downloading and configuring it, I opened the installer in the browser. Result: 403 Forbidden.
Pretty quickly I discovered the problems were caused by the symlinks: Apache didn't follow them. At this point, is important to know that I switched my webserver environment from MAMP to the one installed on Snow Leopard by default, because I needed to have PHP 5.3 to play with FLOW3 (getting this to work is another story, but there are some good tutorials on the internet).
A quick look into httpd.conf (which is located in /private/etc/apache2) revelealed that symlinks were enabled. What did I miss? After some googling, I found out there is another config file specific to the user (in my case /private/etc/apache2/users/michael.conf). In there is another setting which didn't have symlinks enabled and overrides the one in the general httpd.conf.
Changing this to Options FollowSymLinks solved the problem for me.
Down under
Just a short note that I'm currently in Australia for an internship during my fifth term. Updates about life and work here can be found on michaelsauter.net/de/australia (for those of you who know german ...). This blog will take a break until next year ... see you then!
As this whole HTML 5 / XHTML thing can be quite confusing, here is a great article from Adactio who helped me see things more clearly: „Misunderstanding markup“.