Ondřej Mirtes

Articles like this one usually start with the words „forget everything you’re used to from Windows.“ It’s nonsense to ask something like that of users, because habits formed over many years of computer use can’t be shaken off so easily.

Instead, I want to share with you the tips and experiences I’ve gathered over 2 months of using a MacBook. I struggled with a lot of things, ran into dead ends, fell into despair. Lately, though, I have the feeling that the tide is turning and I’m starting to recognize the advantages of Mac OS X over a PC.

Rule #1 - forget the traffic light! The trio of colored buttons in the top-left corner of a window reminds everyone of a similar trio from Windows, but their functions differ. The green + usually doesn’t maximize the window - instead it resizes the window to the size it thinks is ideal. There’s practically no difference between the yellow and the red button. Both effectively hide the window; pressing the yellow one is just accompanied by an animation.

Rather than trying to hit tiny buttons, it’s far more convenient to use keyboard shortcuts. Cmd+W is the most frequent shortcut I currently use. It’s the equivalent of pressing the red button. The application doesn’t quit and keeps running in the background; only its current window closes. You can quit an application completely with Cmd+Q, but I’ve found I do that very rarely, more in emergency situations. Another point against Cmd+Q is that it can’t be used in Finder.

OS X blurs the distinction between closed and running applications. To reinforce this idea, I turned off the display of the blue dots under the icons in the Dock in the settings. (System Preferences - Dock - Show indicator lights for open applications) For one thing, it irritated me that the blue dot next to an application stayed there even after I pressed the red button, and for another, it reminded me of the new-posts indicator on Twitter (so I thought there was „something new“ in the application I should look at). I therefore have no idea which applications are running right now, and as a user I don’t even care.

On a MacBook you can’t set what should happen when you close the lid. If it isn’t connected to an external monitor and to power at the same time, it goes to sleep. If you want to finish working or move somewhere, you don’t have to hunt for some sleep mode in the settings - just snap it shut. Waking up after opening it is almost instant.

I recommend going through System Preferences - Trackpad. There’s a list of all the gestures you can perform on the touchpad, and you can turn them on/off as needed. The touchpad can be pressed anywhere, so you can use the same finger to move the cursor and to click. It surprises me how many people don’t know this fundamental thing.

The way Finder is controlled struck me as a bit wild. Enter renames a file; you open it with Cmd+O. The crucial feature, though, is the preview, which is invoked with the spacebar. It handles many file types and doesn’t open a specialized application for it, so it displays very quickly. It can even show .docx, which not even Windows can do out of the box. Not to mention PDF. Finder’s capabilities are extended by TotalFinder.

Applications that aren’t from the App Store are installed by simply dragging the .app file from the archive into the Applications directory in Finder.

A chapter unto itself is the keyboard. Compared to a PC, there’s one extra modifier key here, Cmd. Where Ctrl is used on a PC, Cmd is used here. So for working with text you use Cmd+X, Cmd+C, Cmd+V. Ctrl here only serves as a substitute in cases where Cmd can’t be used. Search is invoked in all applications with Cmd+F, but if I’m in a text editor and want to use Find+Replace, I can’t use Cmd+H, because the system has that reserved for minimizing the window. So I have to press Ctrl+H. If I want to switch between tabs in some application, I can’t use Cmd+Tab, because again the system has that reserved for showing the list of windows. Once again, Ctrl+Tab works here. Most shortcuts can be derived this way.

Both OS X and application authors honor the meaning of keyboard shortcuts. In all of them, Cmd+comma works for going to the settings. If an application has several different views, you can switch between them with Cmd+1, Cmd+2, … Pressing the function keys F1 - F12 by default does what’s drawn on them, i.e. dimming/brightening the display and keyboard, playing music, and so on. An actual press of F1 - F12 can be done with the Fn modifier key. But I haven’t needed it yet. To reload a page, which I need very often when developing websites, you can use Cmd+R in all browsers instead of the F5 I was used to on Windows.

The keyboard is missing Home, End, and Page Up/Down. Cmd in combination with the cursor arrows replaces them. Likewise, Delete for forward deletion of text is missing, but Cmd+Backspace works.

Until I needed to program something on the MacBook, the default Czech keyboard suited me fine. The special characters, though, are placed on it so unconventionally that after two days I gave up on the finger gymnastics. There’s a tool called Ukulele that lets you comfortably define your own keyboard layout. More options are offered by „KeyRemap4Macbook,“ which, for example, lets you turn the Eject key into a classic Delete. But beware, Airs no longer have Eject.

I’m finally getting to the applications. The most important one is still the web browser, even though it’s nowhere near as significant as on Windows. It only makes sense to consider Google Chrome or Safari. Mozilla Firefox doesn’t sit well with the Mac. Chrome is favored by its snappiness and its ever-growing market share, while Safari has a clear sense of better integration with the system.

The web browser on the Mac fades into the background, because for most web applications their desktop variants are available here, and they can sync with their web counterparts. Native applications on the Mac are very pleasant and more convenient than their web counterparts. It’s natural for an application I keep working with to have a separate window on the desktop, rather than just one tiny tab in a web browser. I subscribe to the theory that web applications are such a success only because no one on Windows is capable of creating a functional and good-looking application.

For Gmail users I recommend Sparrow, a client with a pleasant minimalist interface. It supports all the main Gmail features - labels, stars, search. Search doesn’t work by going through all the mail on the disk, but by querying Google’s servers, as if you’d used the search box. The response is therefore instant. I remember years ago, when I set something searching in Outlook, I could have gone and made myself a coffee, if I drank it back then.

For Google Reader users there’s Reeder (it also exists for iPhone and iPad). It likewise syncs with the web interface, can throw articles into Read It Later, and supports Readability (stripping a web page of the clutter around it for comfortable reading).

A given is the official Twitter for Mac, which also follows in the footsteps of its iPhone and iPad counterparts.

I dumped my calendars from Google Calendar into the preinstalled iCal.

Because I’d developed a well-earned hatred of iTunes on Windows, I was looking around for an alternative music player. In short - there isn’t one. As a consolation, I can say that iTunes is quite a different piece of software on the Mac. My story illustrates this well: the first time I connected my iPhone to the MacBook to sync, I waited for the system-wide several-second lag like on Windows. But nothing happened. So I checked the iPhone to see if it was on, I checked whether I’d plugged in the cable correctly. Everything was fine, and yet nothing was happening. I opened iTunes and it was signaling a just-completed backup of the iPhone :) So you can get along with it.

For instant messaging, Adium is widely used, but it didn’t really win me over. There is, however, a little-known cross-platform messenger from Mozilla called Instantbird. It reminds me a lot of Miranda, which I won’t hear a bad word about.

For notes I use Evernote, which probably needs no introduction.

For tracking tasks, I recently started toying with Things, which follows the GTD methodology to the letter. It does, however, represent a sizable investment. I took advantage of the fact that beta testing of cloud syncing is currently underway, so for now I’m using the development version. If it proves itself, I’ll buy it.

If you often work with the command line, I recommend iTerm. Compared to the default terminal, it brings considerable usability improvements.

Next Sunday I’m headed to Appleforum, so it’s quite possible that afterwards I’ll have to rewrite half of this article, or throw the whole thing out.

At today’s Barcamp, Jakub Vrána gave a talk comparing Doctrine 2 ORM with his own library, NotORM. In terms of code simplicity, line count, and the number of queries executed to print out articles and their assigned tags from the database, NotORM won unsurprisingly, which immediately makes it a candidate for the model layer of a web application in the eyes of naive programmers. Which sends a shiver down my spine.

The main motivation for using Doctrine is a consistent representation of data in the application and working with it. And objects give me that. Not wrappers around functions (a class with nothing but static methods), nor wrappers around data (a class with public properties or a generic storage mechanism like DibiRow), but real objects representing some meaningful whole with unbreakable consistency and methods that let me work with them.

If I take it from the angle that I want to store some rows in the database and then select them back out again, then with Doctrine I really do have a lot more writing to do that doesn’t make sense. But if I decide up front that I primarily want to comfortably work with consistent objects in the application, the way it’s normally done in Java, for instance (and something PHP folks still can’t quite get under their skin), then to store them in the database using Doctrine I only have to do the bare minimum - write a few annotations on the class and its properties.

What motivation do we have for this way of writing an application and stepping away from simple database layers like NotORM or dibi? The moment the size of the application exceeds a certain threshold, a model with de facto static methods, in which database access, writing to files, and sending emails are all mixed together, becomes unmaintainable chaos over the long term. That’s when the by-now legendary five-layer model comes into play, whose closest implementation in PHP is precisely Doctrine 2.

This architecture allows for easy testability and therefore reliability, flexibility (the model’s API, and consequently the presentation layer, doesn’t have to change when the database is reworked), it’s maintainable over the long term, and when it comes to multilingualism and versioning, you can do it cleanly and without tearing all your hair out. In this area NotORM, and the classic Nette models the community favored for a long time, really don’t stand a chance.

Of course this isn’t the only correct way to approach the problem. Some companies/projects choose the approach of having all the logic in the database. The PHP application is then built only to play the role of a simple presentation layer, and all operations are carried out using database procedures. Why not.

There’s certainly room in Doctrine to optimize the queries it issues, and I can imagine it using NotORM for that. But having that library as the only model layer in larger applications developed by multiple people doesn’t really work very well.

The syntax for some aspects of object-oriented programming in PHP has a fairly high WTF factor, and more than once I’ve come across an advanced programmer fumbling around, wondering why their code causes a parse error or some other error. So I decided to dust off my blog and pull together a clear, one-stop summary of OOP syntax in PHP.

I’ll be very brief in the individual descriptions; the article doesn’t aim to explain OOP, it focuses purely on the way things are written.

Nice object-oriented code also includes a consistent form, so I recommend studying the Nette Coding Standard.

Classes

Defining a new class

//a general class
class A {

}

//an abstract class - can't be instantiated, only its descendant can
abstract class A {

}

//a final class - can't be inherited from
final class A {

}

//definition of class B, which inherits from class A
class B extends A {

}

Constructor

A method named __construct() that is called when an instance of a new class is created.

class A {
	public function __construct() {

	}
}

//a constructor can have parameters
class A {
	public function __construct($name) {

	}
}

Creating an instance

$a = new A; //if the constructor has no required parameters
$a = new A(); //equivalent notation

$a = new A('foo'); //a constructor with a required parameter

Interfaces

//a general interface
interface A {

}

//interface B, which inherits from interface A
interface B extends A {

}

//class B, which implements interface A
class B implements A {

}

/* PHP allows implementing multiple interfaces at once */

//class C, which implements interfaces A and B
class C implements A, B {

}

Visibility (encapsulation)

For methods and static/instance members (class attributes) you can set the visibility for calling (in the case of methods), or for reading and writing (in the case of attributes). PHP, like other languages, supports three types of visibility:

  • public: anyone can call the methods and access the attributes
  • protected: only the class itself, its descendants (and its ancestors when overriding) and its siblings (two different instances of type B or of supertype A can reach into each other’s protected methods and attributes)
  • private: only the class itself

Attributes

Defining attributes

Convention says that all attributes should be defined at the beginning of the class definition.

class A {
	//instance attributes
	var $a; //the deprecated way of writing public
	public $b;
	protected $c;
	private $d;

	//static attributes
	public static $e;

	//attributes can be given default values of primitive data types or arrays
	//more complex data has to be passed in the constructor
	private $f = '';
	private $g = 'foo';
	private $h = 108;
	private $i = array('bar');
}

Accessing attributes

$a = new A;

//from the outside, to instance attributes
$a->a = 'foo';

//from the outside, to static attributes
A::$e = 'bar';

//from inside the class, to instance attributes
$this->c = 'foo';
echo $this->f;

//from inside the class, to static attributes
self::$e = 'bar';

Constants

PHP lets you define immutable class attributes, e.g. for all sorts of settings and to support the DRY principle.

class A {

	//defining a constant
	const DEFAULT_USER = 'foobar';

}

//access from the outside
echo A::DEFAULT_USER;

//access from the inside
echo self::DEFAULT_USER;

Methods

Defining methods

class A {

	//methods without a stated visibility are treated as public
	function methodFoo() {

	}

	public function methodBar() {

	}

	protected function methodFooBar() {

	}

	private function methodBarFoo() {

	}

	//a method can be abstract, in which case we leave its definition to a descendant of the class
	abstract public function methodAbstract();

	//a method can also be final, in which case it can't be overridden in a descendant
	final public function methodFinal() {

	}

}

Method parameters

class A {

	//a method that takes two parameters
	public function methodExample($a, $b) {

	}

	//PHP doesn't allow method overloading, but it does support optional parameters
	//this method can be called with two or three parameters
	public function methodFoo($name, $age, $sex='male') {

	}

	//you can define what type the incoming parameter should be
	//it can't be used for primitive data types - you can only require an array, an interface or a class - polymorphism works here
	public function methodBar(array $names, Person $p, Traversable $t) {

	}

	//methods can be static too
	public static function methodStatic() {

	}

}

Calling methods

$a = new A;

//instance method from the outside
$a->methodExample('foo', 'bar');

//instance method from the inside
$this->methodFoo('foo', 'bar');
$this->methodFoo('foo', 'bar', 'female');

//static method from the outside
A::methodStatic();

//static method from the inside
self::methodStatic();

Overriding

If in a descendant I define an attribute or method whose name already exists in an ancestor, and their visibility is public or protected, overriding occurs.

class A {
	public $foo = 'foo';

	public function methodExample() {
		return 'foo';
	}
}

class B extends A {
	public $foo = 'bar';

	public function methodExample() {
		return 'bar';

		//with parent::methodExample() I can call the ancestor's method
	}
}

$b = new B;
echo $b->foo; //prints bar
echo $b->methodExample(); //prints bar

If a class ancestor refers to a public/protected attribute or method that is overridden in a descendant, the descendant’s implementation is called/accessed.

Watch out! This doesn’t work for static attributes and methods; there, when accessed via self::, the ancestor’s implementation will still be called. This shortcoming is addressed by late static binding in PHP 5.3, see below.

class A {
	protected $foo = 'foo';

	public function getFoo() {
		return $this->foo;
	}
}

class B extends A {
	protected $foo = 'bar';
}

$b = new B;
echo $b->getFoo(); //prints bar

Bad habits

Don’t try the source code in this section at home, at work, or at school! ;)

Because of its scripting nature, PHP allows some really ugly things in OOP.

$a = 'foo';
$b = 'bar';

//conditional inheritance? 11 out of 10 programmers cry
if ($a == $b) {
	class B {

	}
} else {
	class B extends A {

	}
}

//if I want to work with some attribute, it always has to be defined in the class
class A {
	//yuck!
	if ('foo' == 'bar') {
		public $aaa;
	}

	public function fooBar() {
		if (isset($this->aaa)) { //a pointless check, in correct code $this->aaa must always exist
			//...
		}
	}
}

Dynamic names

If we have a reason to, we can decide based on some variable or computation which class is used, which attribute is accessed, and which method is called.

We of course have to be prepared for all the values that the given variable can take.

$den = date('D'); //takes values from Mon to Sun

$a = new $den; //the class named after the day of the week is called

//from PHP 5.3 on you can also access static attributes/constants/methods
$den::TRIDNI_KONSTANTA;
$den::methodStatic();

//calling a method
$method = 'mojeMetoda';

//the instance method mojeMetoda() of class Thu is called (if it's Thursday ;))
$a->$method();

//if I want to write more complex logic, curly braces are there for that
$bool = true;

//the allow() or deny() method is called
$a->{$bool ? 'allow' : 'deny'}();

Namespaces (PHP 5.3)

If it’s handy for you to have two classes with the same name, just put them into two different namespaces and you’re fine. But watch out! Namespaces tend to create more work than they save. Even so, there’s a way to keep working with namespaces to an absolute minimum.

//you can have multiple levels of namespaces, \ is the separator
namespace Foo\Bar;

//in other files, class A now has to be accessed as Foo\Bar\A
class A {

}
namespace MujNamespace;

class B {

	public function methodTest() {
		/**
		  * if I want to access a completely different namespace from inside some namespace,
		  * I have to choose the absolute "path" with a \ at the beginning
		  */
		$a = new \Foo\Bar\A;

		/**
		  * otherwise this would happen:
		  */
		$a = new A; //the class MujNamespace\A doesn't exist!

		/**
		  * If at the beginning of the file, below the namespace definition, I call:
		  * use \Foo\Bar\A;
		  * ...then I can refer to the class the classic way:
		  */
		$a = new A; //works!
	}

}

Late static binding (PHP 5.3)

I already mentioned the problem with overriding static attributes and methods above, so here I’ll just give a practical example:

class A {
	protected static $foo = 'foo';

	public function methodLsb() {
		echo self::$foo . "\n";
		echo static::$foo . "\n";
	}
}

class B extends A {
	protected static $foo = 'bar';
}

$b = new B;
$b->methodLsb();

//prints:
foo
bar

Nette Framework has many strengths. The main one is the fast and efficient creation of high-quality web applications.

Long gone are the days when I’d spend half an afternoon in PHP cobbling together a passable form with validation of filled-in text fields, e-mail address validity, and a more-or-less acceptable look for the message being sent.

In Nette, building a perfect and bulletproof contact form is a 10-minute job. The framework contains both a class for working with forms and a class for sending e-mail (including support for building the message in a template-based way).

What does the source code of such a form look like? We create it in a factory inside a Presenter:

use Nette\Application\UI\Form;
use Nette\Mail\Message;

class ContactPresenter extends BasePresenter
{
	protected function createComponentContactForm() {
		$form = new Form;
		$form->addText('name', 'Your name')
			->addRule(Form::FILLED, 'Fill in your name');

		$form->addText('email', 'Your e-mail')
			->setEmptyValue('@')
			->addRule(Form::FILLED, 'Fill in your e-mail')
			->addRule(Form::EMAIL, 'The e-mail has an incorrect format');

		$form->addTextarea('text', 'Message')
			->addRule(Form::FILLED, 'Fill in the message');

		$form->addSubmit('okSubmit', 'Send');

		$form->onSubmit[] = array($this, 'contactFormSubmitted');
		return $form;
	}
}

By simply calling the widget macro, we render the form in whatever template we want it in:

{control contactForm}

We write a method that gets called when the form is submitted (while taking care to follow the Post/Redirect/Get pattern):

public function contactFormSubmitted(BaseForm $form) {
	try {
		$this->sendMail($form->getValues());
		$this->flashMessage('Message sent successfully!');
		$this->redirect('this');
	} catch (\Nette\InvalidStateException $e) {
		$form->addError('Failed to send the e-mail, please try again in a moment.');
	}
}

We write the actual e-mail sending (including populating the template file):

private function sendMail($values) {
	$mail = new Message;
	$mail->setSubject('New message from the contact form');
	$mail->setFrom($values['email'], $values['name']);
	$mail->addTo('ondrej@mirtes.cz', 'Ondřej Mirtes');

	$template = $this->createTemplate();
	$template->setFile(__DIR__ . '/../templates/Mail.phtml');

	$template->name = $values['name'];
	$template->email = $values['email'];
	$template->text = $values['text'];

	$mail->setHtmlBody($template);
	$mail->send();
}

And we create the template for how the e-mail will look (Mail.phtml):

<h3>New message from the contact form</h3>

<ul>
	<li><strong>Name</strong> {$name}</li>
	<li><strong>E-mail</strong> <a href="mailto:{$email}">{$email}</a></li>
</ul>

<h1>Message text</h1>

{$text}

That’s all. We have a form that won’t submit unless all required fields are filled in (including client-side validation with JavaScript), that won’t be at risk of being submitted multiple times by hitting F5, and that would have taken us far more time had we tried to build it without a framework.

P.S. Inserting this article into my own CMS (I programmed this blog half a year before I started working with Nette) turned out to be far more demanding than building the entire form - it doesn’t escape characters correctly (which dibi would solve) and it doesn’t syntax-highlight PHP code (which Texy! would solve). David, what would we do without you? :)

P.P.S. At the beginning of October I rewrote the whole blog into Nette, dibi and Texy, so moving the article and highlighting the code in the new system was far more comfortable :)

Further reading

An XML declaration should be part of a valid XHTML page, even though it’s not mandatory.

The problem arises the moment we want to use this declaration at the beginning of a PHP script. Both the XML declaration and the PHP code use < > brackets. PHP tries to chew through the declaration code here, but unsuccessfully - the script stops on the first possible line.

How do we work around this limitation and have an XML declaration in any PHP script? Just use echo with single quotes:

echo '<?xml version="1.0" encoding="utf-8"?>';

Since my original website was powered by a custom system, I implemented features into it gradually, only as I needed them. When, a few months after launch, the bots figured out how to add comments under articles and those started showing up in truly large numbers, the situation needed to be solved.

I didn’t want to bother users with copying characters from illegible images, nor with math. The problem was solved for me by Jakub Vrána. I have to say that his method of eliminating spam worked a hundred percent for me; since deploying it, not a single unsolicited comment (from an automated bot) has reached me.

So how is it done? We assume the bots still haven’t been blessed with JavaScript. We therefore ask the user a question, or instruct them to fill in an additional form field, then use JavaScript to hide that field and fill it with the required value. Users with JavaScript know nothing about any of this. Users without JavaScript aren’t restricted in any way, they just have to fill in one extra value. When processing the submitted form, we then don’t continue if the given variable doesn’t contain the required value.

The part of the form with the protective field

<noscript>
	<label>Fill in nospam:</label>
	<input type="text" name="robot" />
</noscript>
<script type="text/javascript">
	document.write('<input type="hidden" name="robot" value="' + 'no' + 'spam' + '" />');
</script>

The PHP script

What follows here is just a simple condition that won’t let the data through to be written into the database if the form field doesn’t contain the string nospam:

if ($_POST["robot"] !== "nospam") { ... }

E-mail addresses on websites are exposed to attacks by spambots, which index them and store them in their database. So all it takes is having your e-mail just once on some indexed website and the trouble begins. The usual defenses against these methods of harvesting addresses for spam are unfriendly to users. When the at sign is replaced with some other character, a less experienced visitor might not think to replace that character correctly when writing the e-mail. And in the case of addresses displayed as images, the user has to retype the whole thing. On top of that, bots now have quality OCR, so you can’t rely on CAPTCHA technology.

Martin Jurča suggested a defense to me that he himself uses to his full satisfaction. It relies on the fact that bots can’t do JavaScript. JS is used to write out the link in its normal form, and it appears on the page the way we know it. Users aren’t restricted and bots are (at least for some time) eliminated.

The code for implementing it on a website is the following:

<script type="text/javascript">
	var prikaz = "mail";
	var prikaz2 = "to:";
	var jmeno = "ondrej.mirtes";
	var server = "lasthunter";
	var domena = "cz";
	document.write ('<a href="' + prikaz + prikaz2 + jmeno + '@' + server + '.' + domena + '">');
	document.write (jmeno + '@' + server + '.' + domena + '</a>');
</script>

‹ Year 2012