Christer's blog o' funhttps://cogo.wordpress.com
Christer Edvartsen's blog about ... stuff!
Wed, 20 Mar 2019 18:36:16 +0000 en
hourly
1 http://wordpress.com/https://s0.wp.com/i/buttonw-com.pngChrister's blog o' funhttps://cogo.wordpress.com
Update ImageMagick on Travis-CIhttps://cogo.wordpress.com/2013/12/07/update-imagemagick-on-travis-ci/
https://cogo.wordpress.com/2013/12/07/update-imagemagick-on-travis-ci/#commentsSat, 07 Dec 2013 19:37:31 +0000http://cogo.wordpress.com/?p=1193Continue reading →]]>I have an open source software project called Imbo that I have hooked up to Travis-CI for testing of pull requests and pushes on GitHub. I recently came across an issue that made some tests fail on Travis-CI that passed on all other machines I run tests on. The issue seemed to be because of an old version of ImageMagick (6.6.9-7). Travis-CI use this version since they base their VM’s on Ubuntu-12.04-LTS, and that version of ImageMagick is the one currently available on 12.04.

I solved it by compiling my own version of ImageMagick via the .travis.yml file:

This made the tests pass, but the build went from taking about 2 minutes to 10, so it was not really a good fix. After asking around on the #travis-ci channel on IRC (freenode) @henrikhodne said that they might upgrade the package if they found a decent PPA. I looked around myself and found a PPA for Ubuntu-12.04 that had a newer version of ImageMagick available, so I decided to try and use that instead of compiling my own to see if that might speed up the build. I replaced the above snippet with the following in the .travis.yml file:

This reduced the build time to around 3 minutes, and all tests are passing! Travis-CI, I LOVE YOU!

]]>https://cogo.wordpress.com/2013/12/07/update-imagemagick-on-travis-ci/feed/5christerPHP-based BitTorrent trackerhttps://cogo.wordpress.com/2013/01/11/php-based-bittorrent-tracker/
https://cogo.wordpress.com/2013/01/11/php-based-bittorrent-tracker/#respondFri, 11 Jan 2013 13:33:30 +0000http://cogo.wordpress.com/?p=1188Continue reading →]]>Some of you might know that I have a library for encoding PHP variables to their BitTorrent counterparts, and back to PHP, called PHP BitTorrent. Some days back I pushed another library to GitHub, namely a standalone BitTorrent tracker.

The tracker is pretty extensible and comes with a couple of back end implementations for you to choose from, the default being MongoDB. The tracker is not a complete tracker system with user authentication and torrent downloads and such, but a standalone “announcer” (like for instance the official BitTorrent tracker: bttrack). PHP BitTorrent Tracker can easily be extended to do user statistics and so forth though. An event listener doing this is shipped with the package.

More information (installation, configuration and more) is available at the project page on GitHub. Feel free to play around with it, and please use the issue tracker at GitHub if you find any issues. Happy torrenting!

]]>https://cogo.wordpress.com/2013/01/11/php-based-bittorrent-tracker/feed/0christerIRC notifications on GitHubhttps://cogo.wordpress.com/2012/11/07/irc-notifications-on-github/
https://cogo.wordpress.com/2012/11/07/irc-notifications-on-github/#commentsWed, 07 Nov 2012 11:00:06 +0000http://cogo.wordpress.com/?p=1186Continue reading →]]>I host my open source projects over at GitHub, and most of them do notifications to IRC on different events. Recently I saw that imbo/imbo and imbo/imboclient-php did not notify new pull requests and new issues in the issue tracker to IRC. These options are not visible in the admin GUI of the hook either. You can however use the API to enable these events.

These are currently all the events available for this hook. The hook itself can be found here.

]]>https://cogo.wordpress.com/2012/11/07/irc-notifications-on-github/feed/1christerSysInfo-0.1.0 releasedhttps://cogo.wordpress.com/2012/07/21/sysinfo-0-1-0-released/
https://cogo.wordpress.com/2012/07/21/sysinfo-0-1-0-released/#respondSat, 21 Jul 2012 11:57:13 +0000http://cogo.wordpress.com/?p=1171Continue reading →]]>The other day I released the first version of a small Open Source (MIT) PHP library that can be used to fetch system information; like for instance CPU usage, load average and memory usage (amongst other information). The library is available at GitHub and can be installed using composer (support for PEAR and phar will be added later).

If you want to add some features or find any bugs, file an issue and I’ll see what I can do.

]]>https://cogo.wordpress.com/2012/07/21/sysinfo-0-1-0-released/feed/0christerElastica + elasticsearchhttps://cogo.wordpress.com/2012/07/03/elastica-elasticsearch/
https://cogo.wordpress.com/2012/07/03/elastica-elasticsearch/#respondTue, 03 Jul 2012 09:26:06 +0000http://cogo.wordpress.com/?p=1167I just published a post on how to query elasticsearch using the Elastica client over at our company blog:

Now your (empty) channel has been pushed to GitHub, and you can browse it at your user page. Next step is to add some PEAR packages to your channel, re-build, then simply run:

git add --all
git commit -a -m "Added some package"
git push

in the directory where your channel files are located. That’s that, easy as pie!

You can also use a different domain name for your user pages if you want to. Read more about that feature over at GitHub.

Oh, and if you haven’t already you might want to beef up your billing plan from Free to something more awesome. I for one think GitHub is totally worth it.

]]>https://cogo.wordpress.com/2012/02/28/how-to-make-github-host-your-pear-channel/feed/1christerPHP_BitTorrent-0.2.0 releasedhttps://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/
https://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/#respondWed, 04 Jan 2012 18:20:36 +0000http://cogo.wordpress.com/?p=1143Continue reading →]]>During my Christmas vacation I received a pull request on GitHub for my PHP_BitTorrent project which added proper namespaces to the classes. I decided to merge the pull request and do some other changes as well. I removed the static methods and added instance methods instead which, IMHO, makes the API cleaner, and more important, made the code easier to test.

I have also done some more work on the BitTorrent tracker part of the project which is available in a separate branch (not a part of the 0.2.0 release). Feel free to play around with it and don’t hesitate to send me a pull request if you have improvements for it.

]]>https://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/feed/0christerFat Models, Chubby Routes, Super-Skinny Controllershttps://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/
https://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/#respondTue, 08 Nov 2011 13:19:17 +0000http://cogo.wordpress.com/?p=1133Continue reading →]]>We have just started a blog at work where we will be writing about some of the technologies we use daily. I just wrote a post about beefing up the routes in Zend Framework applications.

I will continue to write on this blog, but if you are interested in web technologies be sure to checkout VG Tech as well.

]]>https://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/feed/0christerPlaying with traits in PHP 5.4alpha1https://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/
https://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/#commentsFri, 01 Jul 2011 10:08:51 +0000http://cogo.wordpress.com/?p=1112Continue reading →]]>PHP 5.4alpha1 was released the other day with some cool new features. One of them is an implementation of traits. From the RFC:

Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way, which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins.

There are some nice examples over at the RFC, and I will provide another example in this post.

But first, to be able to play with this we need to build PHP. It’s the usual ./configure; make; make test; dance so it should not pose too many problems. The make test step is optional, but every time you skip that step, God creates another Perl programmer, so please, make test. If you run into any problems building PHP you will have to look elsewhere for answers. I won’t cover that in this post.

Now that you have built PHP, lets start writing some code.

When working on a framework (or something else for that matter), you will most likely need to introduce parameters for some of your classes, be it database adapters or a storage adapter. All these classes will most likely have the following methods:

setParams(array $params)

getParams()

setParam($key, $value)

getParam($key)

The implementation of these methods will most likely be the same. If you put the actual implementation of these methods in many classes you’re not DRY anymore. Since PHP does not support multiple inheritance you will have to make a base class with the implementation of these methods, and have other classes ultimately extend this base class. Now you are relatively DRY, but this solution is not optimal(and sometimes not possible at all).

Enter traits, the newest superhero on the PHP street, or something like that.

Now, I’ll create two classes that needs to support parameters; Cogo\Database\MySQL and Cogo\Storage\Filesystem. They will each extend Cogo\Database and Cogo\Storage respectively that will have the parameter-related methods.

As you can see the parameter-related methods are almost the same. The difference is that the Cogo\Database class wants to have its set methods private and protected.

One possibility would be to create a base class for the parameter handling, and have the two abstract classes extend that one, but because multiple inheritance is not possible in PHP it’s easy to grind to a halt using this solution. In the end you might end up with a huge base class with loads of logic simply because it has some logic that you want to share across many other classes.

The base class would also have to have private on the set methods since you can’t override a method with a stricter visibility, only the other way around.

Using traits, this can be solved in a more elegant fashion. Traits also support changing visibility of the methods defined in the trait, so Cogo\Database can keep its private and protected implementations. Here is how the trait can look like:

As you can see we have replaced the implementation of the parameter methods from both abstract classes with a couple of use statements. In the Cogo\Storage class we have used the methods from the trait as-is, which means they are all public. In the Cogo\Database class we have changed the visibility of two methods to match the initial implementation. We have now managed to keep ourselves DRY, as well as not creating a base class that the two abstract classes extends.

This is just a simple example of how to use traits. They can do loads more, and there are issues like for instance conflict resolution which is not mentioned in this post at all. I will probably post more examples of traits (and perhaps other 5.4 features) later on. In the meantime you should read the RFC, and try it out for yourself.

You will find all the code mentioned in this post over at my php-traits-examples repository at GitHub. Feel free to play around with it, and if you have other examples on how to use traits please fork the project and send me a pull request so I can include it (and learn from it).

]]>https://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/feed/7christerMocking MongoCollection with Mockeryhttps://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/
https://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/#respondFri, 01 Apr 2011 17:12:55 +0000http://cogo.wordpress.com/?p=1096Continue reading →]]>I have played around with the mongo extension to PHP lately and came across an issue when I was trying to write unit tests with PHPUnit for some methods using MongoCollection::insert().

The Image class is just some custom class, and the getCollection() method returns a property set in the class (so I can inject mocked versions of the collection and not depend on MongoCollection).

As you see from the code above the insertData() method changes the first parameter (it adds an _id element that is set to an instance of MongoId). The problem with testing the above method is that when mocking MongoCollection you can’t make it add the _id element to the passed array, so the test fails because of an E_NOTICE that says:

Undefined index: _id.

I tried to solve the problem by using Mockery (a simple but flexible (and awesome) mock object framework by Pádraic Brady) like this:

This is because Mockery uses the call_user_func_array function to call the closure given to \Mockery::on(), and that function does not support references. PHPUnit also uses this function internally for its mock objects.

Feeling a bit bold I tried to change the insertData() method above to pass an instance of stdClass instead of an array to MongoCollection::insert(). Why? Objects in PHP-5 are all references, so I might be able to get Mockery to work without having to specify &$data in the closure. It’s not documented, but hey, you never know without trying right? Here is the new version of insertData():

The only change I made in the test method was to change the closure I give to \Mockery::on() from:

function(&$data) use ($id) {
$data['_id'] = $id;
return true;
}

to

function($data) use ($id) {
$data->_id = $id;
return true;
}

and voila, the test works! The part about giving an instance of stdClass to MongoCollection::insert() is not documented, and I’m not sure if it’s a feature that’s going to stay implemented.

At first I tried to solve this using the built in mock objects in PHPUnit, but since they clone the objects used in the mocks the trick above would not work anyway as the change would not be made on the correct reference.